我有一个具有两个成员变量和一个函数的类。当用户导航到新的故事板并使用带有成员变量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()
}
}
答案 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)
}