I'm fairly new to Objective-C. The app I'm trying to make, is using the foursquare API to list up places that is close by. I've re-written this app more times than I care to admit, because I feel the implementation get messier the bigger the app gets. I take that as a sign that my basic code structure is in need of some improvement.
I'm trying to let my models handle all my data. Here is the main model:
- (instancetype)initVenueServiceWithClientID:(NSString *)clientID clientSecret:(NSString *)clientSecret { if (self = [super init]) { _clientID = clientID; _clientSecret = clientSecret; _name = @"name"; _pluralName = @"pluralName"; _categories = @"categories"; _identifier = @"id"; _location = @"location"; _radius = @"2000"; _requestString = @{@"venueCategories" : @"https://api.foursquare.com/v2/venues/categories?client_id=%@&client_secret=%@&v=%@", @"venueBasedOnLocation" : @"https://api.foursquare.com/v2/venues/search?ll=%f,%f&radius=%@&categoryId=%@&client_id=%@&client_secret=%@&v=%@", @"venueImageURLs" : @"https://api.foursquare.com/v2/venues/%@?client_id=%@&client_secret=%@&v=%@"}; NSDate *date = [NSDate date]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyMMdd"]; _todaysDate = [formatter stringFromDate:date]; } return self; } - (NSURLRequest *)URLRequestWithFormat:(NSString *)attributes, ... { va_list arguments; va_start(arguments, attributes); NSString *urlPath = [[NSString alloc] initWithFormat:_requestString[attributes] arguments:arguments]; va_end(arguments); NSURL *url = [NSURL URLWithString:urlPath]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; return request; } - (void)performRequest:(NSURLRequest *)request withKeyPath:(NSString *)keyPath completion:(TNVenueServiceCompletionBlock)completion { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ NSError *error; NSURLResponse *response; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; _venueData = [responseDictionary valueForKeyPath:keyPath]; if (!error) { completion(_venueData, nil); } else { completion(nil, error); } }); } And the model where I store the categories I get from my JSON request:
- (instancetype)initCategoriesWithIdentifier:(NSString *)identifier pluralName:(NSString *)pluralName categories:(NSString *)categories { if (self = [super init]) { _identifier = identifier; _pluralName = pluralName; _categories = categories; } return self; } The implementation in my viewController then looks something like this:
_venueService = [[TNVenueService alloc] initVenueServiceWithClientID:@"MY_CLIENT_ID" clientSecret:@"MY_CLIENT_SECRET"]; NSURLRequest *request = [_venueService URLRequestWithFormat:@"venueCategories", _venueService.clientID, _venueService.clientSecret, _venueService.todaysDate]; [_venueService performRequest:request withKeyPath:@"response.categories" completion:^(NSArray *array, NSError *error) { if (!error) { NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:[array count]]; for (NSDictionary *data in array) { TNVenueCategories *category = [[TNVenueCategories alloc] initCategoriesWithIdentifier:data[_venueService.identifier] pluralName:data[_venueService.pluralName] categories:data[_venueService.categories]]; [tempArray addObject:category]; } _storedCategories = [NSArray arrayWithArray:tempArray]; dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); } }]; Sure, this works. But am I on the right track? What could I do differently to make it better?