AFNetworking 2.0 - 如何从子类 AFHTTPSessionManager 成功将响应传递给另一个类
Posted
技术标签:
【中文标题】AFNetworking 2.0 - 如何从子类 AFHTTPSessionManager 成功将响应传递给另一个类【英文标题】:AFNetworking 2.0 - how to pass response to another class on success from subclassed AFHTTPSessionManager 【发布时间】:2014-04-29 07:49:32 【问题描述】:初学者 ios AFNetworking 2.0 Qns:将 AFHTTPSessionManager 子类化为“MyAPIManager”之类的东西并将我所有的 API 调用(GET/POST/PUT 等)放在这个自定义管理器类中,我在使用响应时遇到问题在另一个类(比如B类)中请求成功。
我知道我可以重构它并将 POST 调用部分提取到 B 类,以便我可以在回调中转储相关的 B 类方法,但这会变得混乱,尤其是在多个 API 调用的情况下。
我想将此响应(例如返回的 objectId)传递给另一个类,现在我只使用 B 类监听的 NSNotification,但这仍然感觉有点“hackish”,我想知道是否有更好的方法。
目前在 MyAPIManager 中:AFHTTPSessionManager:
- (void) POSTRecordJson:(NSDictionary *)json
[self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject)
NSLog(@"Posted JSON: %@", json.description);
if ([responseObject isKindOfClass:[NSDictionary class]])
NSLog(@"Response: %@", responseObject);
//Notify objectId received
[[NSNotificationCenter defaultCenter]
postNotificationName:@"ReceivedObjectIdNotification"
object:self
userInfo:responseObject];
failure:^(NSURLSessionDataTask *task, NSError *error)
NSLog(@"Error: %@", error);
];
我在 B 类中调用了:
MyApiManager *manager = [MyApiManager sharedInstance];
[manager POSTRecordJson:someJSONdict];
【问题讨论】:
【参考方案1】:你可以做两件事..通过使用协议/委托或块..
但我个人更喜欢block soo..
先制作一个block Datatype
typedef void(^SuccessBlock)(id success);
示例
并添加带有块的参数
- (void) POSTRecordJson:(NSDictionary *)json success:(SuccessBlock)success
[self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject)
NSLog(@"Posted JSON: %@", json.description);
if ([responseObject isKindOfClass:[NSDictionary class]])
NSLog(@"Response: %@", responseObject);
//Notify objectId received
success(responseObject);
failure:^(NSURLSessionDataTask *task, NSError *error)
NSLog(@"Error: %@", error);
];
并调用新函数..
MyApiManager *manager = [MyApiManager sharedInstance];
[manager POSTRecordJson:someJSONdict success:^(id result)
NSDictionary *dictionary = (NSDictionary *)result;
NSLog(@"response: %@",dictionary)
];
【讨论】:
【参考方案2】:您可能希望将完成块传递给您的 -POSTRecordJson:
方法。
例如,您将重构您的方法以执行以下操作:
- (void) POSTRecordJson:(NSDictionary *)json completion:(void(^)(BOOL success, id response, NSError *error))completion
[self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject)
NSLog(@"Posted JSON: %@", json.description);
if ([responseObject isKindOfClass:[NSDictionary class]])
NSLog(@"Response: %@", responseObject);
if (completion) //if completion is NULL, calling it will crash your app so we always check that it is present.
completion(YES, responseObject, nil);
failure:^(NSURLSessionDataTask *task, NSError *error)
NSLog(@"Error: %@", error);
if (completion)
completion(NO, nil, error);
];
然后你可以像这样处理这个实现:
//assuming `manager` and `dictionary` exist.
[manager POSTRecordJson:dictionary completion^(BOOL success, id response, NSError *error)
if (success)
//do something with `response`
else
//do something with `error`
];
但是,如果您是 AFNetworking 的初学者,并且希望采用一种出色的结构来处理 Web 服务,您应该查看this excellent blog post.
【讨论】:
很好,也感谢您处理错误情况!如果可以的话,我会接受更多...【参考方案3】:在从服务器收到响应后,您可以使用块将响应发送回类:
- (void) POSTRecordJson:(NSDictionary *)json response:(void (^)(id response, NSError *error))responseBlock
[self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject)
NSLog(@"Posted JSON: %@", json.description);
if ([responseObject isKindOfClass:[NSDictionary class]])
NSLog(@"Response: %@", responseObject);
responseBlock(responseObject, nil);
failure:^(NSURLSessionDataTask *task, NSError *error)
NSLog(@"Error: %@", error);
responseBlock(nil, error);
];
【讨论】:
以上是关于AFNetworking 2.0 - 如何从子类 AFHTTPSessionManager 成功将响应传递给另一个类的主要内容,如果未能解决你的问题,请参考以下文章
如何从 AFnetworking 2.0 操作/NSURLSessioNDataTask 获取原始 JSON 响应?