Swift:如何在http任务完成之前确保seque没有运行?

时间:2017-04-12 22:16:42

标签: ios swift multithreading concurrency

我希望运行http任务,设置全局定义的变量jwt。然后,只有这样我才能运行将jwt传递给我的下一个活动的seque。

我知道它们的运行不正常,因为打印语句出现故障。捕获位于底部。我编辑了实际的jwt,但黑盒子的位置是jwt字符串。

主视图控制器

import UIKit

var jwt = ""

类ViewController:UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func submitLogin() {

    let url = URL(string: "http://example.com")

    let task = URLSession.shared.dataTask(with: url!) { data, response, error in
        guard error == nil else {
            print(error!)
            return
        }
        guard let data = data else {
            print("Data is empty")
            return
        }

        do {
            if let json = try JSONSerialization.jsonObject(with: data, options:.allowFragments) as? [String:Any] {

                jwt = json["jwt"] as! String
                print("Checkpoint 1 " + jwt)
            }
        } catch let err{
            print(err.localizedDescription)
        }

    }

    task.resume()

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "loginSubmit" {

        if let toViewController = segue.destination as? HomeActivity {
            print("Checkpoint 2 " + jwt)
            toViewController.token = jwt
        }
    }
}

}

第二视图控制器

import UIKit

class HomeActivity:UIViewController {

var token:String!

override func viewDidLoad() {
    super.viewDidLoad()
    renderInbox()
    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func renderInbox() {
    print("Printing token" + token)
}

}

Output Capture

P.S我只用了不到一个星期就做了Swift。所以任何一般的提示或类似的东西都是受欢迎的。比如如何在不使用全局变量的情况下将jwt传递给seque。或者在输出图片中的检查点1之后是什么。

P.P.S很抱歉代码进出Stack Overflow代码块。如果您知道如何修复它让我知道,我会尝试

2 个答案:

答案 0 :(得分:2)

听起来你有一个按钮可以触发segue和URLSession请求。由于请求是异步的,因此segue将始终在请求完成之前启动。按钮同时触发,我无法告诉segue等待。

如果你想在请求之后启动segue,你需要从按钮中删除现有的segue(只需单击它并在Interface Builder中删除),创建一个手动segue(带有标识符),然后然后使用performSegue手动显示segue。

要在Interface Builder中创建手动segue,请从源ViewController顶部栏中的ViewController图标(内部带有白色方框的黄色圆圈)进行控制拖动,直至目的地中的任意位置{ {1}}。

Screenshot of creation of a manual segue

将弹出一个菜单,让您选择所需的转换类型。创建后,转到“属性”检查器并设置描述性标识符。

现在,您可以在URLSession的回调中添加代码,以手动调用新的segue。在" Checkpoint 1":

之后立即添加此行
ViewController

现在您的segue应该在请求完成后才会发生。这也很好,因为如果请求失败或您不喜欢响应,您可以跳过执行segue。

答案 1 :(得分:0)

这里不需要使用segue 在任务的回调中,您可以使用presentViewController方法呈现新的视图控制器(如果您有导航控制器,则使用pushViewController。)