我有一个问题,哪个是将AFNetworking结果发送给控制器的最佳方式或正确方法。是通过委托还是通知?
我创建了一个类来处理具有以下代码的make API调用。因此,如果将此类导入另一个控制器并调用此方法进行API调用。我应该委托还是通知?
我已阅读www.raywenderlich.com/59255/afnetworking-2-0-tutorial并且正在使用代理人。我也看过CodeSchool教程,他们使用了从Model到Controller的通知。
我添加了以下代码,希望能更好地展示我的问题。
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
// notification way inside the BLOCK
[ manager GET:path parameters:params
success:^(NSURLSessionDataTask *operation, id responseObject) {
[ [NSNotificationCenter defaultCenter] postNotificationName:notificationName
object:nil
userInfo:responseObject ];
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
[ [NSNotificationCenter defaultCenter] postNotificationName:notificationName
object:nil ];
}];
// delegate way inside the BLOCK
[ manager GET:path parameters:params
success:^(NSURLSessionDataTask *operation, id responseObject) {
if ([delegate respondsToSelector:@selector(getUserFeedsDidFinish:resultDict:)])
{
[delegate performSelector:@selector(getUserFeedsDidFinish:resultDict:) withObject:self withObject:resultDict];
}
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
if ([delegate respondsToSelector:@selector(getUserFeeds:didFailWithResultDict:)]) {
[delegate performSelector:@selector(getUserFeeds:didFailWithResultDict:)
withObject:self
withObject:[NSDictionary dictionaryWithObject:error.userInfo forKey:KEY_ERRORS]];
}
}];
答案 0 :(得分:3)
我会推荐使用积木,怎么样?我将为您编写一个服务,这个服务是在一个名为Connection:
的类中编写的+(void)requestLocation:(NSString*)googleReference completionBlock:(void (^)(NSString * coordinates, NSError * error)) handler{
NSString * urlString = @"https://maps.googleapis.com/maps/";
NSMutableDictionary * parametersDictionary = [NSMutableDictionary dictionary];
[parametersDictionary setObject:googleReference forKey:@"reference"];
[parametersDictionary setObject:@"true" forKey:@"sensor"];
[parametersDictionary setObject:@"key(it is not)" forKey:@"key"];
AFHTTPClient *HTTPClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:urlString]];
NSURLRequest *URLRequest = [HTTPClient requestWithMethod:@"GET" path:@"api/place/details/json" parameters:parametersDictionary];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:URLRequest];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError * error = nil;
NSDictionary * response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];
NSDictionary * dicGeo = [((NSDictionary*)[response objectForKey:@"result"]) objectForKey:@"geometry"];
NSDictionary * coords = [dicGeo objectForKey:@"location"];
NSNumber * lat = [coords objectForKey:@"lat"];
NSNumber * lng = [coords objectForKey:@"lng"];
NSString * coordinates = [NSString stringWithFormat:@"%@,%@", lat.description, lng.description];
handler(coordinates, error);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"%@", error);
}];
[requestOperation start];
}
然后拨打此服务:
[Connection requestLocation:@"google reference (it is not)" completionBlock:^(NSString *coordinates, NSError *error) {
//Your code with results.
}
答案 1 :(得分:0)
我只是用AFNetworking划过了表面。从我所看到的,大多数似乎使用第三种方法,块。
块有点新,与委托和通知都不同。
块是C函数指针的扩展,可以在调用时将代码传递给方法。
使用块的常见设计模式是创建一个采用完成块的方法。完成块是在异步请求完成时调用的一段代码。
以AFNewtworking方法HTTPRequestOperationWithRequest为例。该方法采用成功块,如果请求成功则调用,以及失败块,如果请求失败则调用该块。
答案 2 :(得分:0)
阻止是使用IMO的最简单方法。您不需要实现额外的委托方法,也不需要任何构造。
基本上像这样定义你的包装。
typedef void(^SampleRequestCompletion)(NSError *error, id data);
- (void)GET:(NSString *)URLString
parameters:(NSDictionary *)parameters
completion:(SampleRequestCompletion)completion
{
[self GET:URLString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Do what you want
if (completion) {
completion(nil, data);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Failure case
if (completion) {
completion(error,nil);
}
}];
}
从这样的任何对象中调用此方法,
[self GET:path parameters:dictionary completion:^(NSError *error, id data) {
}];
因此,只要通话成功或失败,您就可以管理要做的事情。
答案 3 :(得分:-1)
正如教程推荐的那样,我们可以将与Web服务相关的代码提取到一个模块中,该模块更像是一个模型级别的东西。考虑到网络模块和视图之间的通信,视图在单个Web服务客户端上调用/启动请求,一旦响应,通常的工作流将结果发送到视图控制器并在视图中显示数据。我们不需要将任何内容返回给网络模块。
因此,此工作流程更像是通知而非委托。并将V设置为M的代表,这很奇怪。
通知:嘿,伙计,我完成了我的工作,轮到你了。 代表团:嘿,伙计,我已经做了很多,现在我需要你覆盖/备份/提供一些任务,然后我将继续/完成工作。
在某些情况下,很难选择哪一个更好。对于AFNetworking,我认为通知方法更好。