Alamofire nieprawidłowa wartość wokół znaku 0

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

}

To jest moja prośba z Alamofire, na pewną prośbę czasami działa, ale czasami dostaję:

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

Czytałem, że może to być spowodowane nieprawidłowym kodem JSON, ale odpowiedzią jest statyczny ciąg json, który został sprawdzony w walidatorze JSON jako prawidłowy. Zawiera znaki å ä ö i trochę HTML.

Dlaczego czasami otrzymuję ten błąd?

Lord Vermillion
źródło
13
Jedną z rzeczy, które lubię robić, gdy pojawia się ten błąd, jest zakomentowanie responseJSON() { ... }bloku i zastąpienie go .responseString { _, _, s, _ in println(s) }. To pozwala zobaczyć plik json, który jest zwracany w celu wyszukania dziwnego tekstu, który uniemożliwiłby jego przeanalizowanie przezresponseJSON
ad121
Co to jest kod statusu odpowiedzi?
Sahil Kapoor
1
Otrzymuję kod statusu 200 i otrzymuję ten błąd. AHHH. Śmierć mózgu w moim przypadku :). W rzeczywistości nie zwracałem JSON z serwera. To rozwiązuje problem.
Chris Prince
może to zadziała, jeśli użyjesz metody .POST.
Surjeet Rajput
Sprawdź swój adres URL :)
Alok

Odpowiedzi:

141

Ja też miałem ten sam problem. Próbowałem responseStringzamiast responseJSONi zadziałało. Myślę, że to błąd związany Alamofirez używaniem go z django.

Smit
źródło
3
Dziękuję za zwrócenie uwagi. Używałem responseJSON, ale rzeczywista odpowiedź z serwera była w formacie XML! Uratował mi ból głowy :)
C0D3
zapisałem mój projekt po godzinach napotkania tego problemu, powinienem ustawić odpowiedź w formacie JSON na moim serwerze. Nie robiłem tego, ale kiedy już to zrobiłem, mogłem użyć odpowiedzi JSON z alamofire
guijob
Jeśli używasz GET, musisz sprawdzić tylko za pomocą responseString, w przeciwnym razie POST sprawdź to za pomocą responseJSON. Źródła
Anurag Sharma
Straciłem klientów z powodu tego problemu w mojej aplikacji na iOS.
Jaseem Abbas
1
Twoja odpowiedź jest pomieszana z html, musisz przeanalizować html, pobrać ciąg json i przekonwertować go na słownik. Polecam wypróbowanie SwiftSoup lub lepsze alternatywy dla parseHtml, spójrz na stackoverflow.com/questions/31080818/… .
Smit
9

Wystąpił ten sam błąd podczas przesyłania obrazu w formie wieloczęściowej w Alamofire, którego używałem

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

naprawiłem, zastępując przez

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

Mam nadzieję, że to komuś pomoże.

Avijit Nagare
źródło
Miałem godziny, próbując to rozgryźć. Zastanawiam się, dlaczego to rozwiązanie działa ... Dziękuję!
MXV
7

Niech to ci pomoże

Alamofire.request(.GET, "YOUR_URL")
     .validate()
     .responseString { response in
         print("Success: \(response.result.isSuccess)")
         print("Response String: \(response.result.value)")
     }
Krutarth Patel
źródło
Tak, Bro.i zainspirowana twoją odpowiedzią. Po prostu
wgrywam
6

Przydarzył mi się ten sam problem i tak naprawdę okazało się, że był to problem z serwerem, ponieważ typ zawartości nie został ustawiony.

Dodawanie

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

Na żądanie łańcuch rozwiązał to za mnie

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
źródło
6

W moim przypadku adres URL mojego serwera był nieprawidłowy. Sprawdź adres URL swojego serwera !!

Saeed
źródło
To był problem dla mnie. Nie mogę uwierzyć, że to przegapiłem. Muszę mieć w zwyczaju sprawdzanie adresu URL w pierwszej kolejności i zawsze!
LondonGuy
4

Mam ten sam błąd. Ale znalazłem na to rozwiązanie.

UWAGA 1: „To nie jest błąd Alarmofire”, jest to przyczyna błędu serwera.

UWAGA 2: Nie musisz zmieniać „responseJSON” na „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
źródło
4

W ten sposób udało mi się rozwiązać nieprawidłowy błąd 3840.

Dziennik błędów

 responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
  1. Było to z typem kodowania użytym w żądaniu, użyty typ kodowania powinien być akceptowany po stronie serwera .

Aby poznać kodowanie, musiałem przejść przez wszystkie typy kodowania:

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. Zależy to również od odpowiedzi, którą otrzymujemy, użyj odpowiedniego
    • responseString
    • responseJSON
    • responseData

Jeśli odpowiedź nie jest plikiem JSON, a w odpowiedzi jest tylko ciąg znaków, użyj parametru responseString

Przykład : w przypadku logowania / tworzenia API tokena:

„20dsoqs0287349y4ka85u6f24gmr6pah”

responseString

Ratz
źródło
2

Rozwiązałem to używając tego jako nagłówka:

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

Bruno Muniz
źródło
2

W moim przypadku w adresie URL był dodatkowy /.

Alok
źródło
1

Może jest już za późno, ale rozwiązałem ten problem w inny, nie wymieniony tutaj sposób:

Kiedy używasz .responseJSON(), musisz ustawić nagłówek odpowiedzi z content-type = application/json, jeśli nie, ulegnie awarii, nawet jeśli twoje ciało jest prawidłowym JSON. Więc może twój nagłówek odpowiedzi jest pusty lub używa innego typu treści.

Upewnij się, że nagłówek odpowiedzi jest ustawiony content-type = application/jsonna .responseJSON()w Alamofire, działa poprawnie.

guijob
źródło
1

Hej ludzie, oto, co uważam za mój problem: dzwoniłem do Alamofire za pomocą funkcji uwierzytelniania użytkowników: użyłem funkcji „Zaloguj się użytkownika” z parametrami, które byłyby wywoływane z „treści” (e-mail: ciąg znaków, hasło: String) To zostanie przekazane

mój błąd to dokładnie:

opcjonalne (alamofire.aferror.responseserializationfailed (alamofire.aferror.responseserializationfailurereason.jsonserializationfailed (error domain = nscocoaerrordomain code = 3840 "nieprawidłowa wartość wokół znaku 0." userinfo = {nsdebugdescription = nieprawidłowa wartość wokół znaku 0

tu kluczem jest znak 0: co oznacza, że ​​wywołanie „e-maila” nie pasuje do parametrów: Zobacz kod poniżej

func loginUser (email: String, hasło: String, zakończone: @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” w parametrach funkcji musi być zgodny z let „email” podczas parsowania, wtedy zadziała .. Nie mam już błędu ... A znak 0 to „email” w parametrze „body” dla żądania Alamofire:

Mam nadzieję że to pomoże

berkat0789
źródło
1

Wysyłałem niewłaściwy typ (String) do serwera w moich parametrach (potrzebne było Int).

agrippa
źródło
1

Błąd został rozwiązany po dodaniu kodowania: JSONEncoding.default z 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
źródło
0

Aplikacja, nad którą pracowałem dziś rano, miała ten sam błąd. Uważałem, że to błąd po stronie serwera, ponieważ nie mogłem przesłać obrazu użytkownika.

Jednak po sprawdzeniu mojego niestandardowego interfejsu API zdałem sobie sprawę, że po dodaniu certyfikatu SSL do mojej witryny internetowej, że nie zaktualizowałem adresów URL api.swift, danych nie można wysłać:

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

Zmieniłem adres URL na https: //. Problem rozwiązany.

Szlachetny wielokąt
źródło
0

W moim przypadku muszę dodać ten klucz: "Accept": "application / json" do mojego żądania nagłówka.

Coś takiego:

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

Mam nadzieję, że to może komuś pomóc.

Dasoga
źródło
0

Mam ten sam problem i problem jest w params.

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

companyModal.directory_pathto adres URL. to wymuszone z łańcucha na dowolny, który powoduje problemy po stronie serwera. Aby rozwiązać ten problem, muszę podać wartość domyślną, która sprawi, że będzie to wartość łańcuchowa.

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

Prawdopodobnie masz znak „/” na końcu ścieżki. Jeśli nie jest to żądanie GET, nie należy umieszczać znaku „/” na końcu, w przeciwnym razie pojawi się błąd

Mark Darry
źródło
0

Zmieniłem mimeType z „mov” na „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)

Pracował dla mnie .. :)

K Ravi Kumar
źródło
0

W moim przypadku:

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

Zapomniałem miejsca przed \(po Bearer)

wiedźma
źródło
0

W moim przypadku błąd wynikał z podwójnego e-maila. Możesz ponownie sprawdzić swoje API na listonoszu, aby sprawdzić, czy odpowiedź jest OK, czy nie.

Arqam Butt
źródło
0

W moim przypadku próbowałem użyć Postmana, aby uzyskać API i ten błąd pochodzi z zaplecza.

Diệp Lân
źródło