diff --git a/PayfritBeacon/App/AppState.swift b/PayfritBeacon/App/AppState.swift
index 72db257..c88a246 100644
--- a/PayfritBeacon/App/AppState.swift
+++ b/PayfritBeacon/App/AppState.swift
@@ -14,6 +14,9 @@ final class AppState: ObservableObject {
@Published var token: String?
@Published var userId: String?
+ /// When true, skip auto-navigation in BusinessListView (user explicitly went back)
+ var skipAutoNav = false
+
init() {
// Restore saved session
if let saved = SecureStorage.loadSession() {
@@ -36,6 +39,8 @@ final class AppState: ObservableObject {
}
func backToBusinessList() {
+ AppPrefs.lastBusinessId = nil
+ skipAutoNav = true
currentScreen = .businessList
}
diff --git a/PayfritBeacon/Info.plist b/PayfritBeacon/Info.plist
index 7ea74e1..43eff72 100644
--- a/PayfritBeacon/Info.plist
+++ b/PayfritBeacon/Info.plist
@@ -22,6 +22,8 @@
$(CURRENT_PROJECT_VERSION)
LSRequiresIPhoneOS
+ NSCameraUsageDescription
+ Payfrit Beacon needs camera access to scan QR codes on beacon labels for provisioning.
NSBluetoothAlwaysUsageDescription
Payfrit Beacon needs Bluetooth to detect and configure nearby beacons.
NSBluetoothPeripheralUsageDescription
diff --git a/PayfritBeacon/Views/BusinessListView.swift b/PayfritBeacon/Views/BusinessListView.swift
index 74efd03..21658c9 100644
--- a/PayfritBeacon/Views/BusinessListView.swift
+++ b/PayfritBeacon/Views/BusinessListView.swift
@@ -94,18 +94,22 @@ struct BusinessListView: View {
let list = try await APIClient.shared.listBusinesses(token: token)
businesses = list
- // Auto-navigate if only one business (like Android)
- if list.count == 1, let only = list.first {
- appState.selectBusiness(only)
- return
- }
+ // Skip auto-navigation if user explicitly tapped Back
+ if !appState.skipAutoNav {
+ // Auto-navigate if only one business (like Android)
+ if list.count == 1, let only = list.first {
+ appState.selectBusiness(only)
+ return
+ }
- // Auto-navigate to last used business
- if let lastId = AppPrefs.lastBusinessId,
- let last = list.first(where: { $0.id == lastId }) {
- appState.selectBusiness(last)
- return
+ // Auto-navigate to last used business
+ if let lastId = AppPrefs.lastBusinessId,
+ let last = list.first(where: { $0.id == lastId }) {
+ appState.selectBusiness(last)
+ return
+ }
}
+ appState.skipAutoNav = false
} catch let e as APIError where e.errorDescription == APIError.unauthorized.errorDescription {
appState.logout()
} catch {
diff --git a/PayfritBeacon/Views/QRScannerView.swift b/PayfritBeacon/Views/QRScannerView.swift
index 4b9e830..d3a9d0f 100644
--- a/PayfritBeacon/Views/QRScannerView.swift
+++ b/PayfritBeacon/Views/QRScannerView.swift
@@ -241,17 +241,31 @@ final class CameraPreviewUIView: UIView {
func setFlash(_ on: Bool) {
guard let device = AVCaptureDevice.default(for: .video),
device.hasTorch else { return }
- try? device.lockForConfiguration()
- device.torchMode = on ? .on : .off
- device.unlockForConfiguration()
+ do {
+ try device.lockForConfiguration()
+ device.torchMode = on ? .on : .off
+ device.unlockForConfiguration()
+ } catch {
+ NSLog("[QRScanner] Failed to set torch: \(error.localizedDescription)")
+ }
}
private func setupCamera() {
let session = AVCaptureSession()
session.sessionPreset = .high
- guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back),
- let input = try? AVCaptureDeviceInput(device: device) else { return }
+ guard let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
+ NSLog("[QRScanner] ERROR: No back camera available")
+ return
+ }
+
+ let input: AVCaptureDeviceInput
+ do {
+ input = try AVCaptureDeviceInput(device: device)
+ } catch {
+ NSLog("[QRScanner] ERROR: Failed to create camera input: \(error.localizedDescription)")
+ return
+ }
if session.canAddInput(input) {
session.addInput(input)