We should use Aysnc calls when dealing with NSURLConnections.
May articles illustrate why we should do that, among them is this one
The truth about synchronous NSURLConnection. Also see my question on
SO.
But We want also to have our "Communicate" code grouped somewhere not to be implemented by all of our classes in the project.
This post is talking about how to solve this issue.. Thanks to
AliSoftware .
Well, We will have some Utility class the doing the connection and handle the data for us.. but what will we do when we got the data from the server? we should call some method on the caller class (in cases, it is a ViewContoller).. so we should send the target class and the selector to be called when the connection done receiving data.
So, Here's the code (quick and dirty) for the URLCaller class:
1.
2. #import <Foundation/Foundation.h>
3.
4. @interface URLCaller : NSObject
5. {
6. NSMutableData* data;
7. NSObject* target;
8. SEL selector;
9. }
10. @property (nonatomic, retain) NSMutableData* data;
11. @property (nonatomic, retain) NSObject* target;
12. @property (nonatomic) SEL selector;
13.
14. -(id) initWithTarget:(NSObject*) target selector:(SEL)selector;
15. -(void) call:(NSString*) url;
16.
17. @end
18.
19.
20. #import "URLCaller.h"
21.
22. @implementation URLCaller
23. @synthesize data, target, selector;
24.
25. -(id) initWithTarget:(NSObject*) _target selector:(SEL)_selector
26. {
27. if (self = [super init])
28. {
29. self.target = _target;
30. self.selector = _selector;
31. }
32. return self;
33. }
34.
35. -(void) call:(NSString*) url
36. {
37. NSURLConnection* connection = [[NSURLConnection alloc]initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:self];
38. [connection release];
39. }
40.
41. #pragma mark - NSURLConnection deleages
42.
43. -(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
44. {
45. data = [[NSMutableData alloc] init];
46. }
47. -(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)_data
48. {
49. [self.data appendData:_data];
50. }
51. -(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
52. {
53.
54. }
55. -(void)connectionDidFinishLoading:(NSURLConnection*)connection
56. {
57. NSString* stringData = [[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]autorelease];
58. [target performSelector:selector withObject:stringData];
59. }
60.
61. - (void)dealloc
62. {
63. [target release];
64. [data release];
65. [super dealloc];
66. }
67.
68. @end
And in the caller class (in my case is a ViewController), we will use the URLCaller class:
1.
2. -(IBAction)getDataFromServer:(id)sender
3. {
4. URLCaller* caller = [[URLCaller alloc]initWithTarget:self selector:@selector(setTextViewContents:)];
5. [caller call:@"http://search.twitter.com/search.json?q=Muhammad"];
6. [caller release];
7. }
8.
9.
10. -(void) setTextViewContents:(NSString*) contents
11. {
12. text.text = contents;
13. }
You can get the project source code from
here
Very important notice is that, the application will never got freeze while the data is being transferred, and this is what we wants!
No comments:
Post a Comment