NSURLSession.sharedSession().dataTaskWithRequest(request) 最后执行

NSURLSession.sharedSession().dataTaskWithRequest(request) being executed last

我遇到了 NSURLSession.sharedSession().dataTaskWithRequest(request) 的问题。我想根据某些 API 对我的应用程序进行身份验证,如果身份验证成功,则该应用程序将允许用户授权健康工具包并最终从那里获取一些数据。

我的 viewDidLoad()

里有这个
print ("AUTHORIZING APIGEE!!!")
authorizeApigee()
if (self.errorApigee == 0) {
    print ("APIGEE AUTHORIZED!")
    // We cannot access the user's HealthKit data without specific permission.
    print ("AUTHORIZING HEALTHKIT!!")
    getHealthKitPermission()
    print ("HEALTHKIT AUTORIZED!")
} else {
    print ("APIGEE UNAUTHORIZED!")
} 

这是授权函数:

// Authenticating app with Apigee Health APIx
func authorizeApigee(){
        // Send HTTP GET Request


        let scriptUrl = "https://fhirsandbox-prod.apigee.net/oauth/v2"
        let urlWithParams = scriptUrl + "/accesstoken?grant_type=client_credentials"
        let myUrl = NSURL(string: urlWithParams);

        let request = NSMutableURLRequest(URL:myUrl!);
        request.HTTPMethod = "POST"

        // Add Basic Authorization

        let username = "****"
        let password = "****"
        let loginString = NSString(format: "%@:%@", username, password)
        let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
        let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
        request.setValue(base64LoginString, forHTTPHeaderField: "Authorization")

        let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
            data, response, error in

            // Check for error
            if error != nil
            {
                self.errorApigee = 1
                print("error=\(error)")
                return
            }

            // Print out response string
            let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
            print("responseString = \(responseString)")
        }
        task.resume()
    }

问题是,即使调用了authorizeApigee(),应用程序停止在NSURLSession.sharedSession().dataTaskWithRequest(request),退出了函数,显然errorApigee变量没有更新,因此它进入下一步是在不授权 Apigee 的情况下授权 Health Kit。最后,当健康套件获得授权后,它会返回并授权 Apigee。

知道为什么会发生这种情况吗? 任何提示将不胜感激!

这是如何使用 completion 的简单示例:

func authorizeApigee(completion: (auth: Bool) -> Void) {
           // Send HTTP GET Request
    let scriptUrl = "https://fhirsandbox-prod.apigee.net/oauth/v2"
    let urlWithParams = scriptUrl + "/accesstoken?grant_type=client_credentials"
    let myUrl = NSURL(string: urlWithParams);

    let request = NSMutableURLRequest(URL:myUrl!);
    request.HTTPMethod = "POST"

    // Add Basic Authorization

    let username = "****"
    let password = "****"
    let loginString = NSString(format: "%@:%@", username, password)
    let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
    let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
    request.setValue(base64LoginString, forHTTPHeaderField: "Authorization")

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        // Check for error
        if error != nil
        {
            self.errorApigee = 1
            print("error=\(error)")
             completion(auth: false)
        }

        // Print out response string
        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
        print("responseString = \(responseString)")
         completion(auth: true)
    }
    task.resume()
}

以及使用方法:

 self.authorizeApigee { (auth) -> Void in
        if (auth) {
           getHealthKitPermission()
        } else {
          //print errors
        }
    }

NSURLSession.sharedSession().dataTaskWithRequest() 在另一个线程中执行。这样主应用程序线程就不会挂起并等待请求完成。如果你想在异步任务完成后将代码块 运行,我建议你使用完成块。

您需要使用闭包,因为 api 调用以 async 方式工作,所以首先像这样更改您的函数定义

func authorizeApigee(completion: (Int) -> ()){
    let scriptUrl = "https://fhirsandbox-prod.apigee.net/oauth/v2"
    let urlWithParams = scriptUrl + "/accesstoken?grant_type=client_credentials"
    let myUrl = NSURL(string: urlWithParams);

    let request = NSMutableURLRequest(URL:myUrl!);
    request.HTTPMethod = "POST"

    // Add Basic Authorization

    let username = "****"
    let password = "****"
    let loginString = NSString(format: "%@:%@", username, password)
    let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
    let base64LoginString = loginData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
    request.setValue(base64LoginString, forHTTPHeaderField: "Authorization")

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in

        // Check for error
        if error != nil
        {
            completion(0)
            print("error=\(error)")
            return
        }
        // Print out response string
        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
        print("responseString = \(responseString)")
        completion(1)
    }
    task.resume()
}

现在像这样调用你的函数

self.authorizeApigee() { (result) -> () in
     if result == 0 {
          print ("APIGEE AUTHORIZED!")
          // We cannot access the user's HealthKit data without specific permission.
          print ("AUTHORIZING HEALTHKIT!!")
          getHealthKitPermission()
          print ("HEALTHKIT AUTORIZED!")
      } else {
          print ("APIGEE UNAUTHORIZED!")
      }  
}