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