使用AFNetworking的最佳做法

时间:2016-05-01 22:18:57

标签: ios delegates afnetworking objective-c-blocks nsnotificationcenter

我不确定这是一个有明显答案的问题,但我找不到任何问题。

我正在使用AFNetworking连接我的REST服务器。 我正在做基本的任务,比如上传和下载图片,发布和获取json等等。

在某些事情发生变化时更新用户界面的最佳做法是什么。例如,如果已成功下载配置文件图片并需要更改tableview内的图像。

我只有一个使用AFNetworking我的APIConnector的课程

APIConnector.h

@interface APIConnector : NSObject

-(void)downloadClientImageToSystem:(NSString *)imageURL;

@end

APIConnector.m
-(void)downloadClientImageToSystem:(NSString *)imageURL{
    //setup
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

    //Set url
    NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@",backendURL,imageURL]];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    //Create a download task
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {

        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        NSString *filename = [NSString stringWithFormat:@"%@.jpeg",[[imageURL componentsSeparatedByString:@"&imgIndex="] lastObject]];
        return [documentsDirectoryURL URLByAppendingPathComponent:filename];

    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error)
    {
        if (error) {
            NSLog(@"there was an error downloading profile image");
            [[NSNotificationCenter defaultCenter] postNotificationName:DLImageFail object:self];
        }
        else{
            NSLog(@"File downloaded to: %@", filePath);
            [[NSNotificationCenter defaultCenter] postNotificationName:DLImageSucces object:self];
        }
    }];

    [downloadTask resume];
}

正如您所看到的,目前正在使用NSNotificationCenter,但这是最佳解决方案吗?我一直在阅读有关代表和块的内容,而这一切似乎都很松散。我应该在需要它的类中实现AFNetworking,比如我尝试更新tableview的类吗?

谢谢:)

额外代码示例

-(void)executePostForURL:(NSString *)url dictionary:(NSDictionary *)dict success:(SuccessBlock)success failure:(FailureBlock)failure{
    [httpManager POST:url parameters:dict progress:nil
              success:^(NSURLSessionDataTask  * _Nonnull task, id  _Nullable responseObject) {
                  //somehow i need to return [responseObject valueForKey:@"updateLabelString"];
              }
              failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

              }];
}

我正试图在viewdidload中调用它。这当然只是伪代码而不起作用,我如何将[responseObject valueForKey @“updateLabelString”]值解析为我的labelToUpdate.text?

-(void)viewDidLoad{
    NSDictionary *dicToSendToServer;
    UILabel *labelToUpdate = @"temp text";

    [apicon executePostForURL:@"serverurl" dictionary:dicToSendToServer success:^(NSString *test){
        labelToUpdate.text = test;
    }failure:nil];
}

1 个答案:

答案 0 :(得分:4)

我会这样声明:

- (void)executePostForURL:(NSString *)url dictionary:(NSDictionary *)dict success:(void (^)(id objectYouRequested))success failure:(void (^)(NSError *error))failure;

我还想使用typedef来避免某些块语法。我通常定义以下内容:

typedef void (^SuccessBlock)(id result);
typedef void (^MySubclassedObjectSuccessBlock)(SubclassedObject *object);
typedef void (^FailureBlock)(NSError *error);

然后将上面的方法声明简化为:

- (void)executePostForURL:(NSString *)url dictionary:(NSDictionary *)dict success:(SuccessBlock)success failure:(FailureBlock)failure;