コードよりも設計上の考慮事項である問題がある。
私の iOS アプリは、json Web サービスとインターフェイスします。私は AFNetworking を使用していますが、私の問題は基本的に、追加の要求 (上記のトークンを必要とする) を行う前に、init 関数 (AFHTTPClient を認証してトークンを取得する) を完全に完了する必要があることです。
以下のコードから、これを達成するための設計アプローチを聞くことに興味があります。すべてのリクエストを非同期に保つことをお勧めします。別の解決策は、リクエストを initWithHost:port:user:pass 同期 (AFNetworking を使用しない) にすることです。悪い習慣であることを認識しており、避けたいと思っています。
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<<
....
...