Having a problem that relates more to design than to code.
My iOS apps with json web interface. I use AFNetworking, and my problem is mostly I need the init function (which authenticates the AFHTTPClient and retrieves the token) in order to finish completely before I make additional requests (which require the specified token).
From the code below, I would be interested to hear design approaches to achieve this, I would prefer to save all async requests, an alternative solution would be to make a request in initWithHost: port: user: pass synous (without using AFNetworking), which I know is bad practice and you want to avoid.
DCWebServiceManager.h
#import <Foundation/Foundation.h> #import "AFHTTPClient.h" @interface DCWebServiceManager : NSObject { NSString *hostServer; NSString *hostPort; NSString *hostUser; NSString *hostPass; NSString *hostToken; AFHTTPClient *httpClient; } // Designated Initialiser - (id)initWithHost:(NSString *)host port:(NSString *)port user:(NSString *)user pass:(NSString *)pass; // Instance Methods - (void)getFileList; @end
DCWebServiceManager.m
#import "DCWebServiceManager.h" #import "AFHTTPClient.h" #import "AFHTTPRequestOperation.h" #import "AFJSONRequestOperation.h" @implementation DCWebServiceManager - (id)initWithHost:(NSString *)host port:(NSString *)port user:(NSString *)user pass:(NSString *)pass { self = [super init]; if (self) { hostServer = host; hostPort = port; hostUser = user; hostPass = pass; NSString *apiPath = [NSString stringWithFormat:@"http://%@:%@/", hostServer, hostPort]; httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:apiPath]]; [httpClient setAuthorizationHeaderWithUsername:hostUser password:hostPass]; NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:@"authenticate.php" parameters:nil]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject){ // Do operations to parse request token to be used in // all requests going forward... // ... // ... // Results in setting: hostToken = '<PARSED_TOKEN>' NSLog(@"HostToken: >>%@<<", hostToken); } failure:^(AFHTTPRequestOperation *operation, NSError *error){ NSLog(@"ERROR: %@", operation.responseString); }]; [operation start]; } return self; } - (void)getFileList { // ************************* // The issue is here, getFileList gets called before the hostToken is retrieved.. // Make the authenticate request in initWithHost:port:user:pass a synchronous request perhaps?? // ************************* NSLog(@"IN GETFILELIST: %@", hostToken); // Results in host token being nil!!! NSString *queryString = [NSString stringWithFormat:@"?list&token=%s", hostToken]; NSMutableURLRequest *listRequest = [httpClient requestWithMethod:@"GET" path:queryString parameters:nil]; AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:listRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){ NSLog(@"SUCCESS!"); } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){ NSLog(@"ERROR!: %@", error); }]; [operation start]; } @end
ViewController.m
.... DCWebServiceManager *manager = [[DCWebServiceManager alloc] initWithHost:@"localhost" port:@"23312" user:@"FOO" pass:@"BAR"]; [manager getFileList]; // OUTPUTS IN GETFILELIST: (nil) HostToken: >>sdf5fdsfs46a6cawca6<< .... ...
source share