-1

The following are methods that I am using to retrieve data from a server while displaying a UIActivityIndicator. I'm trying to put these methods in the app delegate and then call them from other classes, but I don't know how to return my JSONData. Can anybody help with this?

 -(void)startProcess:(NSString *)buildURL{


UIActivityIndicatorView *aInd = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActionSheetStyleBlackTranslucent];

[aInd setFrame:CGRectMake(0, 0, 50, 50)];
[aInd startAnimating];

// then call the timeCOnsumingmethod in separate thread.
[NSThread detachNewThreadSelector:@selector(getData:) toTarget:self withObject:buildURL];
} 

- (void)getData:(NSString *)buildURL{


NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// Query our database for a restaurant's menus
NSURL *url = [NSURL URLWithString:buildURL];
NSError *e;
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&e];

NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
// NSError *error = nil;

[self performSelectorOnMainThread:@selector(endProcess:) withObject:jsonData waitUntilDone:YES];
[pool release];

//return jsonData;
}

- (IBAction)endProcess:(NSData *)jsonData{
// ??????????
return jsonData;
}
Apollo
  • 8,874
  • 32
  • 104
  • 192
  • Hmm...why not use an asynchronous API for your web service request rather than the convoluted `detachNewThreadSelector:toTarget:withObject:` It will make much more sense than firing off `performSelector...` back and forth. I would go through some examples of asynchronous use of `NSURLRequest` or third-party networking library. [Here's one](http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/) – FluffulousChimp Mar 20 '12 at 19:05
  • this tutorial is great, but how would I change it so that I implement these methods in a separate class? – Apollo Mar 20 '12 at 19:15

1 Answers1

4

Not sure why got downvoted but your approach is all wrong. Here's what you want to do:

  • Add the UIActivityIndicatorView
  • Use NSURLConnection to asynchronously retrieve the data
  • Use NSJSONSerialization to decode the received JSON into a NSDictionary or NSArray
  • Remove the UIActivityIndicatorView

Your best bet would be to implement this as a separate class that takes a delegate object. You could implement a delegate protocol to indicate states like 'started network activity' (which your delegate could use to add a spinner view), and 'received data' (which would pass the decoded object back to the delegate - the delegate could then remove the spinner).

One of the benefits of this approach is you can easily set it up so that the connection/request is canceled when the object deallocs. Then you just store the request object as a property on your delegate, and when your delegate goes away, it deallocs the request, which cancels/cleans up properly.

jsd
  • 7,673
  • 5
  • 27
  • 47
  • Ok great. Is there a tutorial for how to create your own delegate with these methods? Could you provide a sample protocol which takes this delegate? thanks a lot! – Apollo Mar 20 '12 at 19:13
  • 1
    Look at some of the familiar delegate protocols in Cocoa as a guide to what @jsd is referring to. For example, `UITableViewDelegate`. You will create a separate downloader class that holds a reference to a delegate (e.g. your view controller.) That delegate conforms to a protocol that you declare either in your downloader class interface file or as a separate file. Your protocol methods would include things like `- (void)downloaderDidBeginDownload:(id)downloader` etc. – FluffulousChimp Mar 20 '12 at 19:32
  • Is this similar to something like how you display a modalview which also requires a protocol? – Apollo Mar 20 '12 at 21:50
  • Here's an intro to delegates: http://stackoverflow.com/questions/626898/how-do-i-create-delegates-in-objective-c – jsd Mar 20 '12 at 22:43
  • @alanduncan why would that method be void. wouldn't it need to return a value? – Apollo Mar 21 '12 at 00:18