在iOS Swift中执行POST请求 [英] Perform POST request in iOS Swift

查看:117
本文介绍了在iOS Swift中执行POST请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试执行POST请求,但请求未通过.我已经查看过在Swift中执行POST请求,但其中不包含我的信息我在寻找.

I am trying perform a POST request and the request does not go through. I have looked through Perform POST request in Swift already but it does not contain what I'm looking for.

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
    var request = NSMutableURLRequest(URL: NSURL(string: "https://us1.lacunaexpanse.com"))
    println("request url https://us1.lacunaexpanse.com")
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"

    let apikey = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    println("apikey",apikey)

    let username = "username"
    let password = "password"

    var login = Array(["username", "password", "apikey"])

    let jsonDictionary = ["2.0", "jsonrpc", "1", "id", "login", "method", "login", "params"]
    println("jsonDictionary",jsonDictionary)

    var writeError: NSError?

    let jsonData = NSJSONSerialization.dataWithJSONObject(jsonDictionary, options: NSJSONWritingOptions(), error: NSErrorPointer())

    var resultAsString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)

    resultAsString = resultAsString.stringByAppendingString("empire")

    let url = NSURL.URLWithString("string")
    println("url",url)

    var request2 = NSMutableURLRequest()
    println("Post url =%@",url)

    request2 = NSMutableURLRequest(URL:url)

    request2.HTTPMethod = "POST"

    var connection = NSURLConnection(request: request, delegate: self, startImmediately: false)

    return true

推荐答案

这里有很多战术问题:

  1. 您正在创建NSURLSession,但是随后发出了NSURLConnection请求.选择一个或另一个(您也可以使用NSURLSession).

  1. You're creating NSURLSession, but then issuing NSURLConnection request. Pick one or the other (you might as well use NSURLSession).

您的请求字典"不是字典,而是数组.例如,要发出JSON-RPC请求,字典的正确格式为:

Your "request dictionary" isn't a dictionary, but rather an array. For example, to issue the JSON-RPC request, the proper format of the dictionary is:

let requestDictionary = [
    "jsonrpc" : "2.0",
    "id"      : 1,
    "method"  : "login",
    "params"  : ["myuserid", "mypassword", "mykey"]
]

  • 次要问题,但是您使用了很多变量(通过var),其中常量(通过let)就可以了.本着Swift的安全精神,请尽可能使用let.

  • Minor issue, but you're using a lot of variables (via var) where a constant (via let) would be fine. In the spirit of Swift's safety, use let wherever possible.

    根据 Lacuna Expanse API ,您的URL应包含模块名称.

    According to the Lacuna Expanse API, your URL should be including the module name.

    例如,如果在帝国"模块中执行POST请求,则URL为:

    So, for example if doing POST requests in the "Empire" module, the URL is:

    let url = NSURL(string: "https://us1.lacunaexpanse.com/empire")
    

  • 您可能会执行很多请求,所以我建议将大部分请求放在一个函数中,您可以一次又一次地调用它,而不必在各处重复执行代码.也许像下面这样的函数需要以下参数:

  • You're likely to be doing a lot of requests, so I'd suggest putting the bulk of that in a single function that you can call again and again, without repeating code all over the place. Perhaps a function like the following that takes the following parameters:

    • 模块(例如帝国"与联盟");

    • module (e.g. "empire" vs "alliance");

    方法(例如登录"与"fetch_captcha");

    method (e.g. "login" vs "fetch_captcha");

    适合该请求的参数(例如,用于登录"的参数,即名称",密码"和"api_key");和

    the parameters appropriate for that request (e.g. for "login", that would be the "name", "password", and the "api_key"); and

    关闭,当异步请求完成时将被调用.

    closure that will be called when the asynchronous request finishes.

    然后,此函数准备JSON-RPC请求并在请求完成时调用闭包:

    This function then prepares the JSON-RPC request and calls the closure when the request finishes:

    func submitLacunaRequestFromModule(module: String, method: String, parameters: AnyObject, completion: (AnyObject?, NSError?) -> ()) -> NSURLSessionTask? {
        let session = NSURLSession.sharedSession()
        let url = NSURL(string: "https://us1.lacunaexpanse.com")!.URLByAppendingPathComponent(module)
        let request = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"
        request.setValue("application/json-rpc", forHTTPHeaderField: "Content-Type")
    
        let requestDictionary = [
            "jsonrpc" : "2.0",
            "id"      : 1,
            "method"  : method,
            "params"  : parameters
        ]
    
        request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(requestDictionary, options: [])
    
        let task = session.dataTaskWithRequest(request) { data, response, error in
    
            // handle fundamental network errors (e.g. no connectivity)
    
            guard error == nil && data != nil else {
                completion(data, error)
                return
            }
    
            // check that http status code was 200
    
            if let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode != 200 {
                completion(String(data: data!, encoding: NSUTF8StringEncoding), nil)
            }
    
            // parse the JSON response
    
            do {
                let responseObject = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary
                completion(responseObject, nil)
            } catch let error as NSError {
                completion(String(data: data!, encoding: NSUTF8StringEncoding), error)
            }
        }
        task.resume()
    
        return task
    }
    

    这将对JSON-RPC请求中的方法和参数进行所有必要的包装.然后,您需要做的就是调用该方法,就像这样:

    This does all of the necessary wrapping of the method and parameters within a JSON-RPC request. Then, all you need to do to call that method is something like so:

    submitLacunaRequestFromModule("empire", method: "login", parameters: ["myuserid", "mypassword", "mykey"]) { responseObject, error in
    
        // some network error or programming error
    
        guard error == nil else {
            print("error = \(error)")
            print("responseObject = \(responseObject)")
            return
        }
    
        // network request ok, now see if login was successful
    
        if let responseDictionary = responseObject as? NSDictionary {
            if let errorDictionary = responseDictionary["error"] as? NSDictionary {
                print("error logging in (bad userid/password?): \(errorDictionary)")
            } else if let resultDictionary = responseDictionary["result"] as? NSDictionary {
                print("successfully logged in, refer to resultDictionary for details: \(resultDictionary)")
            } else {
                print("we should never get here")
                print("responseObject = \(responseObject)")
            }
        }
    }
    

    对于需要字典的请求,例如创建",只需继续提供字典即可:

    For a request that requires a dictionary, such as "create", just go ahead and supply the dictionary:

    submitLacunaRequestFromModule("empire", method: "create", parameters: [
        "name"      : "user",
        "password"  : "password",
        "password1" : "password",
        "captcha_guid" : "305...dd-....-....-....-e3706...73c0",
        "captcha_solution" : "42",
        "email" : "test@gmail.com"
        ]) { responseObject, error in
    
            guard error == nil else {
                print("error = \(error)")
                print("responseObject = \(responseObject)")
                return
            }
    
            print("responseObject = \(responseObject)")
    }
    

  • 很显然,在上面的这些中,我只是在进行最少的错误处理,因此您可以加强此功能,但是您的问题是关于发出POST请求的,希望上面的示例说明了如何完成此操作.

    Clearly, in these above, I'm just doing minimal error handling, so you could beef this up, but your question was about issuing POST request, and hopefully the above illustrates how that's done.

    这篇关于在iOS Swift中执行POST请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆