Generate Hotspot QR code async

This commit is contained in:
Balazs Perlaki-Horvath 2025-07-07 21:13:22 +02:00
parent ec7f13d1d1
commit 7388188965
3 changed files with 34 additions and 11 deletions

View File

@ -15,13 +15,14 @@
import SwiftUI
import CoreImage
import os
struct QRCode {
static func image(from text: String) -> Image? {
static func image(from text: String) async -> Image? {
let data = Data(text.utf8)
guard let filter = CIFilter(name: "CIQRCodeGenerator") else {
debugPrint("cannot create CIFilter")
os_log("QRCode cannot create CIFilter", log: Log.LibraryService, type: .error)
return nil
}
filter.setValue(data, forKey: "inputMessage")
@ -30,7 +31,7 @@ struct QRCode {
let transform = CGAffineTransform(scaleX: 20, y: 20)
guard let outputImage = filter.outputImage?.transformed(by: transform),
let image = context.createCGImage(outputImage, from: outputImage.extent) else {
debugPrint("cannot create qr code image")
os_log("QRCode cannot create image", log: Log.LibraryService, type: .error)
return nil
}
return Image(image, scale: 1, label: Text(text))

View File

@ -21,6 +21,7 @@ struct HotspotDetails: View {
let zimFiles: Set<ZimFile>
@State private var isPresentingUnlinkAlert: Bool = false
@State private var serverAddress: URL?
@State private var qrCodeImage: Image?
@ObservedObject private var hotspot = Hotspot.shared
private var buttonTitle: String {
@ -52,10 +53,14 @@ struct HotspotDetails: View {
Section(LocalString.hotspot_server_running_title) {
AttributeLink(title: LocalString.hotspot_server_running_address,
destination: serverAddress)
if let qrCode = QRCode.image(from: serverAddress.absoluteString) {
qrCode
if let qrCodeImage {
qrCodeImage
.resizable()
.frame(width: 250, height: 250, alignment: .trailing)
.frame(width: 250, height: 250)
} else {
ProgressView()
.progressViewStyle(.circular)
.frame(width: 250, height: 250)
}
}
.collapsible(false)
@ -72,9 +77,15 @@ struct HotspotDetails: View {
if isStarted {
Task {
serverAddress = await hotspot.serverAddress()
if let serverAddress {
qrCodeImage = await QRCode.image(from: serverAddress.absoluteString)
} else {
qrCodeImage = nil
}
}
} else {
serverAddress = nil
qrCodeImage = nil
}
}
}

View File

@ -29,6 +29,7 @@ struct HotspotZimFilesSelection: View {
@StateObject private var selection: MultiSelectedZimFilesViewModel
#if os(iOS)
@State private var serverAddress: URL?
@State private var qrCodeImage: Image?
#endif
init(hotspotProvider: @MainActor () -> Hotspot = { @MainActor in Hotspot.shared }) {
@ -78,13 +79,17 @@ struct HotspotZimFilesSelection: View {
Section(LocalString.hotspot_server_running_title) {
AttributeLink(title: LocalString.hotspot_server_running_address,
destination: serverAddress)
if let qrCode = QRCode.image(from: serverAddress.absoluteString) {
Section {
qrCode
.resizable()
.frame(width: 250, height: 250)
if let qrCodeImage {
qrCodeImage
.resizable()
.frame(width: 250, height: 250)
} else {
ProgressView()
.progressViewStyle(.circular)
.frame(width: 250, height: 250)
}
}
}
}
Section {
Text(LocalString.hotspot_server_explanation)
@ -99,9 +104,15 @@ struct HotspotZimFilesSelection: View {
if isStarted {
Task {
serverAddress = await hotspot.serverAddress()
if let serverAddress {
qrCodeImage = await QRCode.image(from: serverAddress.absoluteString)
} else {
qrCodeImage = nil
}
}
} else {
serverAddress = nil
qrCodeImage = nil
}
}
.toolbar {