Objective-C:如何从 POST 方法返回响应?
Posted
技术标签:
【中文标题】Objective-C:如何从 POST 方法返回响应?【英文标题】:Objective-C: How to return response from POST method? 【发布时间】:2014-11-16 04:43:20 【问题描述】:我有一个POST
方法,看起来像
+ (id) post
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
id response = nil;
[manager POST:@"https://mapp.com/oauth/register"
parameters:@@"email" : @"e", @"memberExternalId" : @"m"
success:^(AFHTTPRequestOperation *operation, id responseObject)
response = responseObject;
failure:^(AFHTTPRequestOperation *operation, NSError *error)
// (todo) alert on failure
NSLog(@"Error: %@", error);
];
return response;
我想抽象出这个方法以便我可以重用它,所以我创建了id response
。
但是当我分配时
response = responseObject;
我得到编译错误
Variable is declared outside the block and is not assignable
问题
我怎样才能保留response
以便我以后可以返回它。
【问题讨论】:
修改块内的变量时必须使用__block说明符 @gabbler 是的,如果这是一个同步方法,那将是正确的。但事实并非如此,所以从这个函数返回值的整个想法是行不通的。他应该使用完成处理程序模式(很像POST
方法本身)。
【参考方案1】:
您正在调用使用完成块模式的异步方法,因此您应该这样做。所以
将返回类型改为void
;
将块参数添加到您的方法中;
在POST
完成块中,如果提供了completionHandler
,请调用它;
因此:
+ (void) postWithCompletionHandler:(void (^)(id responseObject, NSError *error))completionHandler
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
// these lines not needed
//
// [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
// manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
[manager POST:@"https://mapp.com/oauth/register"
parameters:@@"email" : @"e", @"memberExternalId" : @"m"
success:^(AFHTTPRequestOperation *operation, id responseObject)
if (completionHandler)
completionHandler(responseObject, nil);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
if (completionHandler)
completionHandler(nil, error);
];
因此,您可以这样称呼它:
[MyClass postWithCompletionHandler:^(id responseObject, NSError *error)
if (!responseObject)
NSLog(@"failed: %@", error);
return;
// use the `responseObject` here
];
// Note, because the above is asynchronous, don't try to use `responseObject` here.
// You can only use it inside the above `completionHandler` block.
顺便说一句,您可能不想为每个请求都实例化一个新的AFHTTPRequestOperationManager
。所以我个人 (a) 将 AFHTTPRequestOperationManager
设为此类的属性; (b) 将操作管理器的实例化移动到类的一些初始化方法中; (c) 使这个“执行请求”方法成为实例方法,而不是类方法。它在这里不是那么重要,但是当您考虑将来发出许多请求的功能时,在所有地方实例化新的请求操作管理器是低效的。
【讨论】:
如果call B
依赖于call A
等,如何建模synchronistic
行为?是completionHandler
?是首选方式吗?我很困惑,因为代码变得非常嵌套且难以理解
是的,这是首选方式。如果您发现由于所有这些嵌套而使您的代码变得笨拙,那么请进行功能分解,将嵌套代码移动到您将从完成块调用的自己的方法中。虽然您可以考虑其他技术来使这个固有的异步过程以同步方式运行(例如信号量)或在不同任务/操作之间建立依赖关系(例如调度组通知或操作队列依赖关系),恕我直言,不建议使用这些方法。跨度>
以上是关于Objective-C:如何从 POST 方法返回响应?的主要内容,如果未能解决你的问题,请参考以下文章
如何从Objective-C中的异步内部函数内部返回外部函数
如何从Objective-C中的异步内部函数内部返回外部函数
从 Objective-C 中的 ColdFusion 布尔返回类型获取 BOOL 的更好方法?
从 Objective-C 到 Swift 的 Swift 传递块