Files
simplex-chat/apps/ios/Shared/Views/Chat/ScanCodeView.swift
T
Narasimha-sc eb6d8768eb Recognise wrong QR code type in every scanner
When a scanner is shown a QR code of a different kind than it expects, it
now tells the user what they actually scanned and where to scan it, instead
of a generic "invalid" message. On parse failure each scanner falls back to
a shared classifier (identifyQRCode / wrongQRCodeMessage) that tries the
other known parsers — connection link, server address, migration link,
desktop address — and shows "This is a X. To use it, ...", or the existing
"not a SimpleX code" message when nothing matches.

Each screen keeps its own parser and success path; only the failure branch
changed. The wrong-type alert is presented through each view's own alert
state so it shows within the scanner's presentation. Mirrored on Android,
desktop and iOS. Plan: plans/2026-07-09-qr-recognise-wrong-type.md.

Note: the iOS Swift was written without an Xcode toolchain and is not yet
compiled — needs a Mac/CI build to verify.
2026-07-10 14:27:45 +00:00

61 lines
2.1 KiB
Swift

//
// ScanCodeView.swift
// SimpleX (iOS)
//
// Created by Evgeny on 10/12/2022.
// Copyright © 2022 SimpleX Chat. All rights reserved.
//
import SwiftUI
import CodeScanner
struct ScanCodeView: View {
@Environment(\.dismiss) var dismiss: DismissAction
@Binding var connectionVerified: Bool
var verify: (String?) async -> (Bool, String)?
@State private var scanAlert: SomeAlert?
var body: some View {
VStack(alignment: .leading) {
CodeScannerView(codeTypes: [.qr], scanMode: .oncePerCode, completion: processQRCode)
.aspectRatio(1, contentMode: .fit)
.cornerRadius(12)
Text("Scan security code from your contact's app.")
.padding(.top)
}
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.alert(item: $scanAlert) { $0.alert }
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
func processQRCode(_ resp: Result<ScanResult, ScanError>) {
switch resp {
case let .success(r):
Task {
if let (ok, _) = await verify(r.string) {
await MainActor.run {
connectionVerified = ok
if ok {
dismiss()
} else if let msg = wrongQRCodeMessage(r.string, detectSecurityCode: false) {
scanAlert = SomeAlert(alert: wrongQRCodeAlert(msg), id: "wrongQRCode")
} else {
scanAlert = SomeAlert(alert: Alert(title: Text("Incorrect security code!")), id: "incorrectCode")
}
}
}
}
case let .failure(e):
logger.error("ScanCodeView.processQRCode QR code error: \(e.localizedDescription)")
dismiss()
}
}
}
struct ScanCodeView_Previews: PreviewProvider {
static var previews: some View {
ScanCodeView(connectionVerified: Binding.constant(true), verify: {_ in nil})
}
}