NSMutableURLRequest cannot connect to local network - objective-c

I am using AFNetworking to connect from an iOS v6.0 app to my local Cold Fusion 8 server, not on the same machine but on the same network and the connection times out. When I use an external public server it works fine.
I have tried the connection via IP address and it doesn't work.
I have tried an entry in the hosts file assigning a domain name to the IP address and this doesn't work either. Please see the error below.
I can however connect via a web browser just fine.
Also, the server side files are exactly the same. Versions of Cold Fusion are the same. The only difference that I can find are the public server is Win2003 with IIS6 and the local server is Windows7 with IIS7.
Any thoughts on why this would not work on a local network. Makes local development kind of difficult.
Here is the relevant code:
// load params
NSMutableDictionary *myParams = [[NSMutableDictionary alloc] init];
[myParams setValue:#"Hello" forKey:#"Parameter1"];
[myParams setValue:#"There" forKey:#"Parameter2"];
// Load the base URL into a URL object
// Changing this to an external public server works fine
NSURL *baseURL = [NSURL URLWithString:#"http://www.mylocalmachine.com/"];
// Create HTTP client and init with base url
AFHTTPClient *myHttpClient = [[AFHTTPClient alloc] initWithBaseURL:baseURL];
// POST request to path with the parameters
NSMutableURLRequest *myRequest = [myHttpClient requestWithMethod:#"POST" path:#"myfile.cfm" parameters:myParams];
// Block response from the HTTP client request and pass it back to the calling object
AFJSONRequestOperation *myOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:myRequest
success:^(NSURLRequest *mySuccessRequest, NSHTTPURLResponse *mySuccessResponse, id mySuccessJSON)
{
// PROCESS THE SUCCESS RESPONSE;
}
failure:^(NSURLRequest *myFailureRequest, NSHTTPURLResponse *myFailureResponse, NSError *myFaliureError, id myFailureJSON)
{
// PROCESS THE FAILURE RESPONSE... AFTER 60 seconds the system will fallout to this block.
}];
// Create a queue object
NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
// Add the operation object to the queue
[myQueue addOperation:myOperation];
The following is the error I get print the myFailureError object
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x8481000 {NSErrorFailingURLStringKey=http://www.mylocalmachine.int/myfile.cfm, NSErrorFailingURLKey=http://www.mylocalmachine.int/myfile.cfm, NSLocalizedDescription=The request timed out., NSUnderlyingError=0x9189e20 "The request timed out."}
Update----
I believe I have narrowed the issue down to what I beleive to be an issue with the iPhone simulator accessing IIS 7. It will access previous versions of IIS on the same network using the same code no problem.
The problem may be in the iPhone Simulator's User-Agent. I have tried to find a way to change the iPhone Simulator's User-Agent or allow the User-Agent in IIS 7 but can not seem to figure it out. The User-Agent the iPhone Simulator 6 is presenting is (iPhone Simulator; ios 6.0; Scale/2.00).
Does anyone know how to either allow this User-Agent on IIS 7 or change the User-Agent in the iPhone simulator?
Has anyone else seen this issue?
Thanks in advance,
Ed
Update----
Hi Everyone
Ok so I figured out how to change the User-Agent and Content-Type using the NSMutableURLRequest. I changed these to match what the browser would send, FireFox browser, and tried again to no avail. I still believe there is an issue with the configuration of IIS 7.5 but I can not find it...
Thanks for anyones help!!!
Ed

please try to remove last 2 lines of code and write
remove this
NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperation:myOperation];
add this instead
[myoperation start];
and also write failure:nil before that ending square bracket(]) like
AFJSONRequestOperation *myOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:myRequest
success:^(NSURLRequest *mySuccessRequest, NSHTTPURLResponse *mySuccessResponse, id mySuccessJSON)
{
// PROCESS THE SUCCESS RESPONSE;
}
failure:^(NSURLRequest *myFailureRequest, NSHTTPURLResponse *myFailureResponse, NSError *myFaliureError, id myFailureJSON)
{
// PROCESS THE FAILURE RESPONSE... AFTER 60 seconds the system will fallout to this block.
}failure:nil];
let me know is it working or not...!!!!
Happy Coding!!!!!!

I have resolved this issue. I will post what the resolution was to hopefully help someone else with a similar issue.
Turns out the problem was AVG installed on the system that was running IIS 7. It was a difficult issue to determine because any other system could access the web server with out any problems. It was only specific with the iPhone simulator accessing the system running IIS7. Even Safari or FireFox running on the same Mac would work just fine. Now what within AVG was causing the problem... That is yet to be determined.
I truly hope this helps someone along the way!

Related

ITLibrary: The operation couldn’t be completed. (OSStatus error 7011.)

Usually, initializing ITLibrary works like a charm.
But when calling
NSError *error = nil;
ITLibrary *library = [ITLibrary libraryWithAPIVersion:"#1.0" error:&error];
on a customer's machine, I get a The operation couldn’t be completed. (OSStatus error 7011.) error message.
Does anybody know what that means and how to fix it?
This is on macOS 10.15.7, after using Migration Assistant, i.e. moving from an older machine.
The issue was eventually resolved.
Since it is very unlikely that one comes up with the solution, I'm going to post it here:
There was a different issue where an iPhone wasn’t connecting to Finder. A level 2 tech Apple support person suggested to open the TV app and the Music app. Opening both apps somehow fixed both problems.

Block set by setDataTaskWillCacheResponseBlock on AFHTTPSessionManager is never called

I develop an application that relies heavily on AFNetworking to load data from a private API into Mantle models. My API client is a singleton subclass of AFHTTPSessionManager.
I'm trying to implement a basic offline mode by leveraging NSURLCache. The approach is to modify the request's cache policy on dataTaskWithRequest:request:completionHandler to NSURLRequestReturnCacheDataDontLoad if the AFNetworkReachabilityManager says the network is not reachable.
While I can verify that this actually works by using breakpoints during tests, the requests themselves are not being cached. I verified this by downloading the application container from Xcode, and checking the Cache.db sqlite file, which was empty. I also verified that I was looking at the correct cache by manually creating a dummy NSCachedURLResponse and forcefully storing it in the cache using storeCachedResponse:forRequest. Then the dummy response did show up in the Cache.db sqlite file.
So, I think I narrowed down the problem to my "usual" responses not being cached. I can also modify the headers sent by the server API. What I intend to do here is set a header Cache-Control: private on the API responses (so as not to make the other clients that use this API cache responses they shouldn't), and modify this cache header in the block of setDataTaskWillCacheResponseBlock, but this block never fires.
I understand that the URL system may decide when to call URLSession:dataTask:willCacheResponse:completionHandler, which calls the block, based on some undocumented rules, mainly the presence of a Cache-Control header, and the response size/cache size ratio. But my response is a 145-byte JSON, and the Cache-Control header is set (I verified both via curl -v and inspecting the task parameter of the success block of my request.
I also tried a more aggressive cache header, Cache-Control: public, max-age=2592000, to see if this caches the response or at least calls the block, but the behaviour was exactly the same. I also checked the myAFHTTPSessionManagerSubclass.session.delegate property, which was indeed pointing to myAFHTTPSessionManagerSubclass, as expected.
I also tried overriding URLSession:dataTask:willCacheResponse:completionHandler directly in my subclass, but it still was not called. Setting a breakpoint on this same delegate method on AFURLSessionManager.m in the Pods directory also does not work, the execution never stops on the breakpoint.
I'm using version 2.5.4 of AFNetworking, according to my Podfile.lock file.
So, how to make my responses cache (preferably without setting agressive caching policies on the response), so I can implement a quick offline mode in my app?
EDIT: I also tried to create a NSURLSession to see if this would work. So, I created a simple Node.js server that just answers something simple and sets a cache header:
$ curl -v http://192.168.1.107:1337/
* Hostname was NOT found in DNS cache
* Trying 192.168.1.107...
* Connected to 192.168.1.107 (192.168.1.107) port 1337 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.37.1
> Host: 192.168.1.107:1337
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Cache-Control: public
< Date: Thu, 11 Jun 2015 14:38:14 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
Hello World
And then created a simple view controller to test:
- (void)viewDidLoad {
[super viewDidLoad];
// Prime the cache
[NSURLCache setSharedURLCache:[[NSURLCache alloc] initWithMemoryCapacity:2*1024 diskCapacity:10*1024*1024 diskPath:#"mytestcache"]];
// The sleep is to be absolutely sure the cache did initialise
sleep(2);
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
[[session dataTaskWithURL:[NSURL URLWithString:#"http://192.168.1.107:1337"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(#"Got response: %#", [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
}] resume];
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse *))completionHandler {
completionHandler(proposedResponse);
}
The response is correctly printed, but willCacheResponse is never called (I set a breakpoint). I tried checking the container again, and the mytestcache directory was created, but it was empty. I also tried Cache-Control: max-age=86400, to the same result.
( cross-posted to AFNetworking issues at: https://github.com/AFNetworking/AFNetworking/issues/2780 )
Well, I will surprise you - the code you wrote above is working just fine, ...but it's incorrect for what you're trying to achieve ;)
Reason is simply - delegate methods are not being called when you create requests by method dataTaskWithRequest:completionHandler:. You need to use method dataTaskWithRequest: instead.
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html#//apple_ref/doc/uid/TP40013509-SW1 - read first Note
Second thing is that NSURLSession just really sux when we talk about caching. You may face several issues in iOS 7.x/8.x. I faced such nightmare when I was implementing custom cache in my app, which eventually has nothing in common with NSURLCache. Also I decided to create my kind of framework based on NSURLSession and AFNetworking.
One of the issues on iOS 7 is creating NSURLSession with defaultConfiguration, the NSURLCache object will be different than global one - quite unexpected behaviour.
One of the issues on iOS 8 is that the POST requests are also being cached, which may compromise security of your app. BTW https://www.google.pl/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=nsurlcache+ios+8+broken
Maybe it does not answer your questions, but you should be aware of that strange behaviours and differences between iOS versions.
Honestly I recommend you to use AFHTTPRequestOperationManager instead of AFHTTPSessionManager, because at least NSURLConnection works like a harm with NSURLCache :)

-1001 error when NSURLSession via httpproxy and /etc/hosts

I am trying to setup a http proxy server in my computer to simulate a virtual development environment.
To access the local url, I put the DNS info into computers' /etc/hosts.
Here is my test code:
NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:#"http://someurl.local/bluh/bluh/path"];
NSURLSessionDataTask *dataTask =
[session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response,
NSError *error) {
NSLog(#"data is %# error is %#", data, error);
}];
[dataTask resume];
My Experiments:
1. Browsers like safari or chrome can access both local web services and remote web services.
2. NSURLSession will response a NSURLErrorDomain Code=-1001 "The request timed out." when access local urls.
3. NSURLSession works correct if url not in /etc/hosts.
I also tried the NSURLConnection, same output as NSURLSession's.
so, is it means the NSURLConnection/NSURLSession and browsers use a different strategy to do the DNS?
how to deal or bypass this?
update
I build this environment for ios 7.0+.
Environment:
computer system: OS X 10.9.4 (13E28) which set up a proxy and have server in.
device system: iOS 7.1.2(11D257)
.local is treated as a special TLD on OS X, and I think iOS. I believe this is primarily because it's used as an indicator for Bonjour lookups. Try changing to a different TLD for your development domains. I use ".localhost"; I've seen others use ".dev". Both of those work as expected.
It looks from the linked article that you might have been running into the problem specifically because you were using x.local—a single label, which will be looked up via Bonjour instead of by DNS, so you might also find that x.y.local works, too, but personally I'd just avoid .local all together.

AFNetworking downloading a file despite getting 304 Server response

So I want to download a file from a webserver even though the server response is 304 Not Modified.
I use the AFURLSessionManager's downloadTaskWithRequest: progress: destination: completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) method which works fine for files which aren't modified. However if the server response is 304, it seems there is no valid filePath in completionHandler block and the error says "Request failed: not modified (304)".
I tried configurating AFURLSessionManager's requestCachePolicy to NSURLRequestReloadIgnoringLocalAndRemoteCacheData but that doesn't help: although filePath is set, the data can't be reconstructed from this filepath.
Can someone help me by maybe specifying what exactly would be the best practice for downloading a file with AFNetworking and Server response 304. Thanks in advance!
Nevermind I found the problem. I don't have to set the requestCachePolicy of the NSURLSessionConfiguration. I always added IF_MODIFIED_SINCE_HEADER to the request parameter of downloadTaskWithRequest:. Omitting this, it works.

Check internet connection in iPhone - not just to router

I use the normal Reachability tools to check if there is an internet connection available. It works in most cases, but if I unplug the WAN cable to the wifi-router, for some reason it still say it can find the host by wifi. If I change the web address to something that doesn't exists, it will say "The internet is down", like it should. Where is my problem?
Example:
I. I have the "internet cable" unplugged, but phone connected by wifi to router. I run with this line, the first time for this domain:
hostReachable = [[Reachability reachabilityWithHostName: #"www.google.com"] retain];
Result = No host found (correct)
II. I disable wifi in the phone. Result = Host found with WWAN (correct)
III. I enable wifi in the phone. Result = Host found with WIFI. (not correct, since router is not online)
For internet checking I send an http request to one site(most probably google.com) if it does not return true, it means no internet. This case works even the connection is so slow. Here is the method.
- (BOOL) connectedToInternet
{
NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.google.com"]];
return ( URLString != NULL ) ? YES : NO;
}
You may want to check out this thread. The Reachability code is known to only test connectivity with your router. There should be a notification for connectivity now.