How to check Alamofire failure of bad internet connection? - ios

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

Related

Get Response using Alamofire

I am using Alamofire to make Get Response but unable to get the Valid Response . I am using below details . I dono where i am making mistake.
let myID = MEGHA-WORK SE-107
let headers = ["Authorization": "Basic \(base64Credentials)" , "ID": (myID).trimmingCharacters(in: .whitespaces) ]
let parameters:Parameters = ["ID": (myID).trimmingCharacters(in: .whitespaces)]
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 60
manager.request(url, method: .get, parameters: parameters, encoding: URLEncoding.queryString , headers: headers).responseJSON { (response) in
debugPrint(response)
if response.response?.statusCode == 200 || response.response?.statusCode == 201 {
if let value = response.result.value {
let json = JSON(value)
print(json)
completion(json, nil)
}
}
Task <343CF648-7C9A-4E03-9A82-A88BC41EA926>.<6> finished with error - code: -1005
Response
[Request]: GET https://my-services.myservices.com:443/prweb/api/v1/cases?ID=MEGHA-WORK%20SE-107
[Response]: nil
[Data]: 0 bytes
[Result]: FAILURE: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x109ce9500 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x10d53db00 [0x1b271c310]>{length = 16, capacity = 16, bytes = 0x100201bba06d196d0000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://my-services.myservices.com:443/prweb/api/v1/cases?ID=MEGHA-WORK%20SE-107, NSErrorFailingURLKey=https://my-services.myservices.com:443/prweb/api/v1/cases?ID=MEGHA-WORK%20SE-107, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.}
[Timeline]: Timeline: { "Request Start Time": 553592494.567, "Initial Response Time": 553592497.615, "Request Completed Time": 553592497.615, "Serialization Completed Time": 553592497.616, "Latency": 3.049 secs, "Request Duration": 3.049 secs, "Serialization Duration": 0.000 secs, "Total Duration": 3.049 secs }
It seems that the reason is already printed there:
Code=-1005 "The network connection was lost."
Restarting the simulator and erasing all content and settings seems to fix this for others (Simulator->Hardware->Erase All Content and Settings...)
Please check this thread.
You can handle this way :
if (responseJson.response?.statusCode)! > 200 && (responseJson.response?.statusCode)! < 300{
// handle as appropriate because the response will be success
} else {
}
It may helps you to handle the crash. Thank you

Alamofire post method in iOS Swift 4?

For getting push notification here i am sending postitem, token, like count and currentname using alamofire post method(pod version alamofire 4.5). I did not get any response when post method called and it does not show any errors.
I tried keeping breaking points in alamofire function, it call alamofire.requestion then it goes out function.
Here is the code tried to send post method to backend:
func postNotification(postItem: String, post: Post) {
print("Get token from post:::",post.token)
print(postItem)
let token = UserDefaults.standard.string(forKey: "token")
let headers: HTTPHeaders = ["Content-Type" :"application/x-www-form-urlencoded"]
let parameters : [String:Any] = ["count":post.likeCount!, "likedby":currentName, "postId=":postItem, "token": post.token!]
Alamofire.request("http://highavenue.co:9000/likesnotification/", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { (response:DataResponse<Any>) in
switch(response.result) {
case .success(_):
if let data = response.result.value{
print(data)
}
break
case .failure(_):
print(response.result.error as Any)
break
}
}
}
Getting console error like this
2018-07-10 14:21:07.980212+0530 HighAvenue[10584:4236493] Task <B5FC98AB-C3FE-
4D4F-9A93-72D3FFE35DF7>.<1> finished with error - code: -1001
Optional(Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."
UserInfo={NSUnderlyingError=0x1c0e478f0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://highavenue.co:9000/likesnotification/, NSErrorFailingURLKey=http://highavenue.co:9000/likesnotification/, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.})
That is because you are not setting request time in your network call, by default your request time is a small interval, so please increase request timeout time. something like this,
let request = NSMutableURLRequest(url: URL(string: "")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.timeoutInterval = 120 // 120 secs
let values = ["key": "value"]
request.httpBody = try! JSONSerialization.data(withJSONObject: values, options: [])
Alamofire.request(request as! URLRequestConvertible).responseJSON {
response in
// do whatever you want here
}
Second mistake in your code is you are trying to access http url which are by default are not allowed so you have to by pass this security from your app, Please refer to this answer in order to remove this security layer from your app.
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection

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.

Alamofire returns "The request timed out" with multipart image upload, but no problems with Postman

I am trying to POST data with an image using multipart upload with Alamofire. But it always returns "The request timed out" error.
When tried the same web service with Postman, it works as it should.
Basically Alamofire keeps trying for sometime,and returns this error, but with Postman I can see that the response is almost immediate and no timeout is recieved.
Here is a the helper method I created for the post request:
class func postRequestWithImage(image: UIImage, params : [String : String],success:#escaping (JSON) -> Void, failure:#escaping (NSError) -> Void){
SVProgressHUD.show()
Alamofire.upload(multipartFormData: { (multipartFormData) in
let imageData : Data = UIImageJPEGRepresentation(image, 0.6)!
for (key, value) in params{
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
multipartFormData.append(imageData, withName: "image")
}, to: WEBSERVICE_URL) { (encodingResult) in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
if response.result.isSuccess{
success(JSON(response.result.value!))
SVProgressHUD.dismiss()
}
else{
failure(response.result.error! as NSError)
}
}
case .failure(let encodingError):
failure(encodingError as NSError)
print(encodingError)
}
}
}
The debug response for the same is:
[Request]: http://website.com/v1/service/
[Response]: nil
[Data]: 0 bytes
[Result]: FAILURE: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x6080006441a0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://website.com/v1/service/, NSErrorFailingURLKey=http://website.com/v1/service/, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}
[Timeline]: Timeline: { "Request Start Time": 510773039.719, "Initial Response Time": 510773051.183, "Request Completed Time": 510773120.615, "Serialization Completed Time": 510773120.615, "Latency": 11.464 secs, "Request Duration": 80.895 secs, "Serialization Duration": 0.000 secs, "Total Duration": 80.896 secs }
I solved this. In my case there was a careless mistake. I used an extra slash in the url. I changed the web api to a different folder and while changing it in the iOS code I made this mistake.
I also had some changes made to the .htaccess file, so the request was not giving 404 error but instead trying to connect to that false address. errors that a beginner web developer will make

SoundCloud API: GET request fails with code -1005, using iOS/Alamofire

I'm working on an iOS app where SoundCloud users log in with OAuth in a web view and then the app makes HTTP requests to the SoundCloud API via Alamofire. I've successfully authenticated the user and stored their token (using ABMSoundCloudAPI), but GET requests to https://api.soundcloud.com/me are failing with a -1005 error, "The network connection was lost." This seems to be a common problem with iOS as discussed here, however resetting the simulator doesn't solve the problem for me and the problem also occurs when using a device. I've also tried:
Removing and re-adding the wifi network
Retrying the request programmatically if it fails
Adding a header with "Connection": "Close"
I see the same error in every case. Are there other headers I should try? I'm using these libraries via Cocoapods:
ABMSoundCloudAPI (0.2.1)
AFNetworking (2.6.1)
AFOAuth2Manager (2.2.0)
Alamofire (3.1.2)
SwiftyJSON (2.3.1)
Here is my code:
var retryCount = 0
func getUserInfo(token:String) {
let headers = ["Connection": "Close"]
Alamofire.request(.GET, "https://api.soundcloud.com/me?oauth_token=\(token)", parameters: ["client_id":clientId], encoding: .JSON, headers: headers)
.responseJSON { response in
guard response.result.error == nil else {
print("error calling GET on /me")
print(response.result.error)
if self.retryCount < 2 {
if let token = self.defaults.stringForKey("sc_key_token") {
self.getUserInfo(token)
++self.retryCount
}
}
return
}
guard let value = response.result.value else {
print("Error: did not receive data")
return
}
let user = JSON(value)
print("User info: " + user.description)
}
}
Error message:
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x126248c10 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://api.soundcloud.com/me?oauth_token=USER_TOKEN, NSErrorFailingURLKey=https://api.soundcloud.com/me?oauth_token=USER_TOKEN, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.}
It seems that this was caused by the request encoding. When I switched from .JSON to .URL, the 1005 error went away.

Resources