1
\$\begingroup\$

I load some data from from my webservice via a method using blocks and callbacks.

From my ViewController I make a request to the data loading class and pass the callback block:

- (void)loadRadioStationList
{
 [self.radioDataLoader getRadioStationList:^(NSArray *data, NSDictionary *dictData){
 self.alphabetizedDictionary = [[NSDictionary alloc] initWithDictionary:dictData];
 self.sectionIndexTitles = [[NSArray alloc] initWithArray:data];
 [self.radioStationTableView reloadData];
 }];
}

Then in the dataloading class the method is as so:

-(void) getRadioStationList:(void (^)(NSArray *data, NSDictionary *dictData))callback
{
 NSString *string = RadioStationListURL;
 NSURL *url = [NSURL URLWithString:string];
 NSURLRequest *request = [NSURLRequest requestWithURL:url];
 AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
 operation.responseSerializer = [AFXMLParserResponseSerializer serializer];
 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
 NSXMLParser *XMLParser = (NSXMLParser *)responseObject;
 [XMLParser setShouldProcessNamespaces:YES];
 XMLParser.delegate = self;
 [XMLParser parse];
 callback((NSArray*)self.sectionIndexTitles, (NSDictionary*)self.alphabetizedDictionary);
 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Radio List"
 message:[error localizedDescription]
 delegate:nil
 cancelButtonTitle:@"Ok"
 otherButtonTitles:nil];
 [alertView show];
 }];
 [operation start];
}

It loads the XML file and parses out the data and send the data back to my VC via the callback block.

I've a couple of questions:

  1. Is this an acceptable way of doing this? Would you prefer to see it done another (better) way?
  2. If I was to write an API, would passing the data from the API back to the calling class be a good way to work it, or is there a more suitable method for an API?
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Sep 30, 2016 at 22:35
\$\endgroup\$
0

1 Answer 1

1
+50
\$\begingroup\$

Here is a way how I do it:

Create a class and name it like ClientApi. This class should be a singleton link and be absolutely independent. Also, create a class APIRouter which will return a path for a request. I'm using the AFNetworking framework for communication with different API etc. and JSONModel framework for mapping. Here you can find the full answer about network architecture in iOS apps.

@interface SFAPIClient ()
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@end
@implementation SFAPIClient
+ (instancetype)sharedInstance
{
 static id _sharedInstance = nil;
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
 _sharedInstance = [[[self class] alloc] init];
 });
 return _sharedInstance;
}

If a request should return some data, pass block as a parameter to the method:

- (void)getAllChildsWithCompletion:(void(^)(NSArray *arr, NSError *error))completion
{
 NSString *url = [SFAPIRouter childRoute];
 [self setupRequestSerializer];
 [self.manager GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
 NSError *error = nil;
 NSArray *arr = //map respons
 if (!error)//if everything good call block with data 
 completion(arr, nil);
 else
 completion(nil, error);
 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
 {
 if (completion)
 completion(nil, error);
 }];
}

APIRouter:

static NSString * const kSFServerURL = @"http://0.0.0.0/api/v1";
@implementation SFAPIRouter
+ (NSString *)saveMediaToListRoute
{
 return [kSFServerURL stringByAppendingString:@"/childs"];
}

And then in controller call function from your ClientApi class:

//show activity indicator
[[SFAPIClient sharedInstance] getAllChildsWithCompletion:^(NSArray *arr, NSError *error){
//stop showing activity indicator
if (error)
{
//show alert
return;
}
//do what you need
}];
answered Oct 14, 2016 at 18:56
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.