简体   繁体   中英

Swift wait task finish from another viewcontroller

I have a Viewcontroller VC_B where I connect to Wifi by using "NEHotspotConfigurationManager.shared" to a special device. This function currently errors because it will return nil whenever success or failure. Please follow these links below. https://developer.apple.com/forums/thread/109412 https://stackoverflow.com/.../nehotspotconfigurationmanag.. .

So I will create a Viewcontroller VC_A, then use "pathUpdateHandler" to catch events whenever the wifi connection changed. Then save wifi SSID to CURENT_SSID by using CoreLocation.

  1. access device wifi by DEVICE_SSID at VC_B.
  2. wait until CURENT_SSID successfully is updated at VC_A.
  3. compare DEVICE_SSID and 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()
            }
        }
    }

I am stuck at step 2 when trying to wait for "pathUpdateHandler" to finish from VC_B. Sometimes it changes but sometimes it's not. I use while loop here and it's solved my problem. But I think it's is not the best choice. Is there any better solution for this? Thanks!

Firstly, it could be better to clean up yours example code. In your message it is difficult to understand what is going on.

In my opinion it is a bad idea to use infinite while loops in this case. I can advice these options:

  1. NSLock

  2. Observe event in any way. There are multiple options in iOS, depending on task. You can use delegate pattern and create a delegate protocol and add a reference on VC_B inside VC_A. The similar method is closure usage (save and call closure instead of delegate).

  3. Another option is using NotificationCenter to post notifications in VC_A and observe this event in VC_B. It is basic observer pattern usage in iOS, but you can use more advanced techniques like creating your own observer pattern implementation, like multi-delegates observer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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