将值分配给函数内的类成员

时间:2019-02-21 20:02:27

标签: swift

我有一个具有两个成员变量和一个函数的类。当用户导航到新的故事板并使用带有成员变量y的http GET请求为成员变量x分配值时,将调用该函数。函数完成后,我尝试将x分配给新情节提要的变量,但是它为nil。如何在函数中为x赋值,然后将x传递给新的情节提要?

import UIKit
import os.log

class testViewController: UIViewController {

    var x: XClass!
    var y = “1234”

    override func viewDidLoad() {
        super.viewDidLoad()  
    }

    // MARK: - Navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        switch(segue.identifier ?? "") {
        case “ZViewController”:
            guard let zviewcontroller = segue.destination as? ZViewController else{
                fatalError("Unexpected Destination: \(segue.destination)")
            }

            loadXDetail()
            zviewcontroller.x = x


        default:
            os_log("Not ZViewController Segue", log: OSLog.default, type: .debug)
        }
    }

    private func loadX(){
        // credentials encoded in base64
        let username = “***”
        let password = “***”
        let loginData = String(format: "%@:%@", username, password).data(using: String.Encoding.utf8)!
        let base64LoginData = loginData.base64EncodedString()

        // create the request
        let url = URL(string: "https://example.com")!
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        request.setValue("Basic \(base64LoginData)", forHTTPHeaderField: "Authorization")

        //making the request
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data, error == nil else {
                print("\(error)")
                return
            }

            if let httpStatus = response as? HTTPURLResponse {
                // check status code returned by the http server
                print("status code = \(httpStatus.statusCode)")
                do {
                    let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
                    let items = json["items"] as? [[String: Any]] ?? []
                    for dic in items{
                        //guard let api = dic["Type"] as? String else {return}
                        let a = dic[“A”] as! String
                        let b = dic[“B”] as! String
                        let c = dic[“C”] as! String

                        self.x = XClass(y: y, a: a, b: b, c: c)!
                    }
                } catch let error as NSError {
                    print(error)
                    return
                }
            }
        }
        task.resume()
    }
}

2 个答案:

答案 0 :(得分:1)

在请求完成之前,您无法阻止prepare(for segue内部的冲突,需要导航时需要启动对异步方法的调用

loadX()

然后在let task = URLSession.shared.dataTask(with: request)内完成

 self.x = XClass(y: y, a: a, b: b, c: c)!
 }
 DispatchQueue.main.async {
    self.performSegue(withIdentifier:"SegueID",sender:nil)
 }

,此时x var根据响应具有正确的值


另一件事,您可能需要x作为任何数组,因为它将包含此循环中的最后一个值

                for dic in items{
                    //guard let api = dic["Type"] as? String else {return}
                    let a = dic[“A”] as! String
                    let b = dic[“B”] as! String
                    let c = dic[“C”] as! String

                    self.x = XClass(y: y, a: a, b: b, c: c)!
                }

另外请考虑使用Codable而不是JSONSerialization来解码您的回复

答案 1 :(得分:1)

swift 4.2 / Xcode 10.1:

在viewController或类之间传递数据的方法很少。

最简单的一种是使用全局变量。例如:

import UIKit

var myGlobalVariable = ""  //Or any Type you need

class testViewController: UIViewController {

private func loadX(){

//Do some stuff ...

myGlobalVariable = x

}

import UIKit

class ZViewController: UIViewController {

override func viewDidLoad() {

print(myGlobalVariable)

}

或者,使用单例模式。例如:

创建一个类似的类:

import Foundation

class  SetVariable {

    var test: String?  //Or any type you need

    private init () {}

    static let shared = SetVariable.init()
}

class testViewController: UIViewController {

private func loadX(){

//Do some stuff ...

SetVariable.shared.test = x

}

class ZViewController: UIViewController {

override func viewDidLoad() {

print(SetVariable.shared.test)

}