Alamofire valor inválido em torno do caractere 0

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

}

Este é o meu pedido com Alamofire, para um determinado pedido às vezes funciona, mas às vezes recebo:

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

Eu li que isso pode ser devido a JSON inválido, mas a resposta é uma string json estática que validei no validador JSON como válida. Ele contém caracteres å ä ö e algum HTML.

Por que às vezes recebo esse erro?

Lord Vermillion
fonte
12
Uma coisa que gosto de fazer quando recebo esse erro é comentar o responseJSON() { ... }bloco e substituir por .responseString { _, _, s, _ in println(s) }. Isso permite que você veja o json que é retornado para procurar qualquer texto estranho que o tornaria incomparável porresponseJSON
ad121
O que é o código de status de resposta?
Sahil Kapoor,
1
Recebo um código de status de 200 e este erro. AHHH. Morte cerebral no meu caso :). Na verdade, eu não estava retornando JSON do servidor. Isso resolve tudo.
Chris Prince
pode ser que funcione se você usar o método .POST.
Surjeet Rajput
Verifique seu Url :)
Alok

Respostas:

136

Eu também enfrentei o mesmo problema. Eu tentei em responseStringvez de responseJSONe funcionou. Eu acho que este é um bug em Alamofireusá-lo com django.

Smit
fonte
3
Obrigado por apontar isso. Eu estava usando o responseJSON, mas a resposta real do servidor estava no formato XML! Me salvou da dor de cabeça :)
C0D3
salvei meu projeto depois de horas enfrentando este problema. Devo definir a resposta no formato JSON no meu servidor. Eu não estava fazendo isso, mas uma vez que o fizesse, poderia usar o responseJSON de alamofire
guijob
Se você estiver usando GET, será necessário verificar com responseString, caso contrário, para POST, verifique-o usando responseJSON. Referência: grokswift.com/updating-alamofire-to-swift-3-0
Anurag Sharma
Perdi clientes devido a este problema em meu aplicativo iOS.
Jaseem Abbas,
1
Sua resposta está confusa com html, você precisa analisar o html e obter a string json e convertê-la em dicionário. Eu recomendo experimentar o SwiftSoup ou para melhores alternativas para parseHtml, consulte stackoverflow.com/questions/31080818/… .
Smit de
9

Recebi o mesmo erro ao carregar a imagem no formulário de várias partes no Alamofire que estava usando

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

eu consertei substituindo por

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

Espero que isso ajude alguém.

Avijit Nagare
fonte
Passei horas tentando descobrir isso. Eu me pergunto por que essa solução funciona ... Obrigado!
MXV
7

Que isso te ajude

Alamofire.request(.GET, "YOUR_URL")
     .validate()
     .responseString { response in
         print("Success: \(response.result.isSuccess)")
         print("Response String: \(response.result.value)")
     }
Krutarth Patel
fonte
Sim, irmão, inspirado em sua resposta. Acabei de enviar o código para qualquer calouro
Krutarth Patel
6

O mesmo problema aconteceu comigo e acabou sendo um problema do servidor, pois o tipo de conteúdo não foi definido.

Adicionando

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

Para a cadeia de pedidos resolvido para mim

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
fonte
6

No meu caso, o URL do meu servidor estava incorreto. Verifique o URL do seu servidor !!

Saeed
fonte
Esse foi o problema para mim. Eu não posso acreditar que perdi isso. Eu tenho que criar o hábito de verificar a URL primeiro, e sempre!
LondonGuy
4

Eu tenho o mesmo erro. Mas encontrei a solução para isso.

NOTA 1: "Não é erro Alarmofire", é por causa de erro do servidor.

NOTA 2: você não precisa alterar "responseJSON" para "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
fonte
4

Foi assim que consegui resolver o erro Invalid 3840.

O log de erros

 responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
  1. Foi com o tipo de codificação usado na solicitação, o tipo de codificação usado deve ser aceito no lado do servidor .

Para saber a codificação, tive que percorrer todos os tipos de codificação:

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. Também depende da resposta que estamos recebendo, use o apropriado
    • responseString
    • responseJSON
    • responseData

Se a resposta não for um JSON e apenas string na resposta, use responseString

Exemplo : no caso de login / criar token API:

"20dsoqs0287349y4ka85u6f24gmr6pah"

responseString

Ratz
fonte
2

Resolvi usando isso como cabeçalho:

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

Bruno Muniz
fonte
2

No meu caso, havia um extra / na URL.

Alok
fonte
1

Talvez seja tarde demais, mas resolvi esse problema de outra forma não mencionada aqui:

Ao usar .responseJSON(), você deve definir o cabeçalho de resposta com content-type = application/json, se não, ele irá travar mesmo se seu corpo for um JSON válido. Então, talvez seu cabeçalho de resposta esteja vazio ou usando outro tipo de conteúdo.

Certifique-se de que seu cabeçalho de resposta esteja configurado content-type = application/jsonpara .responseJSON()funcionar corretamente no Alamofire.

guijob
fonte
1

Olá pessoal, descobri que era o meu problema: estava chamando o Alamofire através de uma função para autenticar usuários: usei a função "Login do usuário" com os parâmetros que seriam chamados a partir do "corpo" (e-mail: String, senha: String) Isso seria aprovado

meu erro foi exatamente:

opcional (alamofire.aferror.responseserializationfailed (alamofire.aferror.responseserializationfailurereason.jsonserializationfailed (domínio do erro = nscocoaerrordomain code = 3840 "valor inválido em torno do caractere 0." userinfo = {nsdebugdescription = valor inválido em torno do caractere 0

o caractere 0 é a chave aqui: o que significa que a chamada para o "e-mail" não correspondia aos parâmetros: Veja o código abaixo

func loginUser (email: String, password: String, concluído: @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" nos parâmetros de função deve corresponder a "email" let ao analisar, então ele funcionará .. Eu não recebi mais o erro ... E o caractere 0 era o "email" no parâmetro "corpo" para a solicitação Alamofire:

Espero que isto ajude

berkat0789
fonte
1

Estava enviando o tipo impróprio (String) para o servidor nos meus parâmetros (precisava ser um Int).

Agripa
fonte
1

O erro foi resolvido após adicionar a codificação: JSONEncoding.default com 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
fonte
0

O aplicativo em que trabalhei esta manhã apresentou o mesmo erro. Acreditei ser um erro do lado do servidor, pois não consegui fazer upload de uma imagem de usuário.

No entanto, ao verificar minha API personalizada, percebi que depois de adicionar um certificado SSL ao meu site que não atualizei os URLs api.swift, os dados não conseguiram postar:

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

Mudei o URL para https: //. Problema resolvido.

Nobre Polígono
fonte
0

No meu caso, tenho que adicionar esta chave: "Aceitar": "application / json" à minha solicitação de cabeçalho.

Algo assim:

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

Espero que isso possa ajudar alguém.

Dasoga
fonte
0

Eu enfrento o mesmo problema e o problema está nos parâmetros.

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

companyModal.directory_pathé url. é coagido de string para qualquer que cria problemas no lado do servidor. Para resolver esse problema, preciso fornecer um valor padrão que o torna um valor de string.

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

Provavelmente você tem "/" no final do seu caminho. Se não for um pedido GET, você não deve colocar "/" no final, caso contrário você obterá o erro

Mark Darry
fonte
0

Eu mudei o mimeType de "mov" para "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)

Funcionou para mim .. :)

K Ravi Kumar
fonte
0

Para o meu caso:

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

Eu esqueci o espaço antes \(depois Bearer)

haggag
fonte
0

No meu caso, o erro foi devido a email duplicado. Você pode verificar novamente sua API no carteiro para ver se a resposta está OK ou não.

Arqam Butt
fonte