Alamofire valeur invalide autour du caractère 0

93
Alamofire.request(.GET, "url").authenticate(user: "", password: "").responseJSON() {
    (request, response, json, error) in
    println(error)
    println(json)

}

Ceci est ma demande avec Alamofire, pour une certaine demande cela fonctionne parfois, mais parfois je reçois:

Optional(Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Invalid value around character 0.) UserInfo=0x78e74b80 {NSDebugDescription=Invalid value around character 0.})

J'ai lu que cela peut être dû à un JSON invalide, mais la réponse est une chaîne json statique que j'ai validée dans le validateur JSON comme valide. Il contient des caractères å ä ö et du HTML.

Pourquoi ai-je parfois cette erreur?

Seigneur Vermillion
la source
12
Une chose que j'aime faire lorsque j'obtiens cette erreur est de commenter le responseJSON() { ... }bloc et de le remplacer par .responseString { _, _, s, _ in println(s) }. Cela vous permet de voir le json qui est retourné pour rechercher tout texte étrange qui le rendrait impossible parresponseJSON
ad121
Qu'est-ce que le code d'état de la réponse?
Sahil Kapoor
1
J'obtiens un code d'état de 200 et j'obtiens cette erreur. AHHH. La mort cérébrale dans mon cas :). Je ne retournais pas réellement JSON du serveur. Cela résout le problème.
Chris Prince
peut-être que cela fonctionnera si vous utilisez la méthode .POST.
Surjeet Rajput le
Vérifiez votre URL :)
Alok

Réponses:

136

J'ai également fait face au même problème. J'ai essayé responseStringau lieu de responseJSONça et ça a marché. Je suppose que c'est un bug lié à son Alamofireutilisation avec django.

Smit
la source
3
Merci d'avoir fait remarquer cela. J'utilisais responseJSON mais la réponse réelle du serveur était au format XML! Saved me the headache :)
C0D3
sauvé mon projet après des heures face à ce problème.Je devrais définir la réponse au format JSON sur mon serveur. Je ne faisais pas cela, mais une fois que je l'ai fait, je pourrais utiliser responseJSON de alamofire
guijob
Si vous utilisez GET, vous devez vérifier avec responseString uniquement sinon pour POST, vérifiez-le à l'aide de responseJSON. Référence: grokswift.com/updating-alamofire-to-swift-3-0
Anurag Sharma
J'ai perdu des clients à cause de ce problème dans mon application iOS.
Jaseem Abbas
1
Votre réponse est foirée avec du code HTML, vous devez analyser le code HTML et extraire la chaîne json et la convertir en dictionnaire. Je recommande d'essayer SwiftSoup ou pour de meilleures alternatives à parseHtml, consultez stackoverflow.com/questions/31080818/… .
Smit
9

J'ai eu la même erreur lors du téléchargement de l'image sous forme en plusieurs parties dans Alamofire que j'utilisais

multipartFormData.appendBodyPart(data: image1Data, name: "file")

j'ai corrigé en remplaçant par

multipartFormData.appendBodyPart(data: image1Data, name: "file", fileName: "myImage.png", mimeType: "image/png")

J'espère que cela aidera quelqu'un.

Avijit Nagare
la source
J'ai eu des heures à essayer de comprendre cela. Je me demande pourquoi cette solution fonctionne ... Merci!
MXV
7

Que cela vous aide

Alamofire.request(.GET, "YOUR_URL")
     .validate()
     .responseString { response in
         print("Success: \(response.result.isSuccess)")
         print("Response String: \(response.result.value)")
     }
Krutarth Patel
la source
Oui Bro.i inspiré de votre réponse. je viens de télécharger du code pour tout plus frais
Krutarth Patel
6

Le même problème m'est arrivé et cela a finalement été un problème de serveur car le type de contenu n'était pas défini.

Ajouter

.validate(contentType: ["application/json"])

À la chaîne de demande l'a résolu pour moi

Alamofire.request(.GET, "url")
        .validate(contentType: ["application/json"])
        .authenticate(user: "", password: "")
        .responseJSON() { response in
            switch response.result {
            case .Success:
                print("It worked!")
                print(response.result.value)
            case .Failure(let error):
                print(error)
            }
        }
cameronmoreau
la source
6

Dans mon cas, l'URL de mon serveur était incorrecte. Vérifiez l'URL de votre serveur !!

Saeed
la source
C'était le problème pour moi. Je ne peux pas croire que je l'ai manqué. Je dois prendre l'habitude de vérifier d'abord l'URL, et toujours!
LondonGuy
4

J'ai eu la même erreur. Mais j'ai trouvé la solution.

NOTE 1: "Ce n'est pas une erreur Alarmofire", c'est une erreur de serveur.

REMARQUE 2: vous n'avez pas besoin de remplacer "responseJSON" par "responseString".

public func fetchDataFromServerUsingXWWWFormUrlencoded(parameter:NSDictionary, completionHandler: @escaping (_ result:NSDictionary) -> Void) -> Void {

        let headers = ["Content-Type": "application/x-www-form-urlencoded"]
        let completeURL = "http://the_complete_url_here"
        Alamofire.request(completeURL, method: .post, parameters: (parameter as! Parameters), encoding: URLEncoding.default, headers: headers).responseJSON { response in

            if let JSON = response.result.value {
                print("JSON: \(JSON)") // your JSONResponse result
                completionHandler(JSON as! NSDictionary)
            }
            else {
                print(response.result.error!)
            }
        }
    }
Ram Madhavan
la source
4

C'est ainsi que j'ai réussi à résoudre l'erreur 3840 invalide.

Le journal des erreurs

 responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
  1. C'était avec le type d' encodage utilisé dans la requête, le type d'encodage utilisé devrait être accepté dans votre côté serveur .

Afin de connaître l'encodage, je devais parcourir tous les types d'encodage:

default / methodDependent / queryString / httpBody

    let headers: HTTPHeaders = [
        "Authorization": "Info XXX",
        "Accept": "application/json",
        "Content-Type" :"application/json"
    ]

    let parameters:Parameters = [
        "items": [
                "item1" : value,
                "item2": value,
                "item3" : value
        ]
    ]

    Alamofire.request("URL",method: .post, parameters: parameters,encoding:URLEncoding.queryString, headers: headers).responseJSON { response in
        debugPrint(response)
     }
  1. Cela dépend également de la réponse que nous recevons, utilisez le
    • responseString
    • responseJSON
    • responseData

Si la réponse n'est pas un JSON & juste une chaîne dans la réponse, utilisez responseString

Exemple : en cas d'API de connexion / création de jeton:

"20dsoqs0287349y4ka85u6f24gmr6pah"

responseString

Ratz
la source
2

J'ai résolu en utilisant ceci comme en-tête:

let header = ["Content-Type": "application/json", "accept": "application/json"]

Bruno Muniz
la source
2

Dans mon cas, il y avait un extra / dans l'URL.

Alok
la source
1

Il est peut-être trop tard mais j'ai résolu ce problème d'une autre manière non mentionnée ici:

Lorsque vous utilisez .responseJSON(), vous devez définir l'en-tête de réponse avec content-type = application/json, sinon, il plantera même si votre corps est un JSON valide. Donc, peut-être que votre en-tête de réponse est vide ou utilise un autre type de contenu.

Assurez - vous que votre tête de réponse est réglée avec content-type = application/jsonpour .responseJSON()dans Alamofire travail correctement.

guijob
la source
1

Hé les gars, c'est ce que j'ai trouvé être mon problème: j'appelais Alamofire via une fonction d'authentification des utilisateurs: j'ai utilisé la fonction "Login User" avec les paramètres qui seraient appelés depuis le "body" (email: String, password: String) qui serait passé

mon erreur était exactement:

optionnel (alamofire.aferror.responseserializationfailed (alamofire.aferror.responseserializationfailurereason.jsonserializationfailed (error domain = nscocoaerrordomain code = 3840 "valeur invalide autour du caractère 0." userinfo = {nsdebugdescription = valeur invalide autour du caractère 0)

le caractère 0 est la clé ici: ce qui signifie que l'appel pour le "email" ne correspondait pas aux paramètres: Voir le code ci-dessous

func loginUser (email: String, password: String, completed: @escaping downloadComplete) {let lowerCasedEmail = email.lowercased ()

    let header = [
        "Content-Type" : "application/json; charset=utf-8"
    ]
    let body: [String: Any] = [
        "email": lowerCasedEmail,
        "password": password
    ]

    Alamofire.request(LOGIN_USER, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in
        if response.result.error == nil {

            if let data = response.result.value as? Dictionary<String, AnyObject> {
                if let email = data["user"] as? String {
                    self.userEmail = email
                    print(self.userEmail)
                }
                if let token = data["token"] as? String {
                    self.token_Key = token
                    print(self.token_Key)
                }

"email" dans les paramètres de fonction doit correspondre au let "email" lors de l'analyse, alors cela fonctionnera .. Je n'ai plus eu l'erreur ... Et le caractère 0 était le "email" dans le paramètre "body" pour la requête Alamofire:

J'espère que cela t'aides

berkat0789
la source
1

J'envoyais le type incorrect (String) au serveur dans mes paramètres (devait être un Int).

Agrippa
la source
1

L'erreur a été résolue après l'ajout du codage: JSONEncoding.default avec Alamofire.

  Alamofire.request(urlString, method: .post, parameters: 
  parameters,encoding: 
  JSONEncoding.default, headers: nil).responseJSON {  
   response in
   switch response.result {
                   case .success:
                    print(response)
                    break

                    case .failure(let error):
                     print(error)
        }
   }
Krishnan
la source
0

L'application sur laquelle je travaillais ce matin avait la même erreur. Je pensais qu'il s'agissait d'une erreur côté serveur car je ne pouvais pas télécharger une image utilisateur.

Cependant, après avoir vérifié mon API personnalisée, j'ai réalisé qu'après avoir ajouté un certificat SSL à mon site Web que je n'avais pas mis à jour les URL api.swift, les données ne pouvaient pas publier:

let HOME_URL = "http://sitename.io"
let BASE_URL = "http://sitename.io/api"
let UPLOAD_URL = "http://sitename.io/api/user/upload"

J'ai changé les URL en https: //. Problème résolu.

Polygone noble
la source
0

Dans mon cas, je dois ajouter cette clé: "Accepter": "application / json" à ma demande d'en-tête.

Quelque chose comme ça:

let Auth_header: [String:String] = ["Accept":"application/json", "Content-Type" : "application/json", "Authorization":"Bearer MyToken"]

J'espère que cela peut aider quelqu'un.

Dasoga
la source
0

Je suis confronté au même problème et le problème est dans les paramètres.

let params = [kService: service,
                  kUserPath: companyModal.directory_path,
                  kCompanyDomain: UserDefaults.companyDomain,
                  kImageObject: imageString,
                  kEntryArray: jsonString,
                  kUserToken:  UserDefaults.authToken] as [String : Any]

companyModal.directory_pathest l'URL. il est forcé de passer d'une chaîne à une autre, ce qui crée des problèmes côté serveur. Pour résoudre ce problème, je dois donner une valeur par défaut qui en fait une valeur de chaîne.

 let params = [kService: kGetSingleEntry,
                  kUserPath: companyModal.directory_path ?? "",
                  kCompanyDomain: UserDefaults.companyDomain,
                  kUserToken: UserDefaults.authToken,
                  kEntryId: id,
                  ] as [String: Any]
Hitesh Agarwal
la source
0

Vous avez probablement "/" à la fin de votre chemin. S'il ne s'agit pas d'une requête GET, vous ne devez pas mettre "/" à la fin, sinon vous obtiendrez l'erreur

Mark Darry
la source
0

J'ai changé mimeType de "mov" à "multipart / form-data".

Alamofire.upload(multipartFormData: { (multipartFormData) in
            do {
                let data = try Data(contentsOf: videoUrl, options: .mappedIfSafe)
                let fileName = String(format: "ios-video_%@.mov ", profileID)
                multipartFormData.append(data, withName: "video", fileName: fileName, mimeType: "multipart/form-data")

            } catch  {
                completion("Error")
            }
        }, usingThreshold: .init(), to: url,
           method: .put,
           headers: header)

A travaillé pour moi .. :)

K Ravi Kumar
la source
0

Pour mon cas:

let header = ["Authorization": "Bearer \(Authserices.instance.tokenid)"]

J'ai oublié l'espace avant \(après Bearer)

haggag
la source
0

Dans mon cas, l'erreur était due à un e-mail en double. Vous pouvez revérifier votre API sur postman pour voir si la réponse est OK ou non.

Arqam Butt
la source