Загрузка камеры при запуске - PullRequest
0 голосов
/ 30 мая 2020

Я использую CodeScanner Пола Хадсона для сканирования штрих-кодов в моем приложении.

Я хочу, чтобы считыватель штрих-кода загружался, когда приложение открыто, а также имел оверлей.

Я хочу чтобы иметь возможность запускать сканер при запуске без нажатия кнопки. Я думал, что это будет так же просто, как просто иметь тело в ContentView:

CodeScannerView(codeTypes: [.qr], simulatedData: "Some simulated data", completion: self.handleScan)

Но это выдает:

Terminating app due to uncaught exception 'NSRangeException'

Что я не понимаю, так как переменные я Я передаю такие же, как у меня, кнопка не меняет никаких значений. Единственный массив в нем - [.qr], которому я даю значение.

Я начал изучать UIKit, но решил изучить SwiftUI, и мне было намного сложнее gr asp, поэтому я, вероятно, отсутствуют некоторые базовые c знания.

В моем ContentView:

struct ContentView: View {
    var body: some View {
        ZStack() {
            ScannerView()
            ScannerOverlayView()
        }
    }
}

ScannerView:

import SwiftUI
import CodeScanner

struct ScannerView: View {
    @State private var isShowingScanner = false

    var body: some View {
        Button(action: {
            self.isShowingScanner = true
        }) {
            Text("Show Scanner")
        }
        .sheet(isPresented: $isShowingScanner) {
            CodeScannerView(codeTypes: [.qr], simulatedData: "Some simulated data", completion: self.handleScan)
        }
    }

    private func handleScan(result: Result<String, CodeScannerView.ScanError>) {
       self.isShowingScanner = false
       switch result {
       case .success(let data):
           print("Success with \(data)")
       case .failure(let error):
           print("Scanning failed \(error)")
       }
    }
}

ScannerViewOverlay

Import SwiftUI
struct ScannerOverlayView: View {
    var body: some View {
        VStack() {
                HStack() {
                    VStack() {
                        Spacer()
                        Image("bookmark-icon")
                        Text("Saved items")
                    }
                    Spacer()
                    VStack() {
                        Spacer()
                        Image("settings-icon")
                        Text("Settings")
                    }
                }
                .padding(.horizontal)
            }
        }
    }

Вот начало CodeScanner:

import AVFoundation
import SwiftUI
public struct CodeScannerView: UIViewControllerRepresentable {
public enum ScanError: Error {
    case badInput, badOutput
}

public class ScannerCoordinator: NSObject, AVCaptureMetadataOutputObjectsDelegate {
    var parent: CodeScannerView
    var codeFound = false

    init(parent: CodeScannerView) {
        self.parent = parent
    }

    public func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        if let metadataObject = metadataObjects.first {
            guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else { return }
            guard let stringValue = readableObject.stringValue else { return }
            guard codeFound == false else { return }

            AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            found(code: stringValue)

            // make sure we only trigger scans once per use
            codeFound = true
        }
    }

    func found(code: String) {
        parent.completion(.success(code))
    }

    func didFail(reason: ScanError) {
        parent.completion(.failure(reason))
    }
}
...