繁体   English   中英

Swift 等待另一个视图控制器的任务完成

[英]Swift wait task finish from another viewcontroller

我有一个 Viewcontroller VC_B,我通过使用“NEHotspotConfigurationManager.shared”连接到 Wifi 到一个特殊设备。 这个 function 当前错误,因为无论成功或失败它都会返回 nil。 请点击以下链接。 https://developer.apple.com/forums/thread/109412 https://stackoverflow.com/.../nehotspotconfigurationmanag..

所以我将创建一个 Viewcontroller VC_A,然后在 wifi 连接发生变化时使用“pathUpdateHandler”来捕获事件。 然后使用 CoreLocation 将 wifi SSID 保存到 CURENT_SSID。

  1. 通过 VC_B 的 DEVICE_SSID 访问设备 wifi。
  2. 等到 CURENT_SSID 在 VC_A 成功更新。
  3. 比较 DEVICE_SSID 和 CURRENT_SSID。
1. VC_A
// get current SSID and save to UserData.shared.current_wifi_ssid
    var ssid: String { 
        var return_ssid:String = "取得できませんでした。"
        if let interfaces = CNCopySupportedInterfaces() as NSArray? {
            for interface in interfaces {
                if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary?,
                    let ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String {
                    return_ssid = ssid
                }
            }
        }
        
        UserData.shared.current_wifi_ssid = return_ssid
        return return_ssid
    }
//catch when having wifi connection changing event
    func checkNetWorking() {
        monitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                self.isConnected = true
   //check sign in at backend
                Backend.shared.checkSignedIn {(isSignedIn: Bool) in
                    if !isSignedIn {
                        DispatchQueue.main.async {
                            AlertHelper.displayOK(self, title: "エラー", message: "サインインしてください")
                        }
                    }
                }
            } else {
     //the case no internet or already accessed to DEVICE_WIFI           
                //############# location - wifi
            do something
                //#############
            }
        }
    }

2. VC_B
//connect to device wifi and check
    func connectTheta(ID: String){
        TableVIew.isUserInteractionEnabled = false
        SVProgressHUD.show()
        let manager = NEHotspotConfigurationManager.shared
        let ssid = "THETAYN" + ID + ".OSC"
        let password = ID
        let isWEP = false
        let hotspotConfiguration = NEHotspotConfiguration(ssid: ssid, passphrase: password, isWEP: isWEP)
        hotspotConfiguration.joinOnce = true
        hotspotConfiguration.lifeTimeInDays = 1

        UserData.shared.current_wifi_ssid = "NULL"
        manager.apply(hotspotConfiguration) { (error) in //error always nil
            if error != nil {
            // error
          } else {
            // success
          }
            
            check_wifi_theta();
            
            func check_wifi_theta(){
      //i'm using while here to wait task from VC_A (wait until UserData.shared.current_wifi_ssid is updated)
                while(UserData.shared.current_wifi_ssid=="NULL"){
                    Thread.sleep(forTimeInterval: 0.5)
                }
                print("ssid theta", ssid)
                print("ssid current", UserData.shared.current_wifi_ssid)
                if (UserData.shared.current_wifi_ssid==ssid){
                    print("connect Theta OK")
                    AlertHelper.displayOK(self, title: "接続できました", message: "", okHandler: {_ in
                        self.navigationController?.popViewController(animated: true)
                    })
                }
                else{
                    AlertHelper.displayOK(self, title: "接続できません", message: "THETAの電源が入っている確認してください。")
                }
                self.TableVIew.isUserInteractionEnabled = true
                SVProgressHUD.dismiss()
            }
        }
    }

当我试图等待“pathUpdateHandler”从 VC_B 完成时,我被困在第 2 步。 有时它会改变,但有时不会。 我在这里使用while循环,它解决了我的问题。 但我认为这不是最好的选择。 有没有更好的解决方案? 谢谢!

首先,清理您的示例代码可能会更好。 在您的信息中,很难理解发生了什么。

在我看来,在这种情况下使用无限 while 循环是个坏主意。 我可以建议以下选项:

  1. NSLock

  2. 以任何方式观察事件。 iOS 中有多个选项,具体取决于任务。 您可以使用委托模式并创建委托协议并在 VC_A 内添加对 VC_B 的引用。 类似的方法是闭包使用(保存并调用闭包而不是委托)。

  3. 另一种选择是使用 NotificationCenter 在 VC_A 中发布通知并在 VC_B 中观察此事件。 这是 iOS 中的基本观察者模式用法,但您可以使用更高级的技术,例如创建自己的观察者模式实现,例如多委托观察者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM