为什么我收到错误代码=3840 解析 JSON?
Why do I get an error Code=3840 Parsing JSON?
我是 Swift 和 iOS 开发的新手。我正在测试和学习如何使用远程服务器 api。我在尝试身份验证时从 Strongloop(环回)api 获得 JSON,我尝试使用的解析出现错误:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (No value.) UserInfo=0x7fd623e38870 {NSDebugDescription=No value.}
这是字符串中的 return 值,我显然从 Loopback 得到了正确的 JSON 响应、身份验证令牌、ttl、日期和用户 ID:
{"id":"BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi","ttl":1209600,"created":"2015-07-03T13:04:39.791Z","userId":2}
我认为实际问题不在 parseJSON 方法中,而是在 performLoginRequestWithURL 方法中。它是 returning 一个空字符串。与异步请求有关。我注意到 json 字符串变量直到从方法中被 returned 之后才被设置,所以它 returned 为空白。如果我放置两个 println(json) 方法,一个在异步请求中,一个在它之后,第一个在打印之后。这在某种程度上是有道理的,但我不知道如何解决这个问题。我需要从 post 中获取 json returned,但我不知道如何捕获它。有些东西告诉我我需要使用同步请求,但我不知道如何在从 POST 请求获取 json 的上下文中做到这一点。
这是我的代码:
//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's where the error comes back.
println("JSON Error: \(error)")
} else {
println("Unknown JSON Error")
}
}
return nil
}
我用问题中的字符串测试了 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","ttl":1209600,"created":"2015-07-03T13:04:39.791Z","userId":2}
obj:
[created: 2015-07-03T13:04:39.791Z, userId: 2, ttl: 1209600, id: BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi]
创建小型独立测试或编写单元测试的课程内容。
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)")
}
}
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;
}
我是 Swift 和 iOS 开发的新手。我正在测试和学习如何使用远程服务器 api。我在尝试身份验证时从 Strongloop(环回)api 获得 JSON,我尝试使用的解析出现错误:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (No value.) UserInfo=0x7fd623e38870 {NSDebugDescription=No value.}
这是字符串中的 return 值,我显然从 Loopback 得到了正确的 JSON 响应、身份验证令牌、ttl、日期和用户 ID:
{"id":"BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi","ttl":1209600,"created":"2015-07-03T13:04:39.791Z","userId":2}
我认为实际问题不在 parseJSON 方法中,而是在 performLoginRequestWithURL 方法中。它是 returning 一个空字符串。与异步请求有关。我注意到 json 字符串变量直到从方法中被 returned 之后才被设置,所以它 returned 为空白。如果我放置两个 println(json) 方法,一个在异步请求中,一个在它之后,第一个在打印之后。这在某种程度上是有道理的,但我不知道如何解决这个问题。我需要从 post 中获取 json returned,但我不知道如何捕获它。有些东西告诉我我需要使用同步请求,但我不知道如何在从 POST 请求获取 json 的上下文中做到这一点。
这是我的代码:
//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's where the error comes back.
println("JSON Error: \(error)")
} else {
println("Unknown JSON Error")
}
}
return nil
}
我用问题中的字符串测试了 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","ttl":1209600,"created":"2015-07-03T13:04:39.791Z","userId":2}
obj: [created: 2015-07-03T13:04:39.791Z, userId: 2, ttl: 1209600, id: BHzKnjrbUPn9KSC1GegQTNHJFNwfuifNXPfZuKkYxC5IwRDEHuerurvSdBMzzrVi]
创建小型独立测试或编写单元测试的课程内容。
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)")
}
}
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;
}