我正在尝试执行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
请求,并希望上面说明了如何完成.
这里有一大堆战术问题:
您正在创建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
请求,并希望上面说明了如何完成.