Why I can't access my nodejs local server from iOs simulator - ios

I am trying to make an http request from my xcode to my local server running on nodejs. The following in a part of my iOs code.
let url = URL(string: "http://localhost.com/signup")!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
task.resume()
I recieve the following the response
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."
Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified hostname could not be
found.
I receive the first error if I use localhost.com and I receive the second error if I change the request to www.localhost.com

in this case you have to use your IP to get access to your localhost
ex: let url = URL(string: "http://192.168.1.105/signup")!
so Instead of using (localhost.com/...) you have to set the IP of your computer where you have LOCAL SERVER.

Related

SwiftUI: URL Request over specific browser

I want to retrieve a json from an intranet from outside the intranet in an iPad app. I have a VPN connection configured for this, but it only runs through the VMWare web browser. Safari uses the normal connection.
Is it possible, similar to the browser schemas, to use awbs:// instead of https:// and trigger the VPN configuration from an app? I don't want to open the browser though, I just want to use it. ;)
func getData() async {
#State var value: [responsejson]?
guard let url = URL(string: "https:/...") else {
print("Invalid URL")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) {data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode(responsejson.self, from: data) {
DispatchQueue.main.async {
self.response = decodedResponse.text
}
return
}
}
print("Error: \(error?.localizedDescription ?? "Unknown error")")
}.resume()
}
I tried to replace here https with awbs, but unfortunately it did not work
Task <1039D056-FDC4-46EE-9635-373AF8723409>.<1> finished with error [-1002] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL, NSErrorFailingURLStringKey=awbs://(...)
http,https or awbs is not just a text, but a definition of the protocol. Protocol defines how the data will be transferred, and there is a specific list of protocol that iOS support. see https://en.wikipedia.org/wiki/Internet_protocol_suite (don't be confused with app-scheme, when you open a link and specific app response to it, these are two different things).
So when you try to create an instance of a URL object it actually parses a protocol and uses instructions to make a Request.

TIC TCP Conn Failed when running Swift project on my phone

I am new to Swift. I built a simple application which works fine on the simulator. I am running the same on my device (iPhone 6s with iOS 11.0.2) and it's failing to connect to server.
getting these errors:
2017-10-26 18:16:02.489134-0400 myproj[1451:206438] TIC TCP Conn Failed [1:0x1c0176800]: 1:61 Err(61)
2017-10-26 18:16:02.489771-0400 myproj[1451:206438] Task <0C30ADDC-4A0E-4815-A701-2EF0A7CF5F04>.<1> HTTP load failed (error code: -1004 [1:61])
2017-10-26 18:16:02.490293-0400 myproj[1451:206440] Task <0C30ADDC-4A0E-4815-A701-2EF0A7CF5F04>.<1> finished with error - code: -1004
Please help me understand this error.
EDIT:
Here is the code making that call to the server:
func postRequest(postData: NSDictionary, postHeaders: NSDictionary, endPoint: String,
onComplete: #escaping ((NSDictionary)->Void), callbackParams: NSDictionary = NSMutableDictionary()) {
let url:URL = baseUrl.appendingPathComponent(endPoint)
let session = URLSession.shared
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
var paramString = ""
for (key, value) in postData{
paramString = paramString + (key as! String) + "=" + (value as! String) + "&"
}
request.allHTTPHeaderFields = postHeaders as? [String : String]
request.httpBody = paramString.data(using: String.Encoding.utf8)
let task = session.dataTask(with: request as URLRequest, completionHandler: {
(data, response, error) in
guard let _:Data = data, let _:URLResponse = response , error == nil else {
return}
let json: Any?
do {
json = try JSONSerialization.jsonObject(with: data!, options: [])
}
catch {
return
}
var serverResponse = json as? NSDictionary
DispatchQueue.main.async{
for (key, value) in serverResponse!{
callbackParams.setValue(value, forKey: key as! String)
}
onComplete(callbackParams)
}
})
task.resume()
}
EDIT:
Thanks!
Error -1004 is URLError.cannotConnectToHost. It cannot connect to the server for some reason.
In comments, you say the URL is http://127.0.0.1. That is localhost, the current machine. If you use that URL on a physical phone, it's going to look for the web server on the phone. Lol. It works on the simulator, because the simulator is your computer, the localhost.
You need a URL that your iPhone can resolve to the machine running your web service. For example, find out what the IP for the computer running the web service on your local network, make sure your iPhone is on wifi on the same network, and then use that unique IP number for your computer on the LAN (likely something more like 192.168.0.x).
I was getting the same problem when i was sending/ receiving socket messages! I am using Socket.io and Firebase for push and the error was at the node.js backend. The error was that the mongoose version was deprecated. Whenever this error arises at the iOS End, ask the node.js backend team to look for Red color crash logs. They will surely find the problem causing this error on frontend. Hope this helps !!
In my case i'm not changes the Local host IP address.
Example : #"http://Localhost/Host name/index.pnp/apiname?";
initially i'm used above URL, so i'm got the same error...
Later i changed in to Localhost to 190.177.0.22
Example : #"http://190.177.0.22/Host name/index.pnp/apiname?";
Another corner case if you using something like ngrok and it's still not working is the phone isn't connected to a service provider network or wifi.
In my case my main phone was working the second out of service phone was not.

Error Code=-1005 "The network connection was lost." in Swift while consuming Web Service

I'm working on a iOS project in Swift 2.0, which has Web service calls, these services are slow to respond and that is normal, can be up to 1 minute or a little more, when i call the service 70% of the time it answers with the error "the network connection was lost." The tests were conducted in both simulator and different phone devices and iPad and the result is the same. The network connection is strong and the same application was also created on Android and working properly almost 100% of the time.
The way I call services from any view is as follows:
#IBAction func contratarAct(sender: AnyObject) {
conexion.delegate = self
loadingView = MEXLoadingView(delegate: self, title: "Espere por favor", percent: false, view: self.view)
self.loadingView.showAnimated(true)
let url = urlServicios.urlBaseServicios + "/" + idSolicitud + "/" + idNoCliente + "/CONTRATO"
conexion.consultaServicioGET(url, httpMethod: "PUT")
}
And the method that is executed is as follows:
func consultaServicioGET(url : String, httpMethod : String ){
let urlString = url
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
request.timeoutInterval = 540
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
var session = NSURLSession.sharedSession()
request.HTTPMethod = httpMethod
let urlconfig = NSURLSessionConfiguration.defaultSessionConfiguration()
urlconfig.timeoutIntervalForRequest = 540
urlconfig.timeoutIntervalForResource = 540
session = NSURLSession(configuration: urlconfig, delegate: self, delegateQueue: nil)
let task = session.dataTaskWithRequest(request , completionHandler: {
(data:NSData?, response:NSURLResponse?, error:NSError?) in
if error != nil {
let jsonError : NSDictionary = NSDictionary()
self.delegate?.respuestaServicioGET!(jsonError, mensaje: "\(error!.localizedDescription)")
return
}
let jsonString = NSString(data: data!,encoding: NSASCIIStringEncoding)
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let json: NSDictionary = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
if (json.isKindOfClass(NSDictionary) ){
self.delegate?.respuestaServicioGET!(json, mensaje: "OK")
}else{
let jsonError : NSDictionary = NSDictionary()
self.delegate?.respuestaServicioGET!(jsonError, mensaje: "ERROR")
}
})
task.resume()
}
the error displayed is:
error=Optional(Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x7fbde5f51df0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://particulares-gw-obparticularesmx-pre.appls.cto2.paas.gsnetcloud.com:443/OPB/57dadf7de4b0ac2e518de44a/57dadf7de4b06c6b04ef0dcf/CONTRATO, NSErrorFailingURLKey=https://particulares-gw-obparticularesmx-pre.appls.cto2.paas.gsnetcloud.com:443/OPB/57dadf7de4b0ac2e518de44a/57dadf7de4b06c6b04ef0dcf/CONTRATO, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.})
I add some code like the following:
urlconfig.timeoutIntervalForRequest = 540
urlconfig.timeoutIntervalForResource = 540
Trying to get more "timeout" but this is not looks like a timeout.
I can not get out of this error for days, any help will be greatly appreciated. I'm desperate.
If you're expecting a socket to stay open for minutes at a time, you're in for a world of hurt. That might work on Wi-Fi, but on cellular, there's a high probability of the connection glitching because of tower switching or some other random event outside your control. When that happens, the connection drops, and there's really nothing your app can do about it.
This really needs to be fixed by changing the way the client requests data so that the responses can be more asynchronous. Specifically:
Make your request.
On the server side, immediately provide the client with a unique identifier for that request and close the connection.
Next, on the client side, periodically ask the server for its status.
If the connection times out, ask again.
If the server says that the results are not ready, wait a few seconds and ask again.
On the server side, when processing is completed, store the results along with the identifier in a persistent fashion (e.g. in a file or database)
When the client requests the results for that identifier, return the results if they are ready, or return a "not ready" error of some sort.
Have a periodic cron job or similar on the server side to clean up old data that has not yet been collected.
With that model, it doesn't matter if the connection to the server closes, because a subsequent request will get the data successfully.
I faced the same issue and I am attaching a screenshot of the resolution to show how I resolved the issue.
In my case, the issue was that the API requests are blocked from the server Sucuri/Cloudproxy (Or you can say firewall service). Disabling the firewall resolved the issue
I don't why but it's works when I add sleep before my request:
sleep(10000)
AF.request(ViewController.URL_SYSTEM+"/rest,get_profile", method: .post, parameters: params, encoding: JSONEncoding.default , headers: headers).responseJSON { (response) in
}
I faced this issue and spend more than 1 week to fix this. AND i just solved this issue by changing Wifi connection.

Data task with URL timed out

I am trying to access a website. I am using a dataTaskWithURL request.
Here is my code:
let task = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data, response, error) in
print("2")
if let urlContent = data {
print("3")
let stringContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding)!
let arr = stringContent.componentsSeparatedByString("<b>The computer's solutions will appear below</b><br>")
let second = arr[1]
let newArr = second.componentsSeparatedByString("</tr></table></center><p align=\"center\">")
let results = newArr[0]
self.resultsLabel.text = results
self.stopActivity()
} else {
print(error)
self.stopActivity()
}
})
task.resume()
I have also tried running this code on the main block:
dispatch_async(dispatch_get_main_queue(), {() -> Void in
// Code
})
However, neither of these has been successful. I repeatedly get the following error
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x7ff0a3f4c6e0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=THE URL I AM TRYING TO ACCESS, NSErrorFailingURLKey=THE URL I AM TRYING TO ACCESS, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.})
I have tried looking at this post and this one as well. However, I have not been successful with them. The website loads fairly quickly. How do I get rid of this error?
It could be caused by a number of things; If the issue is happening in the Simulator, I suggest restarting it as per the suggestions in the SO posts below:
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost."
Error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out."
NSURLErrorDomain Code=-1001 error when a http post request is sent
Undocumented NSURLErrorDomain error codes (-1001, -1003 and -1004) using StoreKit
How to use NSURLSessionDataTask in Swift
It might be help to print response as well to see if the HTTP headers can provide a clue.
I realized that I was using https:// instead of http://.

POST Request gives timeout when testing on iPhone device

I'm working on a school project, which is developing a Web application with an API and an iPhone app with swift. I developed the website in Laravel with Homestead/Vagrant.
But when it comes to the iPhone app, i'm facing with a problem:
When a user presses the login button the app sends a http POST request to the API and the API checks if the users exists in the db, if so then it will return a token, after which the user will be redirected to the dashboard. This works fine on the xcode simulator.
My code of the request part looks like this:
var loginUrl = "http://10.1.1.33/api/login" + "?email=" + self.email + "&password=" + self.password
let request = NSMutableURLRequest(URL: NSURL(string: loginUrl)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
let task = session.dataTaskWithRequest(request, completionHandler: {
data, response, error -> Void in
guard error == nil else {
print("First Error!!! \(error)")
self.errorLabel.text = "Request timed Out"
self.enableLoginBtn(true, buttonText: "Login")
return
}
do {
let data: AnyObject? = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
// Okay, the `json` is here, let's get the value for 'success' out of it
let json = JSON(data!)
dispatch_async(dispatch_get_main_queue(), {
if json["token"] != nil {
print("Login successvol!)")
if self.saveSession(json["token"].string!) {
self.enableLoginBtn(true, buttonText: "Login")
self.goToDashboard()
}else {
print("Saving token went wrong")
}
}else {
self.showError("Gebruikersnaam of wachtwoord is onjuist")
self.enableLoginBtn(true, buttonText: "Login")
}
})
}catch let parseError{
print(parseError)
let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("Error could not parse JSON: \(jsonStr)")
self.enableLoginBtn(true, buttonText: "Login")
}
})
task.resume()
But when i try to test the exact same thing on my iPhone 5s (I have a developer license) it's failing every single time. The error i'm getting is:
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x1742e1e80 {NSUnderlyingError=0x170259230 "The operation
couldn’t be completed. (kCFErrorDomainCFNetwork error -1001.)",
NSErrorFailingURLStringKey=http://10.1.1.33/api/login?email=jejz#kdk.nl&password=sndxbdj,
NSErrorFailingURLKey=http://10.1.1.33/api/login?email=jejz#kdk.nl&password=sndxbdj,
NSLocalizedDescription=The request timed out.}
The last couple days i searched the whole internet for a solution, but i couldn't find any solution.
I'd be really grateful if someone can help me out with this.
Thanks in advance.
Best regards
EDITED ---------------------
Screenshot of the error
I think you might be confused about POST and GET requests.
POST parameters are sent in the Request body, while in the GET request the parameters are sent in the URL.
GET Method parameters example:
/test/demo_form.asp?name1=value1&name2=value2
POST Method parameters example:
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
So what you are trying to do, is send the parameters in the URL with the POST request, which is why it doesn't work!
You need to put the parameters in the Request body!
What you need to do is:
1. Change the request URL
var loginUrl = "http://10.1.1.33/api/login"
2. Add the parameters in the Request body
let postString = "email=" + self.email + "&password=" + self.password
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
If you are using iOS 9, this is due to the new Transport security setting that is enabled by default. It blocks all outgoing non https requests. There is a way to turn it off for all requests, so any http request will load. There is also a way to control each url or url wildcard that can load on http.
If you are using http for your login, I suggest you change your server to support SSL and TLS 2.0 (pretty much the standard on most hosts with https) rather than turning it off to load http. Usernames and passwords shouldnt go over http.
If however you need to turn it off for furthering the development until you get a certificate setup, here is how to do it.
Add this to your info.plist file (open it in source code mode, control click on the file and select)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
If you want to control specific urls, you can use <key>NSExceptionDomains</key>

Resources