在swift 4.1

时间:2018-05-17 07:41:42

标签: swift http-method urlrequest

首先让我描述视图控制器(页面设计)。我添加了一个按钮和一个标签。并且我为按钮创建了一个功能。这是viewController.swift文件:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var btnHitWebService: UIButton!
@IBOutlet weak var lblResult: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

}

@IBAction func btnHitWebServiceClick(_ sender: Any) {
    if (getTokenWithPostMethod() == true)
    {
        lblResult.text = "yes, we get token: " + g_token
    }
    else
    {
        lblResult.text = "there is an error, please try again later"
    }
}

func getTokenWithPostMethod() -> Bool{

    var funcResult = false

    var request = URLRequest(url: URL(string: "https://apiABCDEFG.com/token")!)
    request.httpMethod = "POST"
    let postString = "grant_type=password&username=ABCDEF&password=ABCDEF"
    request.httpBody = postString.data(using: .utf8)
    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = URLSession.shared.dataTask(with: request)
    {
        data, response, error in
        guard let data = data, error == nil else
        {
            // check for fundamental networking error
            print("error=\(String(describing: error))")
            return
        }

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200
        {
            // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(String(describing: response))")
        }

        do
        {
            if let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject]
            {
                g_token = (jsonObject["access_token"] as? String)!
                print(g_token)
                g_token_type = (jsonObject["token_type"] as? String)!
                print("\n")
                print(g_token_type)
                funcResult = true ;
            }
        }
        catch let error as NSError
        {
            print(error)
        }
    }

    task.resume()
    return funcResult
}

}

这是我的问题:当我点击按钮时,它在xcode(print)的输出屏幕中给我一个标记,但是getTokenWithPostMethod()方法将我变为false。为什么它会让我失意?在调试过程中:它从'let task ='跳转到'task.resume()'。谢谢! (顺便说一句,我无法分享正确的链接,用户名和密码。我希望这3个没有必要我们解决这个问题)

2 个答案:

答案 0 :(得分:2)

您正在进行API调用。返回值需要时间。这里return语句不会等待响应。你应该使用闭包或委托。您可以尝试给定的代码:

func getTokenWithPostMethod(handler: @escaping (_ funcResult: Bool) -> Void){

    var request = URLRequest(url: URL(string: "https://apiABCDEFG.com/token")!)
    request.httpMethod = "POST"
    let postString = "grant_type=password&username=ABCDEF&password=ABCDEF"
    request.httpBody = postString.data(using: .utf8)
    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = URLSession.shared.dataTask(with: request)
    {
        data, response, error in
        var funcResult = false

        if error == nil, let data = data {
            do
            {
                if let jsonObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String:AnyObject]
                {
                    g_token = (jsonObject["access_token"] as? String)!
                    print(g_token)
                    g_token_type = (jsonObject["token_type"] as? String)!
                    print("\n")
                    print(g_token_type)
                    funcResult = true
                }
            }
            catch let error as NSError
            {
                print(error)
            }
        }
        // edited
        DispatchQueue.main.async {
            handler(funcResult)
        }
    }
    task.resume()
}

这将在响应到来后返回。用以下方法替换该方法的调用:

@IBAction func btnHitWebServiceClick(_ sender: Any) {

    getTokenWithPostMethod { (flag) in
        if flag {
            lblResult.text = "yes, we get token: " + g_token
        } else {
            lblResult.text = "there is an error, please try again later"
        }
    }
}

有关详细信息,请visit

答案 1 :(得分:0)

它返回false,因为你在启动时设置了var funcResult = false,所以在URLSession请求服务器并仅在响应中返回一些数据之前,你的函数返回funcResult值。

你可以在尝试catch之后立即在URLSession任务体内添加以下代码,而不是在btnHitWebServiceClick中添加它:

#include <iostream>
#include <cppml/metrics/AccuracyScore.h>

int main(int argc, char **argv) {
  arma::ivec y_true;
  y_true << -1 << 1 << 1 << 1;
  arma::ivec y_pred;
  y_pred << 1 << 1 << -1 << 1;
  std::cout << "Accuracy score: ";
  std::out << cppml::metrics::accuracy_score(y_true, y_pred);
  return 0;
}