I am retrieving data via NSURLRequest and it is working perfectly. I have added password protection to that directory now and I am not sure how to configure my code to add in the password for the directory (myStuff)
Can anyone tell me how this is done based on my current code?
Thank you
-(void) retrieve
{
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://XXXXXXX.com/myStuff/test.php"]cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:8.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
receivedData = [[NSMutableData data] retain];
} else {
// Inform the user that the connection failed.
[self showServerAlert];
return;
}
}
//CALL THE OTHER DELEGATE METHODS
The standard URL syntax would be:
http://username:password#XXXXX.com/myStuff/test.php
When doing this though you should not use http. You really want to use https. And don't hardcode the password in your code. A hacker could easily figure it out.
Related
This is first time I am trying.
Till now I am successful in getting DATA from SERVER in JSON format.
Now what I want to do is,
I have two NSString values that I have to send to server and server will check for them.
I don't know what checking mechanism is behind.
I am just sending two strings and server will return me try or false.
And I have to show that true or false thing.
All this will be called onClick of UIButton
Here what I tried,
NSString *str = [NSString stringWithFormat:#"http://XXXXXXXXXXXXXXXXXXXXXXX/api/CaptchaImage/CheckCaptchValid?validstring={%#}&encodestring={%#}",string1,string2];
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
[req setURL:[NSURL URLWithString:str]];
NSURLConnection *connGet = [[NSURLConnection alloc]initWithRequest:req delegate:self];
if(connGet)
{
NSLog(#"Connected successfully");
}
else
{
NSLog(#"Not connected successfully");
}
It gives me NSLog as connected successfully,
But I am struck here,
I want a response from server too in NSString format, either True or False.
Can any one guide me for further steps.
I tried some SO links, but didn't get much.
Thanks in advance.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[myData appendData:data];
}
-(void)connectionDidFinishLoading: (NSURLConnection *)connection {
response = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
}
Try this, but I have not tested this code. add appropriate delegate method.
Hope this will work for you
I've looked around a lot and cant seem to find a proper answer for my problem. As of now I have a network engine and I delegate into that from each of the view controllers to perform my network activity.
For example, to get user details I have a method like this:
- (void) getUserDetailsWithUserId:(NSString*) userId
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#Details", kServerAddress]]];
request.HTTPMethod = #"POST";
NSString *stringData = [NSString stringWithFormat:#"%#%#", kUserId, userId];
NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = requestBodyData;
NSURLConnection *conn = [[NSURLConnection alloc] init];
[conn setTag:kGetUserInfoConnection];
(void)[conn initWithRequest:request delegate:self];
}
And when I get the data in connectionDidFinishLoading, I receive the data in a NSDictionary and based on the tag I've set for the connection, I transfer the data to the required NSDictionary.
This is working fine. But now I require two requests going from the same view controller. So when I do this, the data is getting mixed up. Say I have a connection for search being implemented, the data from the user details may come in when I do a search. The data is not being assigned to the right NSDictionary based on the switch I'm doing inside connectionDidFinishLoading. I'm using a single delegate for the entire network engine.
I'm new to NSURLConnection, should I setup a queue or something? Please help.
EDIT
Here's the part where I receive data in the connectionDidFinishLoading:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if ([connection.tag integerValue] == kGetUserDetails)
networkDataSource.userData = self.jsonDetails;
if ([connection.tag integerValue] == kSearchConnection)
networkDataSource.searchData = self.jsonDetails;
}
and after this I have a switch case that calls the required delegate for the required view controller.
Anil here you need to identify for which request you got the data,
simplest way to check it is as below,
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
// Check URL value for request, url for search and user details will be different, put if condition as per your need.
conn.currentRequest.URL
}
Try using conn.originalRequest.URL it will give original request.
You can do in many ways to accomplish your task as mentioned by others and it will solve your problem . But if you have many more connections , you need to change your approach.
You can cretae a subclass of NSOperation class. Provide all the required data, like url or any other any informmation you want to get back when task get accomplish , by passing a dictionary or data model to that class.
In Nsoperation class ovewrite 'main' method and start connection in that method ie put your all NSURRequest statements in that method. send a call back when download finish along with that info dict.
Points to be keep in mind: Create separte instance of thet operation class for evey download, and call its 'start method'.
It will look something like :
[self setDownloadOperationObj:[[DownloadFileOperation alloc] initWithData:metadataDict]];
[_downloadOperationObj setDelegate:self];
[_downloadOperationObj setSelectorForUpdateComplete:#selector(callBackForDownloadComplete)];
[_downloadOperationObj setQueuePriority:NSOperationQueuePriorityVeryHigh];
[_downloadOperationObj start];
metaDict will contain your user info.
In DownloadFileOperation class you will overwrite 'main' method like :
- (void)main {
// a lengthy operation
#autoreleasepool
{
if(self.isCancelled)
return;
// //You url connection code
}
}
You can add that operation to a NSOperationQueue if you want. You just need to add the operation to NSOperationQueue and it will call its start method.
Declare two NSURLConnection variables in the .h file.
NSURLConnection *conn1;
NSURLConnection *conn2;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
if(connection == conn1){
}
else if(connection == conn2){
}
}
This question already has answers here:
How to use iOS Reachability
(3 answers)
Closed 9 years ago.
I'm writing an app for a college that will likely be used on campus. The college's wifi requires credentials to access the internet through a web page (such as AT&T hotspots). I would like my app to detect whether it's 'connected' to the internet or not. In the past, I've seen other applications redirect to Safari so the user can authenticate and then go back to the application. Does anyone know how to detect this sort of thing without simply trying to grab NSData from a connection (such as google.com) and then assuming if no data is grabbed this is the issue?
iOS automatically brings up a web view when you are trying to connect to a network that has a captive portal. To make sure you are connected and authenticated in your app, you should set UIRequiresPersistentWiFi in your Info.plist.
EDIT: My answer above is only for apps that require an internet connection. If you're just checking whether you are connected and authenticated, I believe you just have to use Reachability and check that you are ReachableViaWiFi. (I believe SystemConfiguration will not say you are reachable via Wi-Fi if you are not authenticated.)
If you are looking to handle the captive network authentication in your app instead of in the iOS default web view, you can use the CaptiveNetwork API.
Since you don't want to use a NSData way (I don't like grabbing NSData either as well as using reachability) Here is what I came up with that is more lightweight because it just checks the HEAD response :) :
- (BOOL)connectedToInternet
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:#"http://www.google.com/"]];
[request setHTTPMethod:#"HEAD"];
NSHTTPURLResponse *response;
[NSURLConnection sendSynchronousRequest:request
returningResponse:&response error: NULL];
return ([response statusCode] == 200) ? YES : NO;
}
- (void)yourMethod
{
if([self connectedToInternet] == NO)
{
// Not connected to the internet
}
else
{
// Connected to the internet
}
}
If you don't want to use Reachability you could initiate a NSURLConnection to a random website while on the campus wifi and check for an authentication challenge.
Set up the NSURLConnection:
// Create the request.
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.apple.com/"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [[NSMutableData data] retain];
} else {
// Inform the user that the connection failed.
}
Implement the auth challange delegate method:
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(#"I'm being challenged.");
}
Then do what you want after the challenge.
Without going and looking at Reachability, if you try to use it to reach a host and it is presented with an auth challenge, it may return that there is no connection because it couldn't reach the specified host. Again, not 100% sure if this statement is accurate.
I am making an jsonstring. When i execute it, it works when i do it in my browser. I do this by logging the exact url and copy it in the browser. Than i get the HTTP Get that i want, but in the iPhone i only get a Bad Login.
- (IBAction)getDown:(id)sender { //perform get request
NSLog(#"beginnen met versturen");
//NSString * _barCode = [[NSUserDefaults standardUserDefaults] objectForKey:#"phoneNumber"];
//build up the request that is to be sent to the server
//NSString*jsonString = [[NSString alloc] initWithFormat:#"{\"barcode\":\"%#\"}", _barCode];
NSString*jsonString = [[NSString alloc] initWithFormat:#"{\"barcode\":\"123456\"}"];
NSString *str = [NSString stringWithFormat: #"http://server.nl/scan.php?data=%#",jsonString];
NSLog(#"%#", str);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:str]];
NSLog(#"url: %#", request);
[request setHTTPMethod:#"GET"];
// [request addValue:#"getValues" forHTTPHeaderField:#"METHOD"]; //selects what task the server will perform
NSLog(#"met value: %#", request);
//initialize an NSURLConnection with the request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if(!connection){
NSLog(#"Connection Failed");
}
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ // executed when the connection receives data
receivedData = data;
/* NOTE: if you are working with large data , it may be better to set recievedData as NSMutableData
and use [receivedData append:Data] here, in this event you should also set recievedData to nil
when you are done working with it or any new data received could end up just appending to the
last message received*/
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{ //executed when the connection fails
NSLog(#"Connection failed with error: %#",error.localizedDescription);
}
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
/*This message is sent when there is an authentication challenge ,our server does not have this requirement so we do not need to handle that here*/
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"Request Complete,recieved %d bytes of data",receivedData.length);
//[self.delegate requestReturnedData:receivedData];//send the data to the delegate
NSData *data = receivedData;
NSDictionary *dictionary = [NSDictionary dictionaryWithJSONData:data];
NSLog(#"%#",dictionary.JSONString ); ; // set the textview to the raw string value of the data recieved
NSString *value1 = [dictionary objectForKey:#"barcode"];
NSLog(#"%#", value1);
NSString *value2 = [dictionary objectForKey:#"product"];
NSLog(#"%#",dictionary);
NSLog(#"%#", value2);
}
Here's the log:
2013-01-10 16:31:46.550 Scanner[14875:907] http://server.nl/scan.php?data={"barcode":"123456"}
2013-01-10 16:31:46.551 Scanner[14875:907] url: <NSMutableURLRequest (null)>
2013-01-10 16:31:46.553 Scanner[14875:907] met value: <NSMutableURLRequest (null)>
**2013-01-10 16:31:46.556 Scanner[14875:907] Connection failed with error: bad URL**
When i delete the complete json from the string i get no bad url. So there might be the problem. Anyone know what i am doing wrong?
You need to encode it, before perfoming an URL request.
Best and most elegant solution would be adding a category over NSString for example, something like this:
- (NSString*)URLEncode {
// Should not be encoded:-_.
return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, CFSTR(";/?:#&=+$,!*'()<>#%\"{}|\\^[]`~"), kCFStringEncodingUTF8) autorelease];
//
}
And when you make the request:
NSString *str = [NSString stringWithFormat: #"http://server.nl/scan.php?data=%#",jsonString];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[str URLEncode]];
If you don't want to use additional files (even thought that would be recommended), add this method to your class:
- (NSString*)URLEncode:(NSString )yourURL {
// Should not be encoded:-_.
return [(NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, NULL, CFSTR(";/?:#&=+$,!'()<>#%\"{}|\\^[]`~"), kCFStringEncodingUTF8) autorelease];
}
and use
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[self URLEncode:str]];
I don't have much information right now, I apologize, I'm in a bit of a hurry and just saw your question. But I saw your question and I remember working on a project which was essentially an HTML-based remote control for the iphone, and when the user clicked on some of the buttons for the remote, it followed the urls that opened up identical pages but had server-side code to instruct the server to pause, play, stop, etc... I DO remember that the iPhone had a bug that caused it to not be able to parse all of my URLs, even though they were correctly formatted and worked on a desktop client. That is why I switched over to POST requests (where user clicks instead activated javascript functions that set hidden form variables and then submitted forms rather than directly navigating to long URLS). Anyways, I know this may not directly apply to you, but the point is that I did find a bug in the iPhone's URL parsing, so it might not be your fault. I'll look up any new information I can find a little later. Good luck.
I need to check and evaluate the HTTP Status Codes in my iPhone app. I've got an NSURLRequest object and an NSURLConnection that successfully (I think) connect to the site:
// create the request
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.apple.com/"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData that will hold
// the received data
// receivedData is declared as a method instance elsewhere
receivedData=[[NSMutableData data] retain];
} else {
// inform the user that the download could not be made
}
I got this code here: https://web.archive.org/web/20100908130503/http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
But it doesn't (as far as I can see) say anything about accessing HTTP Status codes.
How to make a connection to a site and then check the HTTP Status Codes of that connection?
This is how I do it:
#pragma mark -
#pragma mark NSURLConnection Delegate Methods
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int responseStatusCode = [httpResponse statusCode];
}
But I'm using an asynchronous NSURLConnection, so this may not help you. But I hope it does anyway!