AFNetworking回调 - 委托还是通知?

时间:2015-03-17 15:15:52

标签: ios objective-c afnetworking-2

我有一个问题,哪个是将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]];
        }
     }];

4 个答案:

答案 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,我认为通知方法更好。