The network connection is lost in swift - ios

I am getting an error time to time while making requests,
Optional(Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <BB6171AF-E4AF-49F2-ACEE-A2CDA67B825E>.<3>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <BB6171AF-E4AF-49F2-ACEE-A2CDA67B825E>.<3>",
"LocalDataPDTask <BB6171AF-E4AF-49F2-ACEE-A2CDA67B825E>.<3>",
"LocalDataTask <BB6171AF-E4AF-49F2-ACEE-A2CDA67B825E>.<3>"
), NSLocalizedDescription=The network connection was lost., _kCFStreamErrorDomainKey=4, NSErrorFailingURLStringKey=https://url, NSErrorFailingURLKey=https://url})
Why am I getting this error?
I have a method which handles api calls called retry() and depending on the status i need to refresh my token and then retry the same request again. So what I have done is check whether the response after excuting the initial api call is SOMECODE and then refresh the access token if it is calling the refreshAccessToken method and depending on its response if it's a success then I recursively call the same function retry() again and excute the logic. It works fine sometimes and sometimes it gives the above error. The code which performs the above operation is posted below,
if responseDescDisplay == "SOMECODE"{
refreshAccessToken(){ isSuccess,isFailed, errCode in
if isSuccess {
retry(urlString: urlString, method: method, requestBody: requestBody, completionHandler: completionHandler)
performRetry = true;
}else{
if !performRetry {
if errCode.isEmpty {
completionHandler(nil,nil,"OHNO");
}else{
completionHandler(nil,nil,"ERROR");
}
}
}
My access token refreshing method looks something like this,
URLSession.shared.dataTask(with: tokenRegenerateRequest) { data, res, err in
print("EROR: ", err)
print("DARA: ", data)
if err != nil {
print("IN HERE")
completionHandler(false, false, "INTERNAL_SERVER_ERROR");
}
guard let data = data, err == nil else {return}
guard let httpResponse = res as? HTTPURLResponse else {
return
}
// print("REGENRATING TOKEN \(httpResponse.statusCode) \(res)");
if httpResponse.statusCode == 200 {
if !data.isEmpty {
do {
let decodedResponse = try! JSONDecoder().decode(RefreshTokenResponse.self, from: data);
print("ACCESS TOKEN REGENRATE REQUEST: ", decodedResponse)
if !decodedResponse.accessToken.isEmpty && !decodedResponse.refreshToken.isEmpty {
completionHandler(true,false, "")
} else {
print("HERE1")
completionHandler(false,true,"")
}
}catch{
print("HERE2")
completionHandler(false,true,"")
}
} else {
print("HERE3")
completionHandler(false,true,"")
}
}else {
print("HERE4", httpResponse.statusCode)
completionHandler(false,true,"")
}
}.resume()
What am i doing wrong. Why do I keep getting the above error? Please can anyone post/suggest a possible way to overcome this issue? Please don't suggest to use any other libraries since I am stick to URLSession. Thanks in advance.

Related

Firebase method is returning an unknown Error

I'm trying to send data to Cloud Storage using the Firebase SDK for iOS. In doing so I'm creating a reference (StorageReference) in this way:
let storageRef = Storage.storage().reference(forURL: Config.CONFIG_ROOF_REF).child("Posts").child(videoIDString)
And using the putFile method:
storageRef.putFile(from: videoURL, metadata: nil) { (metadata, error) in
if error != nil{
ProgressHUD.showError(error?.localizedDescription)
return
}
storageRef.downloadURL(completion: { (url, error) in
if error != nil {
return
}else {
self.videourl = url?.absoluteString
onSuccess(videourl!)
}
})
}
I pass in the argument videoURL and I receive back the error:
An unknown error occurred, please check the server response
I cannot understand why I receive that error since the videoURL I'm passing seems legit.
The videoURL I'm passing is this one:
file:///Users/andreagualandris/Library/Developer/CoreSimulator/Devices/7D3329AC-AD8D-4553-AC61-FDF8435134B6/data/Containers/Data/PluginKitPlugin/8229E521-A7A2-4C09-8312-CC6106C2FED8/tmp/trim.7CC60B3A-6982-4F42-AA63-ED094288A562.MOV
So I think this is a normal URL and there shouldn't be any problem with it.
The actual server response on the console is :
2020-01-26 10:31:27.107215+0100 InstagramClone[2517:235684] Task <4AC8F3F2-1CC6-4064-BBF7-6D0375769C9A>.<1> finished with error [-1] Error Domain=NSURLErrorDomain Code=-1 "unknown error" UserInfo={NSErrorFailingURLStringKey=https://firebasestorage.googleapis.com/v0/b/instagramclone-1ed36.appspot.com/o/Posts%2F412BA396-6CAD-4197-817F-1AA0D9E6E6FE?uploadType=resumable&name=Posts%2F412BA396-6CAD-4197-817F-1AA0D9E6E6FE&upload_id=AEnB2UoAHEWQ0WDv_Id2TK_xSL_71Jrj8kbmuDfLpGkO8fBe6e9sBF74QUj5r0MLdltJN79z5fWAtoqOx8JSAfpppyPe6qKrxA&upload_protocol=resumable, NSErrorFailingURLKey=https://firebasestorage.googleapis.com/v0/b/instagramclone-1ed36.appspot.com/o/Posts%2F412BA396-6CAD-4197-817F-1AA0D9E6E6FE?uploadType=resumable&name=Posts%2F412BA396-6CAD-4197-817F-1AA0D9E6E6FE&upload_id=AEnB2UoAHEWQ0WDv_Id2TK_xSL_71Jrj8kbmuDfLpGkO8fBe6e9sBF74QUj5r0MLdltJN79z5fWAtoqOx8JSAfpppyPe6qKrxA&upload_protocol=resumable, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"BackgroundUploadTask <4AC8F3F2-1CC6-4064-BBF7-6D0375769C9A>.<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundUploadTask <4AC8F3F2-1CC6-4064-BBF7-6D0375769C9A>.<1>, NSLocalizedDescription=unknown error}

Why calls swiftHTTP the response handler if there is no connection?

I'm using swiftHTTP for requesting to my server and when my internet connection is slow, it goes to response part! I've set the example code below:
HTTP.GET("myURL") { response in
let myResponse = response.data // it comes here after the timeout
if response.statusCode == 200 {
//some code
} else {
do {
let jsonError = try JSON(data: myResponse) // in this line it goes to catch because there is no data in myresponse
} catch{
//alert for not having connection
}
}
Why does it call the response function if there's no response?
My server also says, that no request was sent.
It doesn't "go to response", it tries to make the HTTP request as expected and regardless of success or error it's completion handler is called.
The response object that is returned is an object that contains all of the information you need to determine what happened with the request.
So it will contain a timeout status code (HTTP 408), possibly an error message. If it did not respond at all, your app would not be able to handle these cases.
Say for example your user taps on their profile icon in the app and this sends a request to get the users profile, but it timed out. Do you want the user sat waiting, looking at a blank profile screen? It's much better to catch the error and handle it gracefully. In this case you could present a message to the user telling them that something went wrong and close the empty profile screen
Your response handler will also be called from swiftHTTP, if there's no or a very bad connection.To solve this problem, either check if there is an internet connection or check if the data is nil:
HTTP.GET("myURL") { response in
let myResponse = response.data // it comes here after the timeout
if response.statusCode == 200 || response.data == nil {
//some code
} else {
do {
let jsonError = try JSON(data: myResponse) // in this line it goes to catch because there is no data in myresponse
} catch{
//alert for not having connection
}
}
The important part here is the check if response.data == nil.

Checking if song is present in user's Spotify library

Using the below code to check if the user's library contains a particular song. It returns an error. What could I be doing wrong? I couldn't find examples for this particular 'forCheckingIfSavedTracksContains' method anywhere.
let accessToken = SPTAuth.defaultInstance().sessionUserDefaultsKey
let request: URLRequest = try!
SPTYourMusic.createRequest(forCheckingIfSavedTracksContains: ["spotify:track:3ZakaL0QEt5eeD3N7HbaN1"], forUserWithAccessToken: accessToken)
SPTRequest.sharedHandler().perform(request) { (error, response, data) in
if error == nil {
print ("this is data\(String(describing: data))")
} else {
print ("error")
}
}
The error is:
Error Domain=NSURLErrorDomain Code=-1012 "(null)" UserInfo={NSErrorFailingURLStringKey=api.spotify.com/v1/me/tracks/contains?ids=, NSUnderlyingError=0x109e7eb60 {Error Domain=kCFErrorDomainCFNetwork Code=-1012 "(null)" UserInfo={_kCFURLErrorAuthFailedResponseKey=<CFURLResponse 0x109e7e970 [0x1b441e538]>{url = api.spotify.com/v1/me/tracks/contains?ids=}}}, NSErrorFailingURLKey=api.spotify.com/v1/me/tracks/contains?ids=}

iOS App crashes when the service is closed

I've been writing an app with Swift 4 and it communicates with a service via RESTful API.
I have found some helpful code examples and everything works well as the service is running.
However, I could not handle the situation that the service is closed. I have tried try/catch blocks but they did not work well. Please check the code below firstly. It's the part of the communication. Basically it sends an email address to the service and gets a response as an activation code.
URLSession.shared.dataTask(with: request) { (data:Data?, response:URLResponse?, error:Error?) in
guard error == nil else {
// Some code
return
}
guard let responseData = data else {
// Some code
return
}
do {
guard let activation_response = try JSONSerialization.jsonObject(with: responseData, options: [])
as? [String: Any] else {
// Some code
return
}
guard let activation_code = activation_response["activation_code"] as? String else {
// Some code
return
}
// Some code, here, if it works fine.
} catch {
// Some code
return
}
}.resume()
When the service is closed, simply it will throw an error such as TCP connection failed. How can I handle it?
The error I get is something like below:
TheApp[4184:399699] TIC TCP Conn Failed [1:0x604000166600]: 1:61 Err(61)
2018-01-02 20:35:04.930874+0300 TheApp[4184:399699] Task <5ED49B16-BFDC-45A5-85F5-095C4FC4D84D>.<1> HTTP load failed (error code: -1004 [1:61])
2018-01-02 20:35:04.934352+0300 TheApp[4184:399698] Task <5ED49B16-BFDC-45A5-85F5-095C4FC4D84D>.<1> finished with error - code: -1004
It throws an exception and I can not catch it. I could not find how to do it. Thank you very much in advance for your help.

Alamofire doesn't catch error

I'm using Alamofire to get data from my server. However, it doesn't catch the error, as the error returned is nil. I've tested with AFNetworking, and it works fine. For both operation, the status code returned is 401 Unauthorized . Is there's something with my code?
I'm using GrapeAPI for my backend. All it does is just to return the error on fail request
GrapeAPI
error!('Unauthorized', 401)
AFNetworking
manager.GET("someUrl", parameters: nil, success: { (_, object) in
}, failure: { (operation, error) in
// These are the outputs. I'm not assigning any values
// error.localizedDescription = "Request failed: unauthorized (401)"
// statusCode = 401
})
Alamofire
Alamofire.request(.GET, "url", parameters: nil)
.response { (a,b,data,error) in
// These are the outputs. I'm not assigning any values
// error = nil
// data = {"error":"Unauthorized"}
// statusCode = 401
}
I can check the failure using the statusCode. But I prefer to check the error object instead. However, since the error is nil in Alamofire, it's quite confusing to check whether the request has failed or not.
As Matt has mentioned in the comment, I need to add .validate() before calling .response(). This is by design. Final code as below:
Alamofire.request(.GET, "url", parameters: nil)
.validate()
.response { (a,b,data,error) in
// error won't be nil now
// and statusCode will be 401
}
Read this detailed explanation(thanks!) for more information.
Alamofire does not see 401 Unauthorized as an error as it is an valid return. In your comment code you are assigning a value to error not checking it for error, it should be:
Alamofire.request(.GET, "url", parameters: nil)
.response { (a,b,data,error) in
if error != nil{
println(error.localizedDescription)
} else {
if let data = data{
//You should probably use a switch statement here
if data.statusCode == 401 {
println("Unauthorized")
} else if data.statusCode == 200 {
println("Success")
}
}
}
I am not sure if i understand correctly your problem, but I hope that help!

Resources