Why does the error Code = 3840 Parsing JSON occur?

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:

//Login button pressed
@IBAction func login() {
    //Gets url string
    let url = getLogin()
    //Posts url with UITextField data.
    if let jsonString = performLoginRequestWithURL(url) {
        //Error occurs in the parseJSON method
        if let dictionary = parseJSON(jsonString) {
            /*
            if let at = dictionary["id"] as? String {
                accesstoken = at
            }
            if let id = dictionary["userId"] as? Int {
                println(id)
            }
            */
        }
    }

}

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 {
            //Here where the error comes back.
            println("JSON Error: \(error)")
        } else {
            println("Unknown JSON Error")
        }
    }
    return nil
}
+4
source share
3 answers

parseJSON NSURLConnection.sendAsynchronousRequest, , , .

if data != nil {
    json = NSString(data: data, encoding: NSUTF8StringEncoding) as! String
    println("json: \(json)")

    if let dictionary = parseJSON(jsonString) {
        println("dictionary: \(dictionary)")
   }
}
+1

parseJSON , , , parseJSON .

let jsonString = "{\"id\":\"BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi\",\"ttl\":1209600,\"created\":\"2015-07-03T13:04:39.791Z\",\"userId\":2}"
println("jsonString:\n\(jsonString)")

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
}

let obj = parseJSON(jsonString)
println("obj:\n\(obj!)")

:

jsonString: { "ID": "BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi", "": 1209600, "": "2015-07-03T13: 04: 39.791Z", " ": 2}

OBJ: [created: 2015-07-03T13: 04: 39.791Z, userId: 2, ttl: 1209600, id: BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi]

, Unit Tests.

+4
NSArray *jsonObj = [NSJSONSerialization JSONObjectWithData:data
                                                   options:kNilOptions
                                                     error:&err];

if ( err )
{
    // code 3840, data.length = 1 byte, so empty and no error
    if ( NSPropertyListErrorMinimum == err.code )
    {
        return [NSArray array];
    }

    *error = err;
    return nil;
}
0

All Articles