How to solve NSURLErrorDomain: Cannot decode raw data in swift - ios

I am trying to send request to server. I get status code as 200, content-length is 90956 and result return
FAILURE: Error Domain=NSURLErrorDomain Code=-1015 "cannot decode raw data" in swift 4
I tried to change parameter encoding value as JSONEncoding.Default but nothing happen.
AF.request(url, method: .get, parameters: params, headers:headers)
.responseString { response in
print("Request :- " , response.request as Any)
print("Response error :- ", response.error as Any)
print("Response :- ", response.response as Any)
}
Actual
Data None
Network Duration: 0.06679093837738037s Duration: 2.5987625122070312e-05s
Result: FAILURE: Error Domain=NSURLErrorDomain Code=-1015 "cannot decode raw data"
Expected
Data: 90956 Network Duration: 0.06679093837738037s Duration: 2.5987625122070312e-05s Result: SUCCESS

Related

Alamofire stacking responses

I am using Alamofire to communicating with my API, also I am using RequestInterceptor to catch unauthorized requests or for refreshing the JWT token. When everything is going well, there is no problem at all, but in case of bad response (400,401) Alamofire tries to refresh token and send the request again. There is a strange behavior, since it fails with serialization error:
[Request]: PUT https://my.url.com/unregistered?
[Headers]:
Content-Type: application/json
[Body]:
{"name":"user16","email":"dummy#gmail.com"}
[Response]:
[Status Code]: 400
[Headers]:
Connection: keep-alive
Content-Length: 51
Content-Type: application/json
Date: Sun, 19 Sep 2021 08:13:57 GMT
Server: nginx
[Body]:
{"message": "User with same email already exists"}
{"message": "User with same email already exists"}
[Network Duration]: 0.21983695030212402s
[Serialization Duration]: 0.0001439583720639348s
[Result]: failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.}))))))
It basically read the same answer two times and tell me that it's not a JSON serializable. I am absolutely sure that server returns only one response like JSON, what is totally strange is fact that Alamofire doing this at any time, once it get back with successfully serialized body and second time it fails on serialization. This is the code I am using:
func authorization<T: Decodable>(
_ url: String,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
decoder: JSONDecoder = JSONDecoder(),
headers: HTTPHeaders? = nil,
interceptor: RequestInterceptor? = nil,
withInterceptor: Bool = false
) -> Future<T, ServerError> {
return Future({ promise in
AF.request(
url,
method: method,
parameters: parameters,
encoding: JSONEncoding.default,
headers: headers,
interceptor: withInterceptor ? self : nil
)
.validate(statusCode: [200, 401])
.responseDecodable(completionHandler: { (response: DataResponse<T, AFError>) in
print(response.debugDescription)
switch response.result {
case .success(let value):
self.saveCookies(cookies: HTTPCookieStorage.shared.cookies)
promise(.success(value))
case .failure(let error):
promise(.failure(self.createError(response: response.response, AFerror: error, AFIerror: nil, data: response.data)))
}
})
})
}
Also, I've tried adding multiple status codes to validation, nothing helps at all.
When I've used .responseString to get any thoughts I was able to see the response only once, which is strange too.

post request with body Alamofire

I am trying to post some data to the API, but I keep getting Response status code was unacceptable: 404 error message.. I have checked, the POST parameters and API Url are all correct, example request works on the postman but it is not working on Xcode..
my POST request Url is in this format: {{API}}/postData/Id/block.
my POST request function with Alamofire is as follows:
func postData(token: String, id: String, category: String, completion: #escaping(_ data: DataTobePost) -> Void) {
let header: HTTPHeaders = ["authorization": token]
let parameter: Parameters = [
"Id": id,
"category": category ]
Alamofire.request(API_Configurator.postData, method: .post, parameters: parameter, encoding: JSONEncoding.default, headers: header).validate().responseData(completionHandler: { response in
switch response.result {
case .success(let val):
do {
let data = try JSONDecoder().decode(DataTobePost.self, from: val)
completion(data)
}catch {
print("[DataTobePost Catch Error while decoding response: \(error.localizedDescription)]")
}
case .failure(let error):
print("[DataTobePost Failure Error : \(error.localizedDescription)]")
}
})
}
and the response is:
{
"success": true
}
where am i going wrong, can anyone help through this. (I am quite new to Alamofire)
There is no way to check what is wrong.
If you got the 404 error it means 2 things:
Code was written correctly(it compiles)
Requested page does not exist (404 error)
I think you need to check your API_Configurator.postData.
Usually, it's something simple like extra characters like "//", " ", "." etc.
Or the problem with API.
The best way to check API uses Postman

How to check Alamofire failure of bad internet connection?

How can i check if my Alamofire request Failed because of bad internet connection? I get an error but how can i know that it failed because of that
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x6000007fe6a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey={length = 28, capacity = 28, bytes = 0x1c1e1f96000000000000000000000000 ... 0000000100000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask .<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalUploadTask .<1>"
)
You can get the error message from the failure case like this
Alamofire.request("YourURL", method: .post, parameters: parameters)
.responseJSON { response in
if case .failure(let error) = response.result {
print(error.localizedDescription)//The network connection was lost.
} else if case .success = response.result {
print(response.result.value)
}
}
You can check the failure reason through the underlyingError property from AFError as follows
Alamofire.request("url", method: .post, parameters: parameters)
.responseJSON { response in
if let afError = response.error,
let underlyingError = afError.underlyingError as? URLError {
switch underlyingError.code {
case URLError.notConnectedToInternet:
// do your thing here
default:
// any other URLError code handling
}
}

Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840

I am working on swift project and calling webservice with Alamofire.
But, while calling post method, I am getting following error.
Header file :
let accessTokenHeaderFile = [
"Accept": "application/json",
"Content-Type" :"application/json",
"X-TOKEN" : UtilityClass.sharedInstance.accessTokenString
]
Alamofire.request(urlString, method: .post, parameters: params as? [String:Any], encoding: JSONEncoding.default, headers: accessTokenHeaderFile).responseJSON { response in
requestVC.removeLoader()
switch (response.result) {
case .success:
if response.result.value != nil{
completionHandler (response.result.value)
}
break
case .failure(let error):
failureHandler (error as NSError?)
break
}
}
And the error is
FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
Can anyone suggest me, how to fix this, I tried googling, but whatever I found the answers not helped me.
Error of 3840 saying that the response from server is not a valid JSON string. So you can check you parameters key value may be it’s wrong assign because similar of responseString instead of responseJSON.
Your response is not a valid json hence you're getting this error. Please check the response.response?.statusCode to see what is server returning. And if you want to see the actual response try using responseString or responseData methods instead of responseJSON
e.g.
Alamofire.request(urlString, method: .post, parameters: params as? [String:Any], encoding: JSONEncoding.default, headers: accessTokenHeaderFile). responseData {
You can find out more response methods here

Can not fetch data using Alamofire?

I am trying to fetch data in my iOS app from my Django backend. In postman if I perform a GET request on the following URL http://127.0.0.1:8000/api/places/categories with the params being Key:"Authorization" Value: "Bearer access_token".I get a JSON response.
Inside my app I am doing something like this with the help of Alamofire:
let access_token = "123"
let headers = ["Authorization": "Bearer" + access_token]
Alamofire.request(self.categoriesUrl, method: .get, parameters:nil,encoding: JSONEncoding.default,headers: headers).response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.error)")
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)")
}
}
I get an error saying Authorization Credentials were not provided. I understand this and it asks me to pass in the parameters but the parameters just need a token. So I do something like this:
let access_token = "123"
let params = ["Authorization": "Bearer" + access_token]
Alamofire.request(self.categoriesUrl, method: .get, parameters:params,encoding: JSONEncoding.default,headers: nil).response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.error)")
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)")
}
}
It waits for a while but fails to fetch the data with the following error:
Response: nil
Error: Optional(Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x61800004b0d0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://127.0.0.1:8000/api/places/categories/, NSErrorFailingURLKey=http://127.0.0.1:8000/api/places/categories/, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.})
Data:
EDIT1:
This is very simple to fix, I guess you are using iOS10 or later version of OS. So instead of calling http , just call https, which means the API calling protocol has been changed to http to https in iOS10 and later.
You have a typo here :
let params = ["Authorization": "Bearer" + access_token]
You're missing a space after Bearer.

Resources