在iOS Swift中执行POST请求

  发布于 2022-12-27 15:38

我正在尝试执行POST请求,但请求没有通过.我已经查看了Swift中的Perform POST请求,但它不包含我正在寻找的内容.

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

Rob.. 8

这里有一大堆战术问题:

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

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

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

    小问题,但你使用了很多变量(via var),其中常量(via let)就可以了.本着Swift安全的精神,let尽可能使用.

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

    因此,例如,如果POST在"Empire"模块中执行请求,则URL为:

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

    您可能会做很多请求,所以我建议将其中的大部分放在一个可以反复调用的函数中,而不必在整个地方重复代码.也许像下面这样的函数采用以下参数:

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

    方法(例如"login"vs"fetch_captcha");

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

    异步请求完成时将调用的闭包.

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

    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请求中完成方法和参数的所有必要包装.然后,您需要做的就是调用该方法,如下所示:

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

    对于需要字典的请求,例如"create",请继续并提供字典:

    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请求,并希望上面说明了如何完成.

1 个回答
  • 这里有一大堆战术问题:

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

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

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

      小问题,但你使用了很多变量(via var),其中常量(via let)就可以了.本着Swift安全的精神,let尽可能使用.

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

      因此,例如,如果POST在"Empire"模块中执行请求,则URL为:

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

      您可能会做很多请求,所以我建议将其中的大部分放在一个可以反复调用的函数中,而不必在整个地方重复代码.也许像下面这样的函数采用以下参数:

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

      方法(例如"login"vs"fetch_captcha");

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

      异步请求完成时将调用的闭包.

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

      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请求中完成方法和参数的所有必要包装.然后,您需要做的就是调用该方法,如下所示:

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

      对于需要字典的请求,例如"create",请继续并提供字典:

      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请求,并希望上面说明了如何完成.

    2022-12-27 15:40 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有