I have 2 separate NSURLConnection.
NSURLConnection * connection_users;
NSURLConnection * connection_cards;
Then i created the data with parameters, etc. and I finish with:
connection_users = [[NSURLConnection alloc] initWithRequest: url_request_users delegate: self startImmediately: YES];
In the delegate method:
- (void) connection: (NSURLConnection *) connection didReceiveData: (NSData *) data
i Checked if the connection is for the connection_users:
if (connection == connection_users) / / do something as an example:
NSDictionary * json_response = [NSJSONSerialization JSONObjectWithData: data options: kNilOptions error: & error];
Use the "data" that came from the method.
Before closing the "if" I create the next connection to "connection_cards", doing the same things
Out of "if" but within the same method I do another "if" to "connection_cards" and do the same thing with JSONObjectWithData.
Only the "data" that comes from the method is always of the first connection.
What is happening differently? For the second connection was initiated then you should receive the "data" corresponding.
Already canceled the first connection before starting the second to see if solved, but no.
How to obtain the "data" correct for second connection?
PS: if you need more codes, please let me know.
EDITED:
As Wain ask
url_request_users = [[NSMutableURLRequest alloc] init];
NSMutableString *post_users = [[NSMutableString alloc] init];
[post_users appendFormat:#"%#", [NSString stringWithFormat:#"email=%#&senha=%#",
[[alert textFieldAtIndex:0] text],
senha_md5]];
[url_request_users setURL:[NSURL URLWithString:WBS_USERS_RECOVER]];
[url_request_users addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[url_request_users setHTTPMethod:#"POST"];
[url_request_users setHTTPBody:[post_users dataUsingEncoding:NSUTF8StringEncoding]];
connection_users = [[NSURLConnection alloc] initWithRequest:url_request_users delegate:self startImmediately:YES];
For n different connections you will need n different NSMutableData which contains result of related NSURLConnection. A basic example for your question;
NSMutableData *data_users;
NSMutableData *data_cards;
Than on your didRecieveData;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (connection == connection_users) {
[data_users appendData:data];
} else if ( connection == connection_cards) {
[data_cards appendData:data];
}
}
This way you can keep track of your data's and connection's seperately. Remember to clear leftovers for your datas when your connection is over
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (connection == connection_users) {
// use data from data_users
NSDictionary * json_response = [NSJSONSerialization JSONObjectWithData:[data_users copy] options: kNilOptions error: & error];
data_users = [[NSMutableData alloc] init]; // clear data users
}
// do the same for cards connection
}
Last thing to do is to allocate your data before you call this function;
url_request_users = [[NSMutableURLRequest alloc] init];
NSMutableString *post_users = [[NSMutableString alloc] init];
[post_users appendFormat:#"%#", [NSString stringWithFormat:#"email=%#&senha=%#",
[[alert textFieldAtIndex:0] text],
senha_md5]];
[url_request_users setURL:[NSURL URLWithString:WBS_USERS_RECOVER]];
[url_request_users addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[url_request_users setHTTPMethod:#"POST"];
[url_request_users setHTTPBody:[post_users dataUsingEncoding:NSUTF8StringEncoding]];
data_users = [[NSMutableData alloc] init]; // add this line in your code
connection_users = [[NSURLConnection alloc] initWithRequest:url_request_users delegate:self startImmediately:YES];
Related
i have a method for http connection, which was working fine for me until the server i am trying to have an invalid ssl certificate.
Since i am using
[NSURLConnection sendSynchronousRequest:returningResponse:error]
There is no chance to pass authentication challenge by using NSURLConnection delegate methods.
Now, i need to change my service call code as fast as possible.
My method returns the data received from the connection, that is the major problem i can not easily change mine to
NSURLConnection to initWithRequest:delegate:
My service call method is as follows;
-(id)serviceCall:(NSString*)str withURL:(NSString*)serviceUrl withIdentifier:(NSString*)type
{
globalURL = [[NSURL alloc] initWithString:serviceUrl];
shouldAllowSelfSignedCert = YES;
// if(ISDEBUG) NSLog(#"%#",serviceUrl);
NSMutableDictionary* json;
NSURLResponse* response;
NSData* responseData = [NSMutableData data];
NSError* error = nil;
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:globalURL];
[request setHTTPMethod:#"POST"];
[request setHTTPBody: [str dataUsingEncoding: NSUTF8StringEncoding]];
NSString* msgLength = [[NSString alloc] initWithFormat:#"%lu", (unsigned long)[str length]];
[request addValue:#"text/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request addValue:msgLength forHTTPHeaderField:#"Content-Length"];
request.timeoutInterval = 180;
responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if([type isEqualToString:#"image"])
{
if(ISDEBUG) NSLog(#"%#",responseData);
return responseData;
}
else
{
if(error)
{
UIAlertView *message = [[UIAlertView alloc] initWithTitle:NO_WS_CONNECTION message:#"" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
if(ISDEBUG) NSLog(#"%#",error);
}
else
{
if(responseData !=nil)
{
json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:NO_WS_CONNECTION delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if(ISDEBUG) NSLog(#"%#",responseString);
}
return json;
}
I hope i am clear enough.
What is your advise?
Thanks.
You should have a good reason to do it synchronously, so, I will try to help you without changing the flow.
Try wrapping the request into a class where you can implement the request using initWithRequest:delegate: and make the class return the response using block.
You will have something like:
[YourRequestClass requestWithURL:serviceURL callback:^(NSData *yourData, NSError *error){
}];
Ok, at this point you have a new tool that makes ASYNCHRONOUS requests, make the authentication challenge stuff for you and returns the result on a block.
Now, you can simply use dispatch_semaphore to block your thread until the request returns a response ....
-(id)serviceCall:(NSString*)str withURL:(NSString*)serviceUrl withIdentifier:(NSString*)type {
__block NSData *myData = nil;
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
[YourRequestClass requestWithURL:serviceUrl callback:^(NSData *yourData, NSError *error){
//ignoring error (this is an example !)
myData = yourData;
dispatch_semaphore_signal(sem);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
//Use myData and make yourObject here!
return yourObject;
}
Note that It's just an example, and I'm just trying to pointing you the right way ... I didn't test this code, but I believe it should work as expected!
I'm trying to make a basic app that takes in a persons details and posts it on a private server. My URL is kept blank for now, If I use the NSURLConnectionDelegate and use didFailWithError, it works saying there's no connection but when I try the NSLog method it says
"connection is made"
for some reason. This is my code
- (void) saveData{
NSString *name = self.NameTextField.text;
NSString *phoneNumber = self.phoneNumberTextField.text;
NSString *age = self.ageTextField.text;
NSString *email = self.emailTextField.text;
//Define the URL
NSURL *url = [[NSURL alloc]initWithString:#""];
//Initialize a request from the URL
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];
//Specify that it will be a post request.
request.HTTPMethod = #"POST";
// This is how we set header fields
[request setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSString *DataString = [NSString stringWithFormat:#"name=%#&phonenumber=%#&age=%#&email=%#",name,phoneNumber,age,email];
//Change your requests HTTPBody property
NSData *requestBodyData = [DataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = requestBodyData;
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = conn;
if(self.connection){
NSLog(#"Connection is made");
}else{
NSLog(#"Connection is not made");
}
[self.connection start];
}
Do inform if theres any other mistake in my code.
All that if (self.connection) is doing is checking to see if it's nil it's not actually checking to see if a connection has been made you do that at [self.connection start];. So essentially:
if (self.connection) {
NSLog(#"Connection is made");
} else {
NSLog(#"Connection is not made");
}
is the exact same as
if (self.connection != nil) {
NSLog(#"Connection is made");
} else {
NSLog(#"Connection is not made");
}
And self.connection is not nil because you assign conn to it which has been initialized. This can be seen in the two lines below from your code.
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = conn;
What you could do if you are wanting to check whether the connection was successful or not is check the HTTP Status code in didReceiveResponse: (Code obtained from Checking for valid IP for connection with NSURLConnection)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
switch ([(NSHTTPURLResponse *)response statusCode]) {
case 200: {
NSLog(#"Received connection response!");
break;
}
default: {
NSLog(#"Something bad happened!");
break;
}
}
}
OR if it's just to see whether you can or not you could implement the Reachability code that Apple supplies or use another open source version.
Your code checks whether the self.connection variable is not null, which it's not since the alloc init seems to have executed successfully. i.e the object is created and that is what you are checking, whether it does what you want is a different story.
i am using singleton class for web service calling and display in uitableview ,My function is when i clicked submit button of new orchardname for new add then view redirect to tableview but data not seen which add recently. "singOrchard.orcharsList" it's orchard name array which i have to display. "[wOrchrad getorchardslist]" it's my web service call.
- (IBAction)Submit:(id)sender
{
if (Orchadname.text.length == 0) {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"DataTree" message:#"Please Enter OrchardName" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[message show];
}
else {
[singOrchard.orcharsList removeAllObjects];
NSString *urlStr = [NSString stringWithFormat:#"http://xyz.com"]; // Passing token to URL
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self]; // Support to perform URLrequest
if (theConnection) { // checking connection successfull or not
webData1 = [NSMutableData data];
NSLog(#"Orchard Name is %#", Orchadname.text);
}
[wOrchrad getorchardslist];
NSLog(#"ARRAY COUNT %#",singOrchard.orcharsList);
[self performSelector:#selector(gotodetails) withObject:nil afterDelay:4];
}
}
"[wOrchard getorchardslist]- Singletone+Webserviceutility"
- (void)getorchardslist
{
orchardsnames = [[NSMutableArray alloc] init];
singltoneclass = [SingletoneClass sharedInstanceMethod];
theRequest =[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.xyz.com"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
webData = [NSMutableData data];
[theConnection start];
}
You are not using the return result from theConnection. (At least not in your provided code.) Since you have set your class as the delegate, implement the NSURLConnectionDataDelegate methods.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
use it to save your JSON data to an NSArray, which you can then use in your UITableView.
If you send your request asynchrounsly, don't forget to append the data with
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
I am making an iPhone app that will need to communicate with the Sendy API. I believe that it uses some kind of JSON, but I'm not really sure, nor do I know where to start. I'm particularly interested in the subscribe portion of the API. Basically, I need to know how to talk to the Sendy API from my app.
Any help is appreciated.
My code:
- (IBAction)submitButtonPressed:(id)sender
{
self.data = [[NSMutableData alloc] initWithLength:0];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://www.erwaysoftware.com/sendy/subscribe"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"john#test.com" forHTTPHeaderField:#"email"];
[request setValue:#"john" forHTTPHeaderField:#"name"];
[request setValue:#"LxxxxxxxxxxxxxxxxxxxxQ" forHTTPHeaderField:#"list"];
[request setValue:#"true" forHTTPHeaderField:#"boolean"];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
[conn start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.data setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
[self.data appendData:d];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Error", #"")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil] show];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseText = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
// Do anything you want with it
NSLog(#"%#", responseText);
}
When the log happens, the string is empty. I know through breakpoints that the last method is called.
Looking at the API it's all just plain text response.
Since it's a POST you can use an NSURLConnection to compose the request. See this question for information on formatting the response.
An alternative is to use something like AFNetworking or RestKit that might be a little more friendly if you're doing more work with APIs.
I'm guessing you've already resolved this but in case anyone else gets stuck here (as I did) I thought I'd post what I did to get it to work.
The first thing you need to do is create a category called NSString+URLEncoding (or whatever) which is going to take your email and name fields from blah#blah.com and turn it into blah%40blah.com. I modified this from the handy blog post found here
#interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
#end
#import "NSString+URLEncoding.h"
#implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding)));}
#end
Ok so now just import NSString+URLEncoding.h and add the following code and you'll be in business. This post helped me with this part
- (IBAction)submitButtonPressed:(id)sender
{
NSMutableURLRequest *newRequest = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:#"http://stashdapp.com/sendy/subscribe"]];
[newRequest setHTTPMethod:#"POST"];
[newRequest setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSString *email = #"name#domain.com";
NSString *name = #"First Lastname";
NSString *list = #"XXXXXXXXXXXXXXXXXX";
NSString *postData = [NSString stringWithFormat:#"email=%#&boolean=true&name=%#&list=%#", [email urlEncodeUsingEncoding:NSUTF8StringEncoding],[name urlEncodeUsingEncoding:NSUTF8StringEncoding],list];
[newRequest setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:newRequest delegate:self];
[conn start];
}
You still include the delegate methods which you quoted in your question.
Hope it helps someone!
Suppose i have two classes A & B. class A calls the asynchronus method Foo in class B. Foo method fetches data using asynchronous ASIHTTPRequest and send the data from Foo back as the return value to Class A. Class A will use that returned data and do the things
I am creating a object of my class URLParser here in another class and calling the function getJsonUrl , it will parse and get the json url for me . I am using that returned URL in another ASIHTTPRequest here . But i am getting EXC_BAD_ACCESS ...help me to figure it out ....
......
URLParser *urlParser = [[URLParser alloc] init];
NSString *JsonString = [urlParser getJsonUrl:#"http://mywebs.com/?q=iphone/news"];
NSLog(#" url returned = %#" ,JsonString);
NSURL *JsonUrl = [NSURL URLWithString:JsonString];
newsRequest = [ASIHTTPRequest requestWithURL:JsonUrl];
[newsRequest setDelegate:self];
[newsRequest startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
newsDictionary = [[NSMutableDictionary alloc] init];
NSData *responseData = [request responseData];
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding] ;
self.newsDictionary = [response JSONValue];
[response release];
[self getDataNews:self.newsDictionary];
}
URL Parser Class
#synthesize albumDic;
#synthesize GlobalRequest;
-(NSString*)getJsonUrl:(NSString *)url{
GlobalRequest = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
[GlobalRequest setDelegate:self];
[GlobalRequest startAsynchronous]; // when i called the [GlobalRequest startSynchronous] ....both cases m getting the same error
return JsonStr;
}
- (void)requestFinished:(ASIHTTPRequest *)request{
albumDic = [[NSMutableDictionary alloc] init];
NSData *responseData = [request responseData];
NSString *response = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding] ;
self.albumDic = [response JSONValue];
[response release];
[self GetDictionary:self.albumDic];
}
- (void)requestFailed:(ASIHTTPRequest *)request{
[request cancel];
}