Image request from URL fails - ios

I have the following code:
func getImage(urlString: String, completionHandler: UIImage -> Void) -> NSURLSessionTask {
let request = NSMutableURLRequest(URL: NSURL(fileURLWithPath: urlString)!)
println("Executing image request: \(urlString)")
return session.dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("\tGET request failed: \(error!)")
} else {
println("\tGET request succeeded!")
let response = response as NSHTTPURLResponse
if response.statusCode == 200 {
let image = UIImage(data: data)
dispatch_async(dispatch_get_main_queue()) { // dispatch naar main thread (main_queue is thread# van main thread van app)
completionHandler(image!)
}
}
}
}
}
But when I execute it, I get the following output:
Executing image request: http://i.imgur.com/rfw7jrU.gif
GET request failed: Error Domain=NSURLErrorDomain Code=-1100
"The operation couldn’t be completed. (NSURLErrorDomain error -1100.)"
UserInfo=0x14e9b200 {NSErrorFailingURLKey=file:///http:/i.imgur.com/rfw7jrU.gif,
NSErrorFailingURLStringKey=file:///http:/i.imgur.com/rfw7jrU.gif,
NSUnderlyingError=0x14d8d600 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error -1100.)"}
I have no idea why this happens, as my nearly identical code that gets a .json file does work. I have tested this on both my device and the simulator.
This fails on all urls, not only imgur links. It also crashes before I put it into a UIImage, so that is also not the problem.

From the error message one can see that your URL is a file URL:
file:///http:/i.imgur.com/rfw7jrU.gif
and error -1100 is kCFURLErrorFileDoesNotExist (see CFNetwork Error Codes Reference).
You should replace
NSURL(fileURLWithPath: urlString)
by
NSURL(string: urlString)
// Swift 3+:
URL(string: urlString)

Related

Swift problem with URLSession in Watchkit XCode

I got a problem with UrlSession and a .local domain.
When I send a Request to the IP address of the device in my home network it works. But when I use the .local domain for example "http://esp8266.local" it don't work and there are some errors.
On the IOS App it works fine.
This doesn't work on Watchkit but on IPhone App it works fine:
PDTask .<1> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataPDTask .<1>, NSLocalizedDescription=The request timed out., _kCFStreamErrorCodeKey=-2102, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataPDTask .<1>",
"LocalDataTask .<1>"
), NSErrorFailingURLStringKey=http://esp8266.local/, _kCFStreamErrorDomainKey=4, NSErrorFailingURLKey=http://esp8266.local/}
let url = URL(string: "http://esp8266.local")
var request = URLRequest(url: url!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print(response!)
if error != nil {
print("FAIL")
print(error!)
} else {
print("OKEY")
print(data!)
}
}
task.resume()
And this works fine:
let url = URL(string: "http://192.168.0.109")
var request = URLRequest(url: url!)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
print(response!)
if error != nil {
print("FAIL")
print(error!)
} else {
print("OKEY")
print(data!)
}
}
task.resume()

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

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.

iOS Basic Auth completion error first time

I have implemented this piece of code for basic auth and sometimes doesn't work on first time:
func doRequestWithBasicAuth(completion : (success : Bool, html: String?, error : NSError?) -> Void) {
if let user = self.user {
let loginString = NSString(format: "%#:%#", user.login!, user.pwd!)
let loginData: NSData = loginString.dataUsingEncoding(NSUTF8StringEncoding)!
let base64LoginString = loginData.base64EncodedStringWithOptions(nil)
let url = NSURL(string: user.service!.getURL())
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("Basic \(base64LoginString)", forHTTPHeaderField: "Authorization")
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
if error == nil {
let htmlString = NSString(data: data, encoding: NSUTF8StringEncoding)
completion(success: true, html: htmlString as? String, error: nil)
} else {
completion(success: false, html: nil, error: error)
}
}
} else {
completion(success: false, html: nil, error: NSError())
}
}
This method is attached to a button, so on first tap I get this error:
BASIC AUTH ERROR: Error Domain=NSURLErrorDomain Code=-1012 "The
operation couldn’t be completed. (NSURLErrorDomain error -1012.)"
UserInfo=0x7bad5770
{NSErrorFailingURLKey=https:///auth/Logon.do,
NSErrorFailingURLStringKey=https:///auth/Logon.do,
NSUnderlyingError=0x7b9c47f0 "The operation couldn’t be completed.
(kCFErrorDomainCFNetwork error -1012.)"}
On second tap, call works fine... I can't understand why.. I print user login, psw and url: are the same on twice calls..
Any idea?

NSURLConnection sendSynchronousRequest does not work

Any idea why sendSynchronousRequest not work, and returns nil. Error and response is nil as well.
let url = NSURL(fileURLWithPath: "http://google.com")!
let ur = NSMutableURLRequest(URL: url)
let response: AutoreleasingUnsafeMutablePointer<NSURLResponse?> = nil
let errorPtr = NSErrorPointer()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
let data = NSURLConnection.sendSynchronousRequest(ur, returningResponse: response, error: errorPtr)
if errorPtr != nil {
var error: NSError = errorPtr.memory!
}
})
UPDATE
I tried in the async way:
var oq = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(ur, queue: oq, completionHandler: {response, data, error in
let ii = 7
})
Here I get an error:
(lldb) po error
Error Domain=NSURLErrorDomain Code=-1100 "The requested URL was not found on this server." UserInfo=0x1567f9d0 {NSErrorFailingURLStringKey=file:///http:/google.com, NSErrorFailingURLKey=file:///http:/google.com, NSLocalizedDescription=The requested URL was not found on this server., NSUnderlyingError=0x15691880 "The requested URL was not found on this server."}
Strange google is not available?
You are using fileURLWithPath and that will return the URL
file:///private/var/folders/xs/6k9v2g217155wr9vgb3xrg_80000gn/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.MyPlayground-F81D60A5-6797-4BEB-8AB9-2D156E2B6771/http:/google.com
What you need is let url = NSURL(string: "http://google.com")!
and that will return the URL:
http://google.com

kCLErrorDomain iOS with request interrupted sock=client heroku

I have a backend hosted on heroku using django and I have an iOS app consuming that api. Sometimes the app throws this error
locman err: Error Domain=kCLErrorDomain Code=0 "The operation couldn’t be completed. (kCLErrorDomain error 0.)"
The backend for that same request throws this error
sock=client at=error code=H18 desc="Request Interrupted" status=503
How should I handle this in iOS? It seems like its a problem with the app. Am I just sending up too many requests at once?
heres what my api controller looks like
class func getPictures(location_id: String, completionHandler:( cardImageArray: [CardImage] )->() ){
var bodyString: String = "location_id=\(location_id)"
bodyString = bodyString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let url: NSURL = NSURL(string: BASE_URL + "/api/v1/get_pictures" + "?" + bodyString)!
let req: NSMutableURLRequest = NSMutableURLRequest(URL: url)
req.HTTPMethod = "GET"
//req.HTTPBody = bodyString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
NSURLConnection.sendAsynchronousRequest(
req,
queue: NSOperationQueue.mainQueue())
{ (res: NSURLResponse!, data: NSData! , err: NSError!) -> Void in
let jsonDict = JSON(data: data, options: NSJSONReadingOptions.AllowFragments, error: nil)
if (jsonDict["response"].int == 1){
var cardImageArray: [CardImage] = []
if let photo_urls = jsonDict["photo_urls"].array{
// NSString(data: data, encoding: nil)
for photo_url_raw in photo_urls{
if let url_string = photo_url_raw.string{
let ci = CardImage(urlstring: url_string)
cardImageArray.append(ci)
}
}
return completionHandler(cardImageArray: cardImageArray)
}
}else{
println("error in get pictures")
if let errorMessage = jsonDict["error"].string{
return
}
}
}
}
Figured out this was the error message being printed when location manager can't decide what the users location is. Just handled the error and had the user click a button to try again.

Resources