Недопустимое значение Alamofire около символа 0

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

}

Это мой запрос с Alamofire, для определенного запроса он иногда работает, но иногда я получаю:

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

Я читал, что это может быть из-за недопустимого JSON, но ответ представляет собой статическую строку json, которую я проверил в валидаторе JSON как действительную. Он действительно содержит символы å ä ö и немного HTML.

Почему я иногда получаю эту ошибку?

Лорд Вермиллион
источник
13
Когда я получаю эту ошибку, я люблю закомментировать responseJSON() { ... }блок и заменить его на .responseString { _, _, s, _ in println(s) }. Это позволяет вам увидеть возвращаемый json для поиска любого нечетного текста, который может сделать его неразборчивым поresponseJSON
ad121 02
Что такое код статуса ответа?
Сахил Капур
1
Я получаю код состояния 200 и получаю эту ошибку. ААА. Смерть мозга в моем случае :). На самом деле я не возвращал JSON с сервера. Это решает проблему.
Крис Принс
может быть, это сработает, если вы используете метод .POST.
Сурджит Раджпут
Проверьте свой URL :)
Алок,

Ответы:

142

Я тоже столкнулся с той же проблемой. Я попробовал responseStringвместо этого, responseJSONи это сработало. Я предполагаю, что это ошибка Alamofireс его использованием django.

Smit
источник
3
Спасибо что подметил это. Я использовал responseJSON, но фактический ответ от сервера был в формате XML! Спасла меня от головной боли :)
C0D3 07
сохранил мой проект после нескольких часов столкновения с этой проблемой. Я должен установить ответ в формате JSON на моем сервере. Я не делал этого, но как только я это сделал, я мог бы использовать responseJSON от alamofire
guijob
Если вы используете GET, вам нужно проверить с помощью responseString, иначе для POST проверьте его с помощью responseJSON. Ссылка: grokswift.com/updating-alamofire-to-swift-3-0
Анураг Шарма
Я потерял клиентов из-за этой проблемы в моем приложении для iOS.
Джасим Аббас
1
Ваш ответ испорчен с html, вам нужно проанализировать html, получить строку json и преобразовать ее в словарь. Я рекомендую попробовать SwiftSoup или, чтобы узнать лучшие альтернативы parseHtml, посмотрите stackoverflow.com/questions/31080818/… .
Smit
9

У меня была такая же ошибка при загрузке изображения в многостраничной форме в Alamofire, как и при использовании

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

Я исправил заменой на

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

Надеюсь, это кому-то поможет.

Авиджит Нагаре
источник
У меня были часы, пытаясь понять это. Интересно, почему это решение работает ... Спасибо!
MXV
7

Пусть это поможет тебе

Alamofire.request(.GET, "YOUR_URL")
     .validate()
     .responseString { response in
         print("Success: \(response.result.isSuccess)")
         print("Response String: \(response.result.value)")
     }
Крутарт Патель
источник
Да, братан вдохновился твоим ответом. я просто загружаю код для любого посвежее
Крутарт Патель
7

В моем случае URL-адрес моего сервера был неверным. Проверьте URL своего сервера !!

Саид
источник
Это было проблемой для меня. Не могу поверить, что пропустил это. Я должен выработать привычку проверять URL-адрес в первую очередь и всегда!
LondonGuy,
6

Та же проблема случилась со мной, и на самом деле она оказалась проблемой сервера, поскольку тип контента не был установлен.

Добавление

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

Чтобы цепочка запросов решила это за меня

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
источник
4

У меня такая же ошибка. Но я нашел решение для этого.

ПРИМЕЧАНИЕ 1: «Это не ошибка Alarmofire», это ошибка сервера.

ПРИМЕЧАНИЕ 2. Вам не нужно менять responseJSON на 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!)
            }
        }
    }
Рам Мадхаван
источник
4

Вот как мне удалось устранить ошибку Invalid 3840 Err.

Журнал ошибок

 responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
  1. Это было с типом кодировки, используемым в запросе, используемый тип кодировки должен быть принят на вашей стороне сервера .

Чтобы узнать кодировку, мне пришлось пройти через все типы кодирования:

по умолчанию / 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. Это также зависит от ответа, который мы получаем, используйте соответствующий
    • responseString
    • responseJSON
    • responseData

Если ответ не является JSON, а просто строка в ответе используйте responseString

Пример : в случае входа в систему / создания токена API:

"20dsoqs0287349y4ka85u6f24gmr6pah"

responseString

Рац
источник
2

Я решил использовать это как заголовок:

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

Бруно Мунис
источник
2

В моем случае в URL-адресе был лишний /.

Алок
источник
1

Может быть, уже слишком поздно, но я решил эту проблему другим способом, не упомянутым здесь:

Когда вы используете .responseJSON(), вы должны установить заголовок ответа content-type = application/json, если нет, он выйдет из строя, даже если ваше тело является действительным JSON. Итак, возможно, ваш заголовок ответа пуст или использует другой тип содержимого.

Убедитесь, что заголовок вашего ответа установлен на, content-type = application/jsonчтобы .responseJSON()Alamofire работал правильно.

guijob
источник
1

Привет, ребята, вот что я обнаружил в своей проблеме: я звонил в Alamofire через функцию аутентификации пользователей: я использовал функцию «Войти в систему» ​​с параметрами, которые будут вызываться из «тела» (электронная почта: строка, пароль: String) Это будет передано

моя ошибка была именно такой:

необязательный (alamofire.aferror.responserializationfailed (alamofire.aferror.responserializationfailurereason.jsonserializationfailed (error domain = nscocoaerrordomain code = 3840 «недопустимое значение вокруг символа 0») userinfo = {nsdebugdescription = недопустимое значение около символа 0

символ 0 является здесь ключевым: это означает, что вызов "электронной почты" не соответствовал параметрам: см. код ниже

func loginUser (адрес электронной почты: строка, пароль: строка, завершено: @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" в параметрах функции должно совпадать с let "email" при синтаксическом анализе, тогда он будет работать .. Я больше не получаю ошибку ... А символ 0 был "email" в параметре "body" для запроса Alamofire:

Надеюсь это поможет

berkat0789
источник
1

Я отправлял серверу неправильный тип (String) в своих параметрах (должен быть Int).

Агриппа
источник
1

Ошибка была устранена после добавления кодировки: JSONEncoding.default с помощью 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)
        }
   }
Кришнан
источник
0

В приложении, над которым я работал сегодня утром, была такая же ошибка. Я считал, что это ошибка на стороне сервера, так как мне не удалось загрузить изображение пользователя.

Однако, проверив свой собственный API, я понял, что после добавления SSL-сертификата на мой веб-сайт, для которого я не обновлял URL-адреса api.swift, данные не удалось опубликовать:

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

Я изменил URL-адрес на https: //. Задача решена.

Благородный многоугольник
источник
0

В моем случае я должен добавить этот ключ: «Accept»: «application / json» к моему запросу заголовка.

Что-то вроде этого:

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

Надеюсь, это кому-то поможет.

Дашога
источник
0

У меня такая же проблема, и проблема в параметрах.

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. он переводится из строки в любую, что создает проблемы на стороне сервера. Чтобы решить эту проблему, я должен указать значение по умолчанию, которое делает его строковым значением.

 let params = [kService: kGetSingleEntry,
                  kUserPath: companyModal.directory_path ?? "",
                  kCompanyDomain: UserDefaults.companyDomain,
                  kUserToken: UserDefaults.authToken,
                  kEntryId: id,
                  ] as [String: Any]
Хитеш Агарвал
источник
0

Вероятно, в конце пути стоит "/". Если это не запрос GET, не ставьте "/" в конце, иначе вы получите сообщение об ошибке.

Марк Дэрри
источник
0

Я изменил mimeType с «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)

Сработало у меня .. :)

К. Рави Кумар
источник
0

В моем случае:

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

Я забыл пробел до \(после Bearer)

хаггаг
источник
0

В моем случае ошибка возникла из-за дублирования электронной почты. Вы можете перепроверить свой API на почтальоне, чтобы узнать, в порядке ли ответ.

Аркам Батт
источник
0

В моем случае я попытался использовать Postman для получения API, и эта ошибка возникла из бэкэнда.

Diệp Lân
источник