I am new to Swift and iOS in general. I am testing and learning how to use a remote api server. I get JSON from Apolloop (Loopback) api when I try authentication and parsing, which I try to use, it gets an error:
Domain Error = NSCocoaErrorDomain Code = 3840 "Operation could not be completed. (Cocoa error 3840.)" (No value.) UserInfo = 0x7fd623e38870 {NSDebugDescription = No value.}
Here is the return value in the string, I obviously get the correct JSON response from Loopback, authentication token, ttl, date and userId:
{"identifier": "BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi", "TTL": 1209600, "created": "2015-07-03T13: 04: 39.791Z", "user ID": 2}
I think the actual problem does NOT occur in the parseJSON method, but in the performLoginRequestWithURL method. It returns an empty string. Something related to asynchronous request. I noticed that the json string variable is not set until it returns from the method, so it returns empty. If I put two println (json) methods, one inside the asynchronous request and one after it, the one that first prints. It makes sense, but I don’t know how to solve it. I need to return json from the post, but I do not know how to do this. Something tells me that I need to use a synchronous request, but I don't know how to do this in this context of getting json from a POST request.
Here is my code:
@IBAction func login() {
let url = getLogin()
if let jsonString = performLoginRequestWithURL(url) {
if let dictionary = parseJSON(jsonString) {
}
}
}
func getLogin() -> NSURL {
let toEscape = "http://localhost:3000/api/Users/login"
let urlString = toEscape.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let url = NSURL(string: urlString)
return url!
}
func performLoginRequestWithURL(url: NSURL) -> String? {
let bodyData = "username=\(textEmail.text)&password=\(textPW.text)"
var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)
var json = ""
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){
response, data, error in
if data != nil {
json = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
}
println(json)
}
return json
}
func parseJSON(jsonString: String) -> [String: AnyObject]? {
if let data = jsonString.dataUsingEncoding(NSUTF8StringEncoding) {
var error: NSError?
if let json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &error) as? [String: AnyObject] {
return json
} else if let error = error {
println("JSON Error: \(error)")
} else {
println("Unknown JSON Error")
}
}
return nil
}
source
share