ios - 在 swift 4.1 中使用 httpMethod (POST) 调用 Web 服务

标签 ios swift http-method urlrequest

让我先描述一下 View Controller (页面设计)。我添加了一个按钮和一个标签。我为按钮创建了一个函数。这是 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 的输出屏幕中为我提供了一个标记(打印),但 getTokenWithPostMethod() 方法返回 false。为什么返回 false?在调试过程中,从let task =跳转到task.resume()。谢谢! (顺便说一下,我不能分享正确的链接、用户名和密码。我希望这 3 个不是解决这个问题所必需的)

最佳答案

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

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

关于ios - 在 swift 4.1 中使用 httpMethod (POST) 调用 Web 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50385928/

相关文章:

ios - 在 uiscrollview 中滑动不能正常工作

swift - 强制子类快速实现协议(protocol)

python - 如何使用 FlaskClient 测试分段上传(用于单元测试)

node.js - 构建 Restful API 时选择哪种 HTTP 方法

javascript - Internet Explorer (IE11) 不保存从 GET 返回的特定对象值

ios - 为什么当我返回 false 时 textFieldShouldReturn 仍然有效?

iphone - iOS7 主屏幕模式下的 Cookie

ios - 如何在 Objective-C 中创建对象?

iOS - 从我的应用程序以编程方式进行 WhatsApp 语音/视频通话

ios - 如何在 TableView 中保存数据?