web-dev-qa-db-fra.com

Le texte JSON ne commence pas par un tableau ou un objet, et l'option permettant aux fragments de ne pas être définis

J'envoie cette réponse json du serveur pour une demande à mon IOS 7 application. 

{
 "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"
            }
        ]
    }
}
}

J'utilise le code suivant pour analyser l'objet json ci-dessus en objet NSDictionary. 

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

Mais je reçois cette erreur sur le code ci-dessus. 

Error Domain = NSCocoaErrorDomain Code = 3840 "L'opération n'a pas pu être complétée Terminée. (Erreur Cocoa 3840.)" (Le texte JSON n'a pas commencé avec array ou Object et l'option permettant d'autoriser les fragments non définis.) UserInfo = 0x8a8a700 {NSDebugDescription = Le texte JSON n'a pas commencé avec un tableau ou un objet et option pour autoriser les fragments non définis.}

12
LvN

J'ai rencontré la même erreur lors de la consommation d'un flux d'une page php. Tout comme vous l'avez rencontré, la chaîne JSON résultante a passé une inspection visuelle, mais ne parvient pas à être sérialisée. Je soupçonnais qu'il y avait un caractère caché quelque part dans le fil; j'ai donc converti chaque caractère en son équivalent décimal unicode et examiné les résultats:

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

J'ai trouvé cela avant le premier caractère et après le dernier était le caractère # 65279. Après une recherche rapide sur Google, j'ai trouvé Quel est ce personnage? 65279 , où ceci a été identifié comme une marque d'ordre de octets .

Dans mon cas, j'ai pu résoudre ce problème à la source en ouvrant et en enregistrant tous les fichiers php inclus, en utilisant un éditeur de texte offrant une option permettant d'utiliser l'encodage "Encoder dans UTF-8 sans BOM". Pour plus d'informations sur le côté php, voir Comment éviter l'écho du caractère 65279 en php?

10
Dave Burke

Cela est généralement dû à un message d’avertissement émis par votre serveur sans l’afficher dans le tableau des réponses. Par exemple, en PHP, certains "messages d'avertissement" ne sont pas interceptés dans votre tableau. Par conséquent, lorsque vous utilisez enfin "echo json_encode ($ RESPONSE_ARR)", ce n'est pas un format JSON.

2
Kueiapp

Le JSON que vous avez posté a l'air OK. Si c'est ce que votre application iOS a reçu, elle sera analysée. Même si ce n'était pas ok, vous n'obtiendrez pas ce message d'erreur. JSON doit commencer par "[" s'il s'agit d'un tableau et par "{" s'il s'agit d'un dictionnaire comme le vôtre et de tout le reste du message d'erreur que vous avez reçu. Ainsi, même si vous envoyiez '[934knsdf239] [@@@', vous n'obtiendrez pas le message this error, car les données commencent par le [indiquant un tableau. 

Vous devez déboguer ceci dans l'application iOS. Convertissez d'abord les données en chaîne, imprimez-la et vérifiez-la. Si la chaîne est correcte, imprimez les données elles-mêmes - parfois, les utilisateurs parviennent à ajouter 0 octet ou caractères de contrôle, ou des marqueurs d'ordre sur deux octets ou quelque chose de similaire qui est invisible dans la chaîne mais n'est pas un JSON légal. 

L'option NSJSONReadingAllowFragments autorise les JSON uniquement constitués d'une chaîne, d'un nombre, d'une valeur booléenne ou d'une valeur null. Ne l'utilisez pas, à moins que vous ne souhaitiez pouvoir traiter l'un de ces éléments seul. 

1
gnasher729

J'ai rencontré le même problème. Mais j’ai trouvé que l’URL que j’envoyais en tant que param sur serveur était erroné. Il y a eu une petite erreur d'un personnage. Par exemple, j'envoyais l'URL ci-dessous

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

L'erreur était extra et symbole devant les sites faisant des problèmes. Alors j'ai enlevé et symbole et trouvé a travaillé pour moi. Donc, assurez-vous d’envoyer le paramètre correct au serveur. 

0
GSK

Le problème provient de l'analyse de la réponse. Vous essayez de désérialiser une réponse JSON (qui DOIT être contenue dans un NSArray ou un NSDictionary), mais votre réponse ne correspond à rien de ce qui précède (très probablement une simple chaîne).

Vous pouvez essayer d'imprimer votre réponse du serveur. S'il vous plaît utiliser le code dans votre bloc catch comme. et identifier une erreur côté serveur ou non.

Les données de votre serveur ne sont pas au format JSON approprié, puis imprimez les données de votre serveur et vérifiez si les données du serveur sont valides ou non.

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()
0
AshvinGudaliya