如何将来自 QR 码扫描仪的字符串值分配给另一个 class 上的另一个变量

How to assign the stringValue coming from QR code scanner to another variable on another class

我在将二维码扫描仪的字符串值分配给另一个 class 上的变量时遇到问题。

  1. 扫描二维码
  2. 二维码中的字符串需要赋给另一个class
  3. 的id变量
  4. 对 class 的 viewController
  5. 执行转场

所以我在另一个 class 上创建了一个初始化变量 id 并将其分配给 temp 正如你所看到的但是仍然没有将 temp 分配给 id 变量并且当我执行代码时变量 id 出现错误 nil...?

Class:QRScannerController

            if metadataObj.stringValue != nil {
            
            let destVC = MonitorimiViewController(temp: metadataObj.stringValue!)
            destVC.id = metadataObj.stringValue!
            
            do {
                
                guard let tabBarController = self.storyboard?.instantiateViewController(withIdentifier: "tabBarController") as? UITabBarController else {
                    return
                }
                
                (tabBarController.viewControllers![0] as? MonitorimiViewController)?.id = metadataObj.stringValue!
                tabBarController.modalTransitionStyle = .crossDissolve
                tabBarController.modalPresentationStyle = .custom
                self.present(tabBarController, animated: true, completion: nil)
            }
        }
        captureSession.stopRunning()
    }

Class: MonitorimiViewController

init(temp : String){
    id = temp
    super.init(nibName: nil, bundle: nil)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}


var id:String?


    func fetchAndReloadData(){
    APICaller.shared.getVehicles(for: id!) {[weak self] (result) in     // error nil value at id! 
        guard let self = self else { return }
        
        switch result {
        case .success(let vehicle):
            self.listOfVechicle = vehicle
            DispatchQueue.main.async {
                self.monitorimiTableView.reloadData()
            }
        case .failure(let error):
            print(error)
        }
    }
}

如有任何疑问,请随时提出,因为我已经被这个问题困扰好几天了:(

如果自己不会debug(以后积累经验),千万不要写这种代码:

(tabBarController.viewControllers![0] as?MonitorimiViewController)?.id = metadataObj.stringValue!

所以,它说的是什么:

tabBarController.viewControllers!: 如果没有 viewControllers: crash.

(... as? SomeClass):如果不是那个class(或者符合协议,或者子class等),转换就会失败,并且会nil.

所以在你的情况下,它是:

(someNilValue)?.id = someId

所以,什么也得不到 someId

如何自己知道:

guard let viewcontrollers = tabBarController.viewControllers else {
    print("tabBarController.viewControllers is nil")
    return
}

guard let firstVC = viewControllers.first else {
    print("viewControllers is empty")
    return
}

guard let asMonitorimiVC = firstVC as? MonitorimiViewController else {
    print("firstVC is NOT a MonitorimiViewController instance: \(firstVC)") //by default, you should see its type in console, by you could also use type(of:)
    return
}

asMonitorimiVC.id = someId

你的应该会在 guard let asMonitorimiVC 失败,因为 firstVCUINavigationController.

guard let asNavigationVC = firstVC as? UINavigationController else {
    print("firstVC is NOT a UINavigationController instance: \(firstVC)") //by default, you should see its type in console, by you could also use type(of:)
    return
}

guard let firtVCFromNavVC = asNavigationVC.viewcontrollers.first else {
    print("asNavigationVC.viewcontrollers is empty") //But that shouldn't be the case, I used viewcontrollers, but you could also use topViewController in this case
    return
}

guard let asMonitorimiVC = firtVCFromNavVC as? MonitorimiViewController else {
    print("firtVCFromNavVC is NOT a MonitorimiViewController instance: \(firstVC)") //by default, you should see its type in console, by you could also use type(of:)
    return
}

asMonitorimiVC.id = someId

当然,这是一个冗长的解决方案,你可能想削减它一点,但在调试时,不要犹豫,明确代码:

guard let navVC = tabBarController.viewControllers?.first as? UINavigationController else {
print("tabBarController.viewControllers is nil or empty, or the first of it is not a UINavigationController")
return 
}
guard let asMonitorimiVC = navVC.viewControllers.first as? MonitorimiViewController else {
    print("navVC.viewControllers is empty, or its first is not a is NOT a MonitorimiViewController instance: \(navVC.viewControllers.first)")
    return
}

旁注:您可能会注意到,如果您在上一个问题中回答正确 my first question in comment,我们会直接发现问题:

Is (tabBarController.viewControllers![0] as? MonitorimiViewController) nil?

因为 print("Is it nil: (tabBarController.viewControllers![0] as?MonitorimiViewController))` 应该显示它实际上是 nil,因为转换失败...