JSON文本不以数组或对象和选项开头,以允许未设置片段

时间:2014-01-30 09:27:47

标签: ios iphone ios7

我正在从服务器发送这个json响应,请求我的IOS 7应用程序。

{
 "root": {
    "success": "1",
    "message": "Successfully retrieved data.",
    "data": {
        "records": [
            {
                "receipt_key": "xxxxxxxx",
                "receipt_id": "xxxxxxxx",
                "store_name": "xxxxxx",
                "amount": "xxxx",
                "date_purchase": "xxxxxxxx",
                "is_processed": "x",
                "created_on": "xxxxxxxx",
                "modified_on": "xxxxxxxx",
                "modified_on_millis": "xxxxxxxx",
                "user_folder": "xxxxxxxx",
                "category_id": "xxxxxxxx",
                "is_deleted": "x",
                "currency_id": "xxxxxxxx"
            }
        ]
    }
}
}

我使用以下代码解析上面的json到NSDictionary对象。

 NSMutableDictionary *json=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];

但是我在上面的代码中遇到了这个错误。

  

错误域= NSCocoaErrorDomain代码= 3840“操作不能   完成。 (可可错误3840.)“(JSON文本没有以数组或   允许片段未设置的对象和选项。)UserInfo = 0x8a8a700   {NSDebugDescription = JSON文本不是以数组或对象开头的   允许片段未设置的选项。}

5 个答案:

答案 0 :(得分:10)

从php页面使用Feed时遇到了同样的错误。就像您遇到的那样,生成的json字符串通过了视觉检查,但无法序列化。我怀疑是饲料中有一个隐藏的字符,所以我将每个字符转换为其unicode十进制等值并检查结果:

NSString *feedStr = [[NSString alloc] initWithData:feedData encoding:NSUTF8StringEncoding];
for(int i=0; i<[feedStr length]; ++i)
{
    unichar c = [feedStr characterAtIndex:i];
    NSLog(@"decimal char %d", c);
}

我发现在第一个角色之前和最后一个角色之后是角色#65279。快速谷歌搜索后,我找到What is this char? 65279,其中标识为byte order mark

在我的情况下,我能够通过打开并保存所有包含的php文件来解决这个问题,使用文本编辑器提供了一个选项,可以在没有BOM的情况下使用UTF-8编码&#34;编码。有关php端的更多信息,请参阅How to avoid echoing character 65279 in php?

答案 1 :(得分:2)

这通常是因为从服务器抛出一些警告消息而没有将其放入响应数组中。例如在PHP中,一些&#34;警告消息&#34;没有被你的数组捕获,所以当你最终使用&#34; echo json_encode($ RESPONSE_ARR),&#34;它不是JSON格式。

答案 2 :(得分:1)

您发布的JSON看起来很好。如果这是您的iOS应用程序收到的,它将被解析。即使它不好,您也不会收到此错误消息。 JSON必须以&#39; [&#39;如果它是一个数组,并且&#39; {&#39;如果它是像你这样的字典,其他一切你得到的错误信息。即使你发送了[934knsdf239] [@@@&#39;你不会得到这个错误信息,因为数据以[表示一个数组开头]开头。

您需要在iOS应用程序中对此进行调试。首先将数据转换为字符串并打印并检查它。如果字符串看起来不错,那么打印数据本身 - 有时人们设法添加0字节或控制字符,或两个字节顺序标记或类似的东西在字符串中不可见但不是合法的JSON。

选项NSJSONReadingAllowFragments允许JSON只包含字符串,数字,布尔值或空值。不要使用此功能,除非您希望能够自行处理其中一个。

答案 3 :(得分:0)

我遇到了同样的问题。但是我发现我作为服务器向服务器发送的Url是错误的。有一个字符错误。例如,我发送了以下网址

URL = https://somerUrl/api/v2/&venues/search?client_id=jkdasljf3242jka-fsdf-fadsfasd&lat=40.712488&long=-74.006277&distance=25

错误是额外的&amp;在制造麻烦的场地前面的象征。所以我删除了&amp;符号,发现对我有用。因此,请确保您正在向服务器发送正确的参数。

答案 4 :(得分:0)

问题来自响应解析。您正在尝试反序列化JSON响应(必须包含在NSArrayNSDictionary中),但您的响应不是上述(很可能是一个简单的字符串)。

您可以尝试打印服务器响应。请使用catch块中的代码。并识别服务器端的错误。

您的服务器数据不是正确的JSON格式,然后打印出您的服务器数据并检查服务器数据是否有效。

URLSession.shared.dataTask(with: url) { (data, response, error) in

        if let jsonData = data {
            do {
                let parsedData = try JSONSerialization.jsonObject(with: jsonData, options: .mutableLeaves) as! [String: AnyObject]
            }
            catch let err{
                print("\n\n===========Error===========")
                print("Error Code: \(error!._code)")
                print("Error Messsage: \(error!.localizedDescription)")
                if let data = data, let str = String(data: data, encoding: String.Encoding.utf8){
                    print("Server Error: " + str)
                }
                debugPrint(error)
                print("===========================\n\n")

                debugPrint(err)
            }
        }
        else {
            debugPrint(error as Any)
        }

    }.resume()