首页 > 解决方案 > 如何在扩展中的 didSet 变量中调用扩展中的函数

问题描述

我需要做的是从一个静态变量调用一个位于 UIViewController 扩展中的函数,其中的 didSet 也位于 UIViewController 的扩展中。这将是一些示例代码。

extension UIViewController {
    static var isWifiAvailable = false {
        didSet {
            if isWifiAvailable = true {
                 getValidLogin()
            }
        }
    }

    func getValidLogin() {
        // do something
    }

    func otherFuncCallsit() {
         isWifiAvailable = true
    }

}

我尝试使用

DispatchQueue.main.async {
    let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first

    if let topController = keyWindow?.rootViewController {
         topController.getValidLogin(username: email, password: password, sender: "backgroundCheck")
    }
}

但这导致我从 getValidLogin 调用的 api 不起作用。如果我使用这个解决方案,当我调用 api 时, session.uploadTask 之后什么都不会运行(例如 print("ok") 不会运行)。这是我实际的 getValidLogin() (更改了 api 的 url)

func getValidLogin(username: String, password: String, sender: String = "") {
        
        let session = URLSession.shared
        let url = URL(string: "example.com")!
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let json = [
            "UserName": username,
            "Password": password
        ]
        let jsonData = try! JSONSerialization.data(withJSONObject: json, options: [])
        var done = false
        let group = DispatchGroup() // initialize
        
        print(request)
        let task = session.uploadTask(with: request, from: jsonData) { data, response, error in
            group.enter()
            if data == nil {
               
                self.showNoWifiAlert()
                
                loginResponseDetails.message = "Cannot Login Due to Unstable Internet Connection. Please Try again"
                group.leave()
                done = true
            } else {
                do {
                        guard let dictionary = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] else {
                            print("Could not cast JSON content as a Dictionary<String, Any>")
                            return
                        }
                        UIViewController.isWifiAvailable = true
                        loginResponseDetails.token = dictionary["Token"] as? String ?? "nil"
                        loginResponseDetails.message = dictionary["Message"] as! String
                        loginResponseDetails.status = dictionary["Status"] as! Bool
                        loginResponseDetails.isResetFirstPassword = dictionary["IsResetFirstPassword"] as! Bool
                        loginResponseDetails.isFinalRegistrationSubmitted = dictionary["IsFinalRegistrationSubmitted"] as! Bool
                        loginResponseDetails.finalStatus = dictionary["FinalStatus"] as? String ?? "nil"
                        loginResponseDetails.isAgreementsAccepted = dictionary["IsAgreementsAccepted"] as! Bool
                        loginResponseDetails.carrierCountry = dictionary["CarrierCountry"] as? String ?? "nil"
                        
                        print("token: " + loginResponseDetails.token)
                        print("message: " + loginResponseDetails.message)
                        print("status: " + String(loginResponseDetails.status))
                        print("isResetFirstPassword: " + String(loginResponseDetails.isResetFirstPassword))
                        print("isFinalRegistrationSubmitted: " + String(loginResponseDetails.isFinalRegistrationSubmitted))
                        print("finalStatus: " + loginResponseDetails.finalStatus)
                        print("isAgreementsAccepted: " + String(loginResponseDetails.isAgreementsAccepted))
                        print("carrierCountry: " + loginResponseDetails.carrierCountry)
                        group.leave()
                        done = true
                    } catch {
                        // Print error if something went wrong
                        print("Error: \(error)")
                    }
                }
            }
        group.notify(queue: .main) {
            task.resume()
        }
        repeat {
            RunLoop.current.run(until: Date(timeIntervalSinceNow: 0.1))
        } while !done
        
        print("ok")
        if sender == "backgroundCheck" {
            print(loginResponseDetails.status)
            print("ok")
            if loginResponseDetails.status == true {
                let vc = UIStoryboard(name: "ShamitMain", bundle: nil).instantiateViewController(identifier: "LoginVC")
                let navController = UINavigationController(rootViewController: vc)
                navController.isNavigationBarHidden = false
                navController.modalPresentationStyle = .fullScreen
                
                self.present(navController, animated: true, completion: nil)
            }
        
        }
    }

那么是否有其他方法可以调用 getValidLogin() 或者有什么方法可以解决我在使用上述解决方案时遇到的问题?

标签: iosswift

解决方案


推荐阅读