Perform POST request in iOS Swift

前端 未结 2 1115
不知归路
不知归路 2021-01-03 12:07

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

相关标签:
2条回答
  • 2021-01-03 12:47

    As @jcaron points out, this post is full of bad edits. There's a lot of variables that have different names later in the function and so on. Not to mention you should NEVER post your api key in a SO question or anywhere on the internet for that matter.

    To answer your question on to do a post request in Swift, unless you need incredibly granular control over the process, take a look at Alamofire (same guy that wrote AFNetworking). A POST request is as simple as Alamofire.request(.POST, "http://someapiurl.com") You can also pass in a dictionary of body parameters if you so choose.

    0 讨论(0)
  • 2021-01-03 12:51

    There are a whole bunch of tactical issues here:

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

    2. 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"]
      ]
      
    3. 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.

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

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

      let url = NSURL(string: "https://us1.lacunaexpanse.com/empire")
      
    5. 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");

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

      • 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.

      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
      }
      

      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)")
      }
      

    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.

    0 讨论(0)
提交回复
热议问题