IOS/SWIFT4 - HTTP load failed (error code: -1005 [4:-4]) - ios

Does anybody know what HTTP load failed (error code: -1005 [4:-4]) is? I saw a few answers on here, some say it's that the server can't process more than x requests at a time, others say its alamofire.
My script refreshes every 60 seconds and there is only one request at a time. I have alamofire installed in my project, but not using it for this refresh.
It works the first few times, but after a few minutes i get this 1005 error and then it never again afterwards unless i go to a different page and come back.
URLCache.shared.removeAllCachedResponses()
if let requestURL = URL(string: "https://www.example.com/file.php") {
var urlRequest = URLRequest(url: requestURL)
urlRequest.httpMethod = "POST"
let postString = "username=\(Username.text!)&password=\(Password.text!)&device_token=\(device_token)"
urlRequest.httpBody = postString.data(using: .utf8)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest as URLRequest) { (data, response, error) in
if let data = data {
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] {
// get lots of vars here
// Async Stuff
DispatchQueue.main.async(execute: {
// do lots of things here
})
}
} catch {
print("Error: \(error)")
}
}
}
task.resume()
}
The error goes like this:
TIC Read Status [2:0x60400016bac0]: 1:57
... HTTP load failed (error code: -1005 [4:-4])
... finished with error - code: -1005
• I tried to add session.reset(completionHandler: { print("session ended") }) at the end
• In another post i read that i should add a header-length. but not sure if i should do that on the server or the Xcode project?
• And somehow i can't catch this error and trigger something else.

Related

API call is giving outdated response in swift

I am making a HTTP get request in swift where I am getting an outdated response for some reason..I have compared the response in Postman with the one I printed in the Xcode and I'm getting this..
Response Headers in Postman:
Response Headers printed in Xcode Console:
see the sections highlighted in green, both the calls are made at the same time. This is a live API of my project and as there is no change in the current live data I am not showing JSON response. But as you can see in the response headers, the value for field "Date" in both Postman and Xcode is different.. When I do it in Postman, it is giving me new response every time. But in Xcode I'm getting the same response all day. I don't know why This is happening. And after erasing the contents of simulator (or deleting the app from simulator) and reinstalling the project again it gave me a new updated response. But it's again repeated...
Code in RequestManager Class:
import Foundation
class RequestManager {
class func callTheGetAPI(urlString: String, closure: #escaping (Data?)->Void) {
let url = URL.init(string: urlString)
var urlRequest = URLRequest(url: url!)
urlRequest.httpMethod = "GET"
urlRequest.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
if (error != nil) {
print(error!.localizedDescription)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse!.allHeaderFields)
closure(data)
}
}
dataTask.resume()
}
}
code in my ViewController:
override func viewDidLoad() {
super.viewDidLoad()
getRecommendedData()
}
func getRecommendedData() {
let url = APIManager.API_01
RequestManager.callTheGetAPI(urlString: url, closure: { response in
do {
if (try JSONSerialization.jsonObject(with: response!, options: .mutableContainers) as? [[String : Any]]) != nil{
// print(json)
}
} catch let error {
print(error.localizedDescription)
}
})
}
This is all I have guys.. If anyone knows what's happening or if I'm doing something wrong.. Please help..
Replace below line
var urlRequest = URLRequest(url: url!)
With
var urlRequest = URLRequest(url: url!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 60)
From the documentation reloadIgnoringCacheData: Specifies that the
data for the URL load should be loaded from the origin source. No
existing local cache data, regardless of its freshness or validity,
should be used to satisfy a URL load request.
By default it uses caches.

HTTP load failed (error code: -1005 [4:-4]) - BUT NOT Alamofire

TIC Read Status [2:0x6040001660c0]: 1:57
<10> HTTP load failed (error code: -1005 [4:-4])
<10> finished with error - code: -1005
I can't figure out this error. There are several threads about this, but they are all about uploading with alamofire. I have alamofire in my app, but not in this view controller and I don't use alamofire for this connection.
The error appears in about 1 out of 20 connection.
Here is my code
URLCache.shared.removeAllCachedResponses() if let requestURL = URL(string: "https://example.com/test.php") {
var urlRequest = URLRequest(url: requestURL)
urlRequest.httpMethod = "POST"
let postString = "task_id=1"
urlRequest.httpBody = postString.data(using: .utf8)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest as URLRequest) { (data, response, error) in
if let data = data {
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any] {
// Async Stuff
DispatchQueue.main.async(execute: {
})
}
} catch {
print("Error: \(error)")
self.errorAction()
}
}
}

Getting JSON Response from API Swift

At an earlier point today, I was able to use this API and get a response in my iPhone app. The fact that I have been trying to debug this for so long is making be believe that I'm crazy! Attached is a screenshot of my console...
Here is my code pertaining to my API call. Using Apple's URLSession and following many stack overflow questions / Tutorials I can not get this thing to work.
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print("request failed \(error)")
return
}
do {
if let json = try JSONSerialization.jsonObject(with: data) as? [String: String], let result = json["result"] {
// Parse JSON
}
} catch let parseError {
print("parsing error: \(parseError)")
let responseString = String(data: data, encoding: .utf8)
print("raw response: \(responseString)")
}
}
task.resume()
Every time I get this interesting [BoringSSL] Error and the searching I've done regarding that has not produced effective in fixing whatever bug I have.
Like I said, earlier today I had this app working using the same API. I have tried the key that the website gave me and the test key they use on their site. Now that I think of it, I am going to use the exact URL from my code and the screenshot and take a screenshot from the response I get in my browser. See below:
Received above response with the exact URL being used in my app.
tried your API in my project. It worked. You can check the difference below:
let urlTest = URL(string: "https://www.zipcodeapi.com/rest/wvyR5aWjHNUF80Z6kmr1bTuNojfzhmvtcmfBD8QNo9qbNAHy9FvBISINKF3W5i9J/multi-distance.json/99501/99501,%2085001,%2072201/km")
var request = URLRequest(url: urlTest!)
request.httpMethod = "GET"
let session = URLSession(configuration: .default)
let task : URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode == 200{
do {
let json = try JSON(data:data!)
}
catch {
print("Could not convert JSON data into a dictionary.")
}
}
}
task.resume()
Printing description of json:
▿ {
"distances" : {
"85001" : 4093.922,
"72201" : 4962.6189999999997
}
}
May be you have to turn off Transport Layer Security, because that worked for me.
Go to your info.plist file and add a property named App Transport Secrity Settings and set its Allow Arbitrary loads option to NO
Hope this helps.

Swift 3: URLSession / URLRequest Not Working

I am still trying to convert our application from Swift 2 over to Swift 3 because I am being forced to since all of our Apple devices are now running iOS 10.
I have gone through the code conversion and thought I was doing well however, while attempting to debug my JSON issues (posted in another question), I am now dealing with requests not even being sent.
let params: [String:AnyObject] = [
"email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
"action":"601" as AnyObject,
"params":params as AnyObject
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
var request = URLRequest(url: URL(string: "http://domain.tld/path/")!)
request.httpBody = requestObject
request.httpMethod = "POST"
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
NSLog("Got here?")
session.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else {
print("error=\(error)")
return
}
NSLog("Got here 3?")
let object:JSON = JSON(data:data)
NSLog("Object: \(object)")
}.resume()
NSLog("Got here 4?")
} catch {
NSLog("Got here catch?")
}
NSLog("End of getUser")
The code above yields the following output:
2016-10-04 13:00:12.011969 OneTouch[1589:623015] [DYMTLInitPlatform] platform initialization successful
2016-10-04 13:00:12.264319 OneTouch[1589:622954] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2016-10-04 13:00:12.265321 OneTouch[1589:622954] [MC] Reading from public effective user settings.
2016-10-04 13:00:12.295055 OneTouch[1589:622954] Got here?
2016-10-04 13:00:12.295445 OneTouch[1589:622954] Got here 4?
2016-10-04 13:00:12.295515 OneTouch[1589:622954] End of getUser
(lldb)
Which means that the request isn't even being made. Is there some key that I have to add to the PLIST again? This is starting to get annoying.
Below is my old code and it isn't even working anymore:
let params: [String:AnyObject] = [
"email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
"action":"601" as AnyObject,
"params":params as AnyObject
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
let request = NSMutableURLRequest(url: URL(string: "http://domain.tld/path/" as String)!, cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20)
request.httpBody = requestObject
request.httpMethod = "POST"
NSLog("Got here?")
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error in
if error != nil {
NSLog("Got here 2?")
}
NSLog("Got here 3?")
let object:JSON = JSON(data:data!)
NSLog("Object: \(object)")
})
NSLog("Got here 4?")
task.resume()
} catch {
NSLog("Got here catch?")
}
NSLog("End of getUser")
The code above yields the same output as the other code does!
If you put a breakpoint immediately after calling getUser, the URLSession task's completion handler, which runs asynchronously (i.e. generally finishes later, unless the request failed immediately or was satisfied by some cached response) may not have had a chance to be called.
If you put a breakpoint inside the dataTask completion handler, you should see your data at that point.
Personally, I'd make sure to give getUser a completion handler so you know when it's done:
func getUser(completionHandler: #escaping (JSON?, Error?) -> Void) {
let params = [
"email":"\(preferences.string(forKey: "preference_email")!)"
]
let requestParams: [String: Any] = [
"action": "601",
"params": params
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams)
var request = URLRequest(url: URL(string: "http://domain.tld/path/")!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 20)
request.httpBody = requestObject
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else {
completionHandler(nil, error)
return
}
completionHandler(JSON(data: data), nil)
}
task.resume()
} catch {
completionHandler(nil, error)
}
}
Then when you call it, you can do something like:
getUser { json, error in
guard let json = json else {
print(error)
return
}
// do something with json
print(json)
}
And just put your breakpoint in getUser's completion handler. And remember that you have no assurances that the completion handler will run on the main queue or not, so you'll want to make sure to dispatch and UI or model updates back to the main queue.

Controlling tasks within Swift 2.0

Working in Swift 2.0, on IOS 9.2.1 using Xcode 7.2
Learning Swift 2.0 and I have written a routine that creates a NSURL Session, gets back some JSON data and then parses it. It works great...
BUT I some help in understanding how make this work as in get the outer function, share_list_folders to wait until the task here truly completes so I can return the result?
var parsedJson:[String:AnyObject] = [:]
func shared_list_folders() {
// **** list_folders (shared) ****
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/sharing/list_folders")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("Bearer ab-XXX", forHTTPHeaderField: "Authorization")
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
//print("Response: \(response)")
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
self.jsonParser(jsonResult)
for (key, value) in self.parsedJson {
print("key2 \(key) value2 \(value)")
}
} catch {
print("Bang")
}
})
task.resume()
let string2return = parsedJson["path_lower"] as? String
return(string2return)!
}
Its not really a completion, cause task will go off and do its own thing and share_list_folders will complete? Obviously I don't get the path_lower value here, until its too late... looked at delegates? And I tried, but then I run into issued with the completion block...
As you noticed NSURLSession after resuming it's task go away and do it's job which requires time. It's part of asynchronous programming when you have to deal with situation when something is calculated/prepared in another thread. Under the hood NSURLSession has own thread and there is waiting for server response. Then invokes completionHandler on main thread. That's a simplified theory. Going back to your question:
It's obviously that you have to wait for server response. As in another languages code is executed line by line, so you can't return anything as you wrote. The answer is: use closures.
Function you declare could use delegate as well but let's focus on closures:
func shared_list_folders(completion: (string: String?, error: ErrorType?) -> Void) {
// **** list_folders (shared) ****
let request = NSMutableURLRequest(URL: NSURL(string: "https://api.dropboxapi.com/2/sharing/list_folders")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.addValue("Bearer ab-XXX", forHTTPHeaderField: "Authorization")
let task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
//print("Response: \(response)")
if let error = error {
completion(string: nil, error: error)
return
}
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Body: \(strData)\n\n")
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options:NSJSONReadingOptions.MutableContainers);
let parsedJson = self.jsonParser(jsonResult) // I assume this returns parsedJson?
let string2return = parsedJson["path_lower"] as? String
completion(string: string2return, error: nil)
} catch { // here we have an error
completion(string: nil, error: error)
}
})
task.resume()
}

Resources