Is there any difference between NSURLRequest class on Mac OS and iOS?
Apparently there is one.
Here how the class description looks on Mac OS:
<NSURLRequest: 0x60000000f290> { URL: http://www.google.com/ }
And here how it looks on iOS:
<NSURLRequest http://www.google.com/>
As it appears there is a big difference for my project as it work perfectly on iOS and connection fails for Mac OS version.
Does anyone know how to make Mac OS app init the NSURLRequest class object exactly the way it does for iOS?
UPD 1
Same code for initialisation of the object for both platforms
NSURLRequest* aRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com/"]];
I tried same to use NSURLRequest in both AFNetworking and NSURLConnection getting same result - successful connection on iOS and 403 error for Mac OS
successful connection on iOS and 403 error for Mac OS
403 is HTTP's Forbidden response. The fact that you're getting a 403 means that a) your request is making a proper HTTP connection, but b) the server doesn't want to talk to you for some reason. A good strategy for diagnosing the issue is to use a proxy like Charles to look at the successful and unsuccessful requests and note the differences. The user agent parameter is one thing that's likely to differ between the two platforms, but you'll probably find other differences as well. Once you know what's different between the two requests, you'll have a better idea of what you need to change to make the failing requests work.
Related
I am developing an app for iOS with Swift 3, this application search with the Bonjour service some robots in the local network which use a specific service, for example robot.local and show them in a list. The Bonjour service gives me the domain of the device. This is a example of the domains searched.
Ex.:
robot1.local
robot2.local
The next step, is when the user click an element of the list. This action start a connection by web sockets with the device and connect it for control it with the Iphone. I am using a library called RBManager which use RocketSocket library for connect. This library helps me to connect to RosBridge.
I use this code for connect:
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"wss://192.168.0.100:9090"]];
self.socket = [[SRWebSocket alloc] initWithURLRequest:request];
self.socket.delegate = self;
[self.socket open];
The problem is when I am install the app by Xcode I have not any problem but when I am install the app by an ipa file or by TestFlight the connection is rejected and shows this error:
managerDidFailWithError Optional(ErrorDomain=NSOSTatusErrorDomain
Code=-9807 "(null)" UserInfo={_kCFStreamErrorDomainKey=3,
_kCFStreamErrorCodeKey=-9807})
I found this issue in the library but is not the solution that I need.
I am deactive ATS in the info.plist but I not know how to solve this error. Could anyone help me?
I found the problem. The problem was that my RosBridge backend run with TLS and I didn't implement it.
The solution is implement the authentication in the client and all works :D
My application has been rejected twice for Incompatibility over Ipv6 network.
This question has been asked several times. Most of the solutions suggested to avoid using third party api for http request and do not hard code ipaddress. I have not done neither.
However does my server have to be ipv6 compatible or is there something wrong with my http request.
So I tested my server https://services.fingrowthbank.com/ on this website http://ipv6-test.com/validate.php for Ipv6 readiness testing. It shows as incompatible. Could this be a reason for the rejection?
Code for http request
let nsUrlObject: NSURL = NSURL(string: urlAndMethod)!
let nsMutableUrlRequestObj: NSMutableURLRequest = NSMutableURLRequest(URL: nsUrlObject, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: nstime_out_intervalObj)
nsMutableUrlRequestObj.HTTPMethod = “POST"
let bodyData = httpBodyStr
nsMutableUrlRequestObj.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding)
nsMutableUrlRequestObj.setValue(httpHeaderStr, forHTTPHeaderField: "Authorization")
NSURLConnection.sendAsynchronousRequest(nsMutableUrlRequestObj, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
if response == nil
{
print(error)
alert.view.removeFromSuperview()
Imps_http_client.showAlertView("Could not connect to the server")
}else{
}
}
There is no problem with your code. The problem is your server side.
As per https://services.fingrowthbank.com/ your server is not compatibility with IPV6. Because I found that you are using old security encryption i.e, Obsolete Cipher suite .
I under lined inside the image.
I tested with sample server. Example: Apple. This apple is using modern cipher suite
The problem with your server there is a chance of security attack number 13. This is the reason the apple is rejected your app. Update your app with late security.
Solution: Just update your server to modern cipher suite.
This url is perfectly fine as far as your are using domain name for sending request to server.
according to apple If you’re writing a client-side app using high-level networking APIs such as NSURLSession and the CFNetwork frameworks and you connect by name, you should not need to change anything for your app to work with IPv6 addresses. If you aren’t connecting by name, you probably should be.
check your code or any third party components you are using and make sure your are not sending any request with IP address instead of domain name. Specifically, Check Reacahbility code. If you are using it, don't use function reachabilityWithAddress , use reachabilityWithHostName instead. reachabilityForInternetConnection is also using reachabilityWithAddress - If you are using this, then edit it.
At last, you can validate your app for ipv6 by creating ipv6 network with mac and testing app with that network.
I'm trying to find a way to prevent NSURLSession from caching responses (in Simulator) by using approach from these questions:
Prevent NSURLSession from caching responses
NSURLCache does not clear stored responses in iOS8
I don't want to use approach from this question:
Clear NSURLSession Cache
which is using ephemeralSessionConfiguration call to NSURLSessionConfiguration when setting up a new NSURLSession instance.
I just want to not cache requests, in worst case clear the cache when application resigns active.
With call [NSURLCache sharedURLCache] removeAllCachedResponses] in applicationWillResignActive execution in app delegate i still get Cache.db present and full of cached responses/requests in respective iOS Simulator cache on disk.
Before that, I changed all my NSURLSessionConfiguration cache policy to NSURLRequestReloadIgnoringCacheData NSURLRequestReloadIgnoringLocalCacheData
NSURLRequestReloadIgnoringLocalAndRemoteCacheData
(tested all three cases, the last one is probably not implemented) instances (and effectively ALL cache policies). Isn't changing cache policy supposed to result in not caching server responses and requests on simulator? Does it depends on storage policy in response headers?
I'm using iOS 9.3 and iOS 10.1 Simulators for iPhone and v. 10 of iOS SDK. Project is in Objective C, maybe full Swift project would behave differently?
Is this behavior different for simulators and with devices? Why is this happening, is there a solution different from using dependency (can't fall onto one right now for some reason).
I had a similar issue and I was able to fix this by setting the properties- URLCache and requestCachePolicy on NSURLSessionConfiguration to nil and NSURLRequestReloadIgnoringCacheData respectively.
Also, you can try setting the cachePolicy property on NSMutableURLRequest to NSURLRequestReloadIgnoringCacheData.
So the rude solution is ... drop the Cache.db file on app resigning. I assume on the simulator you should be able to?!
But, did you try the ephemeralSessionConfiguration? Because Apples header doc says:
* An ephemeral session has no persistent disk storage for cookies,
* cache or credentials.
I have been struggling with an issue where NSURLConnection calls instantly fail. The device needs to be rebooted entirely or Flight Mode needs to be toggled on/off to resolve the problem. Restarting the app (swipe up) alone does not help.
Some facts:
-All URLs are HTTPS, TLS 1.2 compatible with Forward Secrecy. There are no issues with ATS and iOS 9. The error has been present since iOS 7 and remains on 9.2.
-No third party frameworks are used by the app. I use only native NSURLConnection calls that always work, except for when this odd situation occurs.
-No infrastructure/network issues - other devices on same networks (same WiFi for instance) work in the same app at the same time. Going to/from 3G/Wifi makes no difference.
-I always implement willCacheResponse to return nil.
-The service is hosted on AWS Elastic Beanstalk, so some suggested that it might be a DNS caching issue in case of IP address changes - this seems unlikely to me and should trigger multiple errors at once on different devices, which I have never seen.
-The method called is didFailWithError, instantaneously, as if there were no Internet connection on the device at all - all other apps work, however.
-The website that hosts the API used by the app can be browsed with no problems at all times. The website actually makes the same requests to fetch data.
The error code returned is -1003, kCFURLErrorCannotFindHost. I've been following a thread on Git dealing with the same issue to no avail. https://github.com/AFNetworking/AFNetworking/issues/967
I tried using NSURLRequestReloadIgnoringCacheData for all my requests, but that did not help.
With this information, will anyone care to venture a guess what I might be doing wrong? I added the bounty because I have no idea how to approach this problem - especially because it's so inconsistent. And it is definitely not a legitimate error (that is, that the domain could not be found), as the service is operating fine while this happens on random clients.
I create my request with a static method that looks like this. It's been stripped of some non-public info, but basically it just performs a POST request with JSON data. [Controller getSQLHost] just returns a URL - the base domain.
+(NSURLConnection*)initiatePOSTwithJSONDictionary:(NSDictionary*)dictionary toURL:(NSString*)urllocation withDelegate:delegate {
NSMutableDictionary *connectionDictionary = [[NSMutableDictionary alloc] init];
if (dictionary) {
[connectionDictionary setObject:dictionary forKey:#"input"];
}
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:connectionDictionary options:kNilOptions error:nil];
NSURL *url = [NSURL URLWithString:[[Controller getSQLHost] stringByAppendingString:urllocation]];
NSString *postLength = [NSString stringWithFormat:#"%i", (int)[jsonData length]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:jsonData];
return [[NSURLConnection alloc] initWithRequest:request delegate:delegate];
}
Does you delegate implement connectionShouldUseCredentialStorage ? (or respond with YES)
I think the device's keychain is used when this method returns yes which may explain the persisting failure beyond the life time of the running application and why rebooting or otherwise resetting network connectivity "fixes" it. If an authentication failure has been recognized once, it may linger in the key chain for a little while which would then respond immediately without actually going to the server.
What would cause the authentication to register as a failure in the keychain in the first place may depend on a variety of factors. It could be as simple as a typo in the saved password or more convoluted such as some certificate expiration preventing the SSL layer from establishing a secure link.
You're creating NSURLConnections on the current runloop. How many are active at any one time? Have you considered using an NSOperationQueue so that you don't get bitten by load bugs?
Is your delegate thread-safe? If not, that could explain the sporadic-ness of the bug.
You say you don't see the problem often, but others do. Can you borrow their devices and maybe even them and their usage patterns and thus get to see the problem more often?
I am using the ASIHttpRequest library for IOS to attempt to download a zip file from my iPad application and it all works fine. However, I am trying to simulate a request timeout and handle this situation appropriately. I am using a trial version of CharlesProxy to attempt to simulate a timeout and Im also killing my tomcat server. In the situation where I am killing the tomcat server in the middle of the zip download, the ASIHttpRequest is still receiving a 200 response, with the error object begin set to nil even though the download is not complete and is not successful.
I have checked the downloadComplete property on the ASIHttpRequest request object and it is set to YES.
Has anyone else noticed this?