-1

Я не уверен, что это вопрос с очевидным ответом, но я не смог его найти.Лучшая практика использования AFNetworking

Я использую AFNetworking для подключения к моему серверу REST. Я выполняю основную задачу, например, загружать и загружать изображения, размещать и получать json и т. Д.

Что лучше всего обновлять пользовательский интерфейс, когда что-то меняется. Например, если вы успешно загрузили изображение профиля и вам нужно изменить изображение в виде таблицы.

У меня есть только 1 класс, который использует 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 внутри классов, которые ему нужны, например класс, в котором я пытаюсь обновить свой табличный вид?

Спасибо :)

Дополнительный пример кода

-(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]; 
} 
+0

Лично я добавляю параметры блока успеха и отказа моих методов, которые делают сетевые запросы. Блок успеха обычно принимает 1 параметр (любой объект, который вы запрашиваете), и блок сбоя будет принимать объект NSError. – AdamPro13

+0

Я обновил раздел, который имеет успех и параметры блока отказов. Как будет выглядеть решение с тем, что вы предлагаете? – 4FunAndProfit

ответ

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; 
+0

Так, чтобы понять я хотел бы использовать это с моей TableView как: [апите executePostForUrl: @ "URL" словарь: DIC Сукчеса:^({ изображения = [UIImage imagenamed: @ "image.png"]; }) недостаточность :^({ [db savetolog: @ "could not executepost"]; })] ;? :) – 4FunAndProfit

+0

Когда я сделал succesfull executePostForUrl, я хотел бы вернуть экземпляр пользователя, как это сделать с помощью этого метода? Использование пользователя __block User *; а затем dispatch_async (get_main_queue, когда я достиг успеха? – 4FunAndProfit

+0

Да, вы можете сделать что-то подобное. Просто получите ссылку на свой пользовательский объект (я не уверен, как именно ваш магазин в вашем приложении), а затем передайте это объект в блок успеха – AdamPro13

Смежные вопросы