Lefora Free Forum
login join
Loading
1792 views

Return data from NSURLConnection delegate method

Page 1
1–6
novice - member
27 posts

Here is the situation. I am sending my AppDelegate a Notification to update some data within itself. The AppDelegate then calls a class method which was initially set to return a Dictionary from my server synchronously. I change the code around inside the class method so now it uses NSURLConnection to asynchronously get data from my server. So I put the original return data into the delegate method - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data.
My question is now, how do I return the Dictionary from that delegate method back to my AppDelegate?

?
288 posts


There are three ways to pass data between objects in cocoa.

1) Directly.  The sender has a pointer to the receiver and knows which method to call
2) Notification.  The sender broadcasts and the reciever listens
3) Bindings.  The sender and receiver both have a binding to the same value

Directly is the simplest and in your case here, it's probably very simple to use the following technique:

Controller.mm
#include stuff

MyController* myController ;

// your async call back is here somewhere
... didReceiveData :(NSData) data
{
  NSDict* dict ........ ;
  [myController heresTheDictionaryBuddy:dict] ;
}



@implementation Controller {

- (void) heresTheDictionaryBuddy:(NSDictionary*) theDict
{
  // do the business
  [theDict retain];
  [myDict release] ;
  myDict = theDict ;
}

- (void) awakeFromNib
{
  myController = self ;
}
@end

If your async call back code is in a different .m/.mm file, you can declare extern Controller* myContoller ; in a shared .h file and the linker will take care of the rest.

////
Here's another simple direct way:

I don't remember using the classes that you mentioned, however with most of those things, there is an id contextInfo you can pass.  So when you "fire" the async event, you can do something like:

myConnections:@"url" ..... context: self

In the receiver, you can do:

Controller* controller = (Controller*) context ;
[controller heresTheDictionaryBuddy:dict];

__________________
novice - member
27 posts

Perhaps it will be easier to show you my code to get a better idea. If this bad code, don't blame me, I inherited it.

My AppDelegate function in which I want to get a return value

 


- (BOOL)autoLoginWithUserName:(NSString *)username andPassword:(NSString *)password {

     self.appointmentsForDate = [[NSMutableArray alloc] init];

     NSArray *keys = [NSArray arrayWithObjects:@"username", @"password", @"appID", nil];
     NSArray *objects = [NSArray arrayWithObjects:username, password, @"1", nil];
     NSDictionary *parameters = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
     NSDictionary *wsResponse=[WebServices callRestService:@"loginUser" withParameters:parameters]; <-----This is were I require a return value from the class method, so I would have to continue from
                                                                                                          here to go through the validation process

     NSString *responseString = [wsResponse objectForKey:@"value"];

     if (responseString) {

          XMlParser *xmlParser = [[[XMlParser alloc] init] autorelease];
          NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding]] autorelease];

          [parser setDelegate:xmlParser];
          [parser setShouldProcessNamespaces:NO];
          [parser setShouldReportNamespacePrefixes:NO];
          [parser setShouldResolveExternalEntities:NO];
          [parser parse];

          NSDictionary *resultDictionary = xmlParser.parentElement;

          NSArray *elementArray = [resultDictionary objectForKey:@"elementData"];     

          NSDictionary *attributesDict = [elementArray objectAtIndex:1];

          NSString *response = [attributesDict objectForKey:@"result"];

          if ( [response compare:@"Fail"] == NSOrderedSame) {
               return NO;
          }

          else {
               [[NSUserDefaults standardUserDefaults] setObject:username forKey:@"username"];
               [[NSUserDefaults standardUserDefaults] setObject:password forKey:@"password"];
               [[NSUserDefaults standardUserDefaults] setObject:[attributesDict objectForKey:@"userid"] forKey:@"userid"];

               BOOL selected =  [[attributesDict objectForKey:@"User"] boolValue];

               [[NSUserDefaults standardUserDefaults] setBool:selected forKey:@"Enabled"];
               [functions dismissModalViewControllerAnimated:YES];
               [self getAppointmentsForDate];

               return YES;
          }
     }

     else {
          UIAlertView *error = [[[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not connect to server" delegate:nil cancelButtonTitle:@"Retry" otherButtonTitles:nil] autorelease];

          [error show];

          return NO;
     }

     return NO;

}

 

This is where I initially would get my value from, but I want to make it asynchronous.

 


+(id)callRestService: (NSString *) methodName withParameters:(NSDictionary *) parameters

{
     NSURLRequest *url=[WebServices getRestUrl: methodName withParameters: parameters];

     XMlParser *xmlParser = [[[XMlParser alloc] init] autorelease];

     NSXMLParser *parser = [[[NSXMLParser alloc] initWithContentsOfURL:[url URL]] autorelease];

     if (parser) {

          [parser setDelegate:xmlParser];
          [parser setShouldProcessNamespaces:NO];
          [parser setShouldReportNamespacePrefixes:NO];
          [parser setShouldResolveExternalEntities:NO];
          [parser parse];

          return xmlParser.parentElement;
     }

     return NO;
}


 

?
288 posts

Routers

Thanks for the code - it looks fine (although I suspect it's leaking memory).  I'm at work now (in California). I'll have to leave this until I get home this evening - however I promise I will reply.

__________________
novice - member
27 posts

Never mind, I am going to keep that code. There was a problem in communication, so I thought I need to update this code.

?
288 posts

OK.  I'm happy to be off the hook.  However I have written a little program httpget which does an async http get request and display progress and output.    http://clanmills.com/articles/cocoatutorials/httpget.zip

Usual guarantees and excuses.  I know the code leaks memory, but what the heck, I've had a long day in the office. 


__________________
Page 1
1–6

Locked Topic


You must be a member to post in this forum

Join Now!