Reputation: 199
I have a method to download a JSON result from a server regularly so I would like to learn how to input parameters as opposed to keep typing out the same method over and over!
Here is what I have so far:
-(void)downloadData:(NSString *)saveto downloadURL:(NSString *)URL parameters:(NSString *)params{}
It is mostly working ok, except where I am attempting to save my result. I wish to store my result in an array called "locations", I am trying to pass the name locations in the "saveto" NSString
, but am not sure how to do so?
Originally I used:
locations =[[NSMutableArray alloc] init];
I would like to somehow pass the name of the array I wish to save to so like this?:
saveto = [[NSMutableArray alloc] init];
Example to run method:
[self downloadData:[NSString stringWithFormat:@"locations"] downloadURL:[NSString stringWithFormat:@"http://test.com:80/test/locations.php"] parameters:[NSString stringWithFormat:@"welcome=hi"]];
Upvotes: 0
Views: 138
Reputation: 438222
You haven't shown us how you're retrieving the data (synchronously or asynchronously?) nor how you're building that request (it's curious that params
and saveto
and URL
are all string parameters).
But I'd suggest doing it asynchronously (since you never want to block the main queue). And in that case, you provide a "block" parameter that the caller can specify the block of code to run when the download is done.
So, you might have downloadData
that looks something like:
- (void)downloadDataWithURL:(NSURL *)URL parameters:(NSDictionary *)parameters completion:(void (^)(NSArray *array, NSError *error))completion
{
// build your request using the URL and parameters however you want
NSURLRequest *request = ...;
// now issue the request asynchronously
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (!data) {
completion(nil, connectionError);
return;
}
NSError *parseError = nil;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
completion(array, parseError);
}];
}
And can be invoked as:
NSURL *URL = [NSURL URLWithString:@"http://test.com:80/test/locations.php"];
NSDictionary *parameters = @{@"welcome" : @"hi"};
[self downloadDataWithURL:URL parameters:parameters completion:^(NSArray *array, NSError *error) {
if (error) {
NSLog(@"downloadDataWithURL error: %@", error);
return;
}
self.locations = array;
}];
FYI, I made the URL
to be a NSURL
object (to conform to common practice). I also made the parameters
a NSDictionary
(so that if you're making a GET
request or POST
request of type application/x-www-form-urlencoded
, you can more easily do the necessary CFURLCreateStringByAddingPercentEscapes
; if it's JSON request, this also makes it easier to make a proper JSON request).
But feel free to change the parameters URL
and parameters
to be whatever type makes sense for your particular implementation, but hopefully this illustrates the idea. Add an additional completion block parameter which will be the block of code that will be run when the download is done, and then the caller do whatever it wants with the results.
Upvotes: 2
Reputation: 5845
You should not reinvent the wheel and you should use one of the frameworks like AFNetworking or RestKit to do this stuff for you. In addition to doing the work for you it gives you very powerful tools like reachability and error handling and most importantly it handles converting to and from JSON (and many other formats). When you use AFNetworking you get an NSDictionary called responseObject that you can use in many ways including setting an NSString. Most of the time you will simply use that dictionary as the dataSource for your UI so all of the work is done for you.
AFNetworking code looks like this:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
As you can see in only a couple of lines of code you handle success, failure, and the creation of an object with all your info. No need for [[NSDictionary alloc] init]
This is one of the many many great tutorials on AFNetworking
Upvotes: 1