Objective c 如何同步使用AFNetworking 2.0
我搜索了很多关于如何同步运行AFNetworking 2.0的示例和教程,只找到了AFNetworking 1.0的解决方案。我发现: 我的例子是:Objective c 如何同步使用AFNetworking 2.0,objective-c,synchronous,afnetworking-2,Objective C,Synchronous,Afnetworking 2,我搜索了很多关于如何同步运行AFNetworking 2.0的示例和教程,只找到了AFNetworking 1.0的解决方案。我发现: 我的例子是: - (User *)getUserWithUsername: (NSString *) username andPassword: (NSString *) password { NSDictionary *params = @{@"email": username, @"password": password}; [[DCA
- (User *)getUserWithUsername: (NSString *) username andPassword: (NSString *) password {
NSDictionary *params = @{@"email": username, @"password": password};
[[DCAPIClient sharedClient] POST:@"login" parameters:params success:^(NSURLSessionDataTask * __unused task, id JSONResult) {
NSLog(@"JSON %@", JSONResult);
BOOL errorCode = [JSONResult objectForKey:@"error"];
if (!errorCode) {
self.username = [JSONResult objectForKey:@"name"];
// Fill the attributes
// self.email = .. a
} else {
// error with login show alert
}
} failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
NSLog(@"error %@", error);
}];
// this does not work
//[[[DCAPIClient sharedClient] operationQueue] waitUntilAllOperationsAreFinished];
if (self.username == nil) {
return nil;
}
return self;
}
但这不起作用,因为首先调用if(self.username==nil)
如何让AFNetworking 2.0 lib同步运行以返回响应
DCAPIClient:AFHTTPSessionManager
+ (instancetype)sharedClient {
static DCAPIClient *_sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedClient = [[DCAPIClient alloc] initWithBaseURL:[NSURL URLWithString:DCAPIBaseURLString]];
_sharedClient.responseSerializer = [AFJSONResponseSerializer serializer];
});
return _sharedClient;
}
我不知道为什么要这样做,但一个解决方案是使用回调块。大概是这样的:
- (void)getUserWithUsername: (NSString *) username andPassword: (NSString *) password success:(void (^)(User *user))success failure:(void (^)(NSError *error))failure
{
NSDictionary *params = @{@"email": username, @"password": password};
__weak __typeof(self)weakSelf = self;
[[DCAPIClient sharedClient] POST:@"login" parameters:params success:^(NSURLSessionDataTask * __unused task, id JSONResult) {
BOOL errorCode = [JSONResult objectForKey:@"error"];
if (!errorCode) {
weakSelf.username = [JSONResult objectForKey:@"name"];
if (weakSelf.username == nil) {
failure(nil);
}else{
success(weakSelf)
}
} else {
failure(nil);
}
} failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
failure(error);
}];
}
您不应该使一个固有的异步方法同步,而是使您的调用站点也异步 也就是说,您的方法变为异步,并提供一个完成处理程序:
- (void) userWithUsername:(NSString *)username
password:(NSString *)password
completion:(completion_handler_t)completion;
其中,completion\u handler\t
是一个类型定义,可以在头文件中声明如下:
typedef void (^completion_handler_t)(User*, NSError*);
请注意,使用typedef
是可选的,可能会使代码更易于理解
然后您可以按如下方式使用它:
[self userWithUsername:username
password:password
completion:^(User* user, NSError*error){
// Check error; do something with user
...
}];
您可以按如下所示实现它:
- (void) userWithUsername:(NSString *)username
password:(NSString *)password
completion:(completion_handler_t)completion
{
NSDictionary *params = @{@"email": username, @"password": password};
[[DCAPIClient sharedClient] POST:@"login" parameters:params
success:^(NSURLSessionDataTask * __unused task, id JSONResult) {
NSLog(@"JSON %@", JSONResult);
BOOL errorCode = [JSONResult objectForKey:@"error"];
if (!errorCode) {
self.username = [JSONResult objectForKey:@"name"];
// Fill the attributes
// self.email = .. a
if (completion) {
completion(theUser, nil); // completion(self, nil)??
}
} else {
if (completion) {
completion(nil, error);
}
}
} failure:^(NSURLSessionDataTask *__unused task, NSError *error) {
if (completion) {
completion(nil, error);
}
}];
}
讨厌的人会讨厌,但有时你只是希望你的HTTP调用是同步的
为此,你可以使用图书馆。它使用诸如
syncGET
和syncPOST
等同步方法为AFHTTPRequestOperationManager
添加了一个方便的类别,这些同步方法在内部使用AFNetworking的waituntlfinished
来实现同步调用。I get编译器错误:completion:(completion\u handler\u t)预计一年内完成type@Bernard您可能没有定义完成处理程序\t
类型。我编辑了我的答案,其中包括类型定义。请注意,typedef
是某种别名,通常是实际类型的更可读版本。typedef进入头文件。有目的地,它就在类定义之上,类定义声明了使用该类型的公共方法。还请注意,任何使用阻塞调用的“同步”程序都可以仅使用异步调用异步实现。一旦您熟悉了异步编程习惯用法,它通常不会比同步风格更“困难”。)如果你想学习这个技巧并释放它的力量,这取决于你:)@CouchDeveloper请参考我答案的第一句话,关键词是“有时”。