So, I have to methods to approach a web service:
A GET:
- (NSDictionary *)getDataFromURL:(NSString*)url {
NSString * serverAddress =[NSString stringWithFormat:url,mySchoolURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL
URLWithString:serverAddress]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10
];
[request setHTTPMethod: #"GET"];
NSError *requestError = nil;
NSURLResponse *urlResponse = nil;
NSData *response = [NSURLConnection
sendSynchronousRequest:request
returningResponse:&urlResponse
error:&requestError];
NSError* error = nil;
NSDictionary *output = [NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:nil];
return output;
}
and a POST:
-(NSData*)postData:(NSDictionary*)requestData toUrl:(NSString*)destination {
NSError *error;
NSData *postdata = [NSJSONSerialization dataWithJSONObject:requestData options:0 error:&error];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postdata length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:destination,mySchoolURL]]];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postdata];
[request setHTTPMethod:#"POST"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
return nil;
}
Somehow, the HTTP header of the POST method does include the cookie's SessionID, while the GET one doesn't.
I have to admit that I don't fully understand the innards of cookies and the like, but several sources on the web claim that I should't worry about the cookies at all, since they are taken care of automatically.
Anyway, the web service I'm talking to expects a Session ID in both POST and GET situations, so now I'm forced to start understanding what's going on.
Could any of you help me out here?
The concrete question is: how to I pass a Session_ID to a URL using a GET method?
Thanks ahead
Okay so one way to do this is by simply adding the cookies to the HTTP headers. When doing this the correctness of the URL is key. If the protocol is wrong, some cookies may not be included. You will need to get all available cookies, and then create a dictionary for the headers with he available cookies. Then you simply add those headers to your request by calling setAllHTTPHeaderFields:. I placed a quick example of how to do this below, however you can learn more about how cookies work at the Apple Documentation Class Reference
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:request.URL];
NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
[request setAllHTTPHeaderFields:headers];
I really hope this helps you out. I would recommend reading the Apples Documentation to help you out as much as possible. I wish you the best of luck!
Related
I'm having a hard time trying to receive JSON form a NSURLConnection request. Can anybody offer any advice? I can't understand why the JSON does not appear
EDIT: When I append the endpoint /books to the end of the url string I get this JSON response: " json NSDictionary * 0 key/value pairs. " Does this mean that there is nothing in the server?
-(void)makeLibraryRequests
{
NSURL *url = [NSURL URLWithString:#"http://prolific-interview.herokuapp.com/54bexxxxxxxxxxxxxxxxaa56"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //;]cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0f];
[request setHTTPMethod:#"GET"];
// This is actually how jQuery works. If you don't tell it what to do with the result, it uses the Content-type to detect what to do with it.
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
//[request setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//parse data here!!
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if (json) {
//NSArray *allBooks = [json objectForKey:#"books"];
//create your MutableArray here
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
else{
NSLog(#"error occured %#", jsonError);
NSString *serverResponse = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"\n\nError:\n%#\n\nServer Response:\n%#\n\nCrash:", jsonError.description, serverResponse);
//[NSException raise:#"Invalid Data" format:#"Unable to process web server response."];
}
}];
}
As YiPing pointed out, you must provide the books end point. But you won't have anything there until you first post a book.
NSDictionary *params = #{#"author": #"Diego Torres Milano",
#"categories" : #"android,testing",
#"title": #"Android Application Testing Guide",
#"publisher": #"Packt Publishing",
#"lastCheckedOutBy": #"Joe"};
NSURL *url = [NSURL URLWithString:#"http://prolific-interview.herokuapp.com/54bexxxxxxxxxxxxxaa56/books/"]; // your id removed for security's sake ... put it back in
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSError *encodeError;
NSData *body = [NSJSONSerialization dataWithJSONObject:params options:0 error:&encodeError];
NSAssert(body, #"JSON encode failed: %#", encodeError);
request.HTTPBody = body;
So, first POST a book using a request like the above, then your original GET (assuming you add the end point) will now return a result.
Add some endpoints to your URL
try this:
http://prolific-interview.herokuapp.com/54bexxxxxxxxxxxxxxxxaa56/books/
I need to make a HTTPS post request to a server using a synchronous connection. I've made plenty of http connections but for some reason the code doesn't work with https and I'm sure the website address is right.
Some of my code:
Note that dparam is a dictionary object.
NSError *err;
NSData *parameterJSONData = [NSJSONSerialization dataWithJSONObject:dparam options:
NSJSONWritingPrettyPrinted error:&err];
NSString *param = [[NSString alloc] initWithData:parameterJSONData encoding:NSUTF8StringEncoding];
NSString *post =[[NSString alloc] initWithFormat:#"varnameOne=%#&varnameTwo=%#¶m=%#",vone,vtwo,param];
//my_url is a string defined elsewhere
NSURL *url=[NSURL URLWithString:my_url];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
I need to do this synchronously as I don't really have the time to change all my database calls to asynchronous and the calls need to either complete or fail before the program continues so it'd have to be made effectively synchronous anyway.
That said I did try a synchronous route but it didn't work with https only http.
Good day,
I am trying to use a Codeigniter based API to connect with iOS and using NSURLRequest.
The API is in debugMode and for now it returns the same key value pair as json as the one that you are posting. I have tried posting the values to the link through postman and it works correctly, however when I post it through my iOS application, the json response is received but the array that should contain the post values is empty.
Here is the iOS Code snippet :
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#",BASEURL,service]];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSString * params = #"authkey=waris";
NSData * postData = [params dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];;
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSLog(#"Posting : '%#' to %#",params,url);
[connection start];
This is the response when I post the same parameters through postman ( A RESTFUL Client for Chrome )
{
"status": "1",
"data": {
"authkey": "warisali"
}
}
However when I query the same API from the above iOS Code I am getting this :
{
data = 0;
status = 1;
}
Any help on the matter will be highly appreciated!
I had same issue (not with CodeIgniter but with Ruby ...)
Try something like this, solved my problem.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#",BASEURL,service]];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
NSDictionary *paramDict = #{#"authkey": #"waris"};
NSError *error = nil;
NSData *postData = [NSJSONSerialization dataWithJSONObject:paramDict options:NSJSONWritingPrettyPrinted error:&error];
if (error)
{
NSLog(#"error while creating data %#", error);
return;
}
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postData length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];;
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSLog(#"Posting : '%#' to %#",params,url);
[connection start];
I ended up using the ASIHttpRequest + SBJson combo and that worked like Charm!
After adding the ASIHttpRequest core classes and SBJson Classes to parse the JSON, I was able to achieve what I wanted !
The problem is that because of the way you're creating the connection, it will start immediately, before you've finished configuring the request. Thus, you're creating a mutable request, creating and starting the connection, then attempting to modify the request and then trying to start the request a second time.
You can fix that by changing the line that says:
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
To say:
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
Or, easier, just move the original instantiation of the NSURLConnection (without the startImmediately:NO) after you've finished configuring your request, and then eliminate the [connection start] line altogether.
// Web service request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: urlLoc]];
NSString *postLength = [NSString stringWithFormat:#"%d", [requestData length]];
[request setHTTPMethod: #"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody: requestData];
NSError *respError = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: &respError ];
//returndata is response of webservice
NSString *responseString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSDictionary *results = [responseString JSONValue] ;
NSLog(#"chat data- %#",results);
NSString *strResults = [results objectForKey:#"d"];
NSLog(#"result string is-%#",strResults);
this is the code that I am using for my Data fetching from web service. But i have to do this every time when come to this page.
Is that any method that can store my data in Cache memory so i need not to request every time.
I Am using
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
but i dont know how to use - (NSCachedURLResponse *) connection this method
thanks...
You need to use cache as of your needs according to this documentation: whenever you requesting a NSMutableURLRequest...
For Ex:
[NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadRevalidatingCacheData timeoutInterval:60];
For More details Kindly look into the Documentation
I've been reading over code samples and posts for days but I haven't found a definitive way to post JSON data from my Core Data objects to a RESTful web service. There's a TON of documentation about pulling the JSON from a web service but not so much about sending stuff back. Can anyone point me to a good example or post some code on how to do it? I'm using Core Data and I have the object I want to send back mapped to a Dictionary but I'm missing the code to send it to the service.
EDIT:
I ended up with the code below which looks right and runs without errors, but I get 0 bytes of data returned and my webservice doesn't seem to be receiving the request. The JSON data looks good, the URL is correct, and I can hit the webservice and get JSON data back from it. The NSURLConnection delegate methods also fire as expected.
Is there anything I'm missing below?
- (void)SubmitSystems
{
NSFetchRequest * allSystems = [[NSFetchRequest alloc] init];
[allSystems setEntity:[NSEntityDescription entityForName:#"System" inManagedObjectContext:self.managedObjectContext]];
NSError * error = nil;
NSArray * systems = [self.managedObjectContext executeFetchRequest:allSystems error:&error];
//error handling goes here
//for (NSManagedObject * system in systems) {
NSManagedObject *system = systems[2];
NSString *entityString = #"System";
NSString * serverString = [NSString stringWithFormat:#"%#%#", kWebServiceAddress, entityString];
NSURL *url = [NSURL URLWithString:serverString];
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:[self jsonSystemDictionary:(System *)system] options:kNilOptions error:&error];
//NSLog([[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]); //debug only
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 30.f];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [jsonData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: jsonData];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//}
}
You're going to need to NSMutableURLRequest. Using this, you can use setHTTPMethod and pass it the #"POST" string, and then use the attributes of your NSManagedObject to populate the URL, HTTPBody and/or HTTPHeader as needed.