有一个比代码更多的是设计考虑的问题。
我的 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
视图控制器.m
....
DCWebServiceManager *manager = [[DCWebServiceManager alloc] initWithHost:@"localhost" port:@"23312" user:@"FOO" pass:@"BAR"];
[manager getFileList];
// OUTPUTS
IN GETFILELIST: (nil)
HostToken: >>sdf5fdsfs46a6cawca6<<
....
...