twostraws / CodeScanner

A SwiftUI view that is able to scan barcodes, QR codes, and more, and send back what was found.
MIT License
1.05k stars 297 forks source link

Completion handler might be called during view update #112

Open fossil12 opened 1 year ago

fossil12 commented 1 year ago
  1. Grant camera access for app
  2. Disable camera access
  3. Open view using a navigation link that contains the CodeScannerView which shows an alert using a state boolean if there is not camera access (see code below).

Expected: The alert appears Actual: No alert is shown and an error is logged: [SwiftUI] Modifying state during view update, this will cause undefined behavior. Workaround: Set the change to the alert bool in a new main actor task


Code to reproduce the issue:

// ContentView.swift

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink("Show Detail") {
                DetailCameraView()
            }
        }
    }
}
// DetailCameraView.swift

import SwiftUI
import CodeScanner

struct DetailCameraView: View {

    @State private var showNoCameraAccess = false

    var body: some View {
        CodeScannerView(codeTypes: [.qr]) { result in
            switch result {
            case .success(_):
                print("Success")
            case .failure(_):
                // Task { @MainActor in // Workaround
                    showNoCameraAccess = true
                // }
            }
        }
        .alert("No Camera Access", isPresented: $showNoCameraAccess) {
            // OK button is shown by default
        }
    }
}
timlittlelabs commented 5 months ago

Can confirm this is happening for us too.

Jeehut commented 2 weeks ago

Same here. Used @fossil12's workaround.