AFNetworking 2.0 - Как передать ответ другому классу в случае успеха

Мне интересно, как я могу вызвать AFHTTPSessionManagern из другого класса. В настоящее время я использую этот код для получения ответа, но я не уверен, как преобразовать его в одноэлементный класс, для которого требуются параметры и ссылка обратной передачи. Я получаю и обрабатываю только код JSON.

static NSString * const BaseURLString = @"http://www.example.com/";
NSURL *baseURL = [NSURL URLWithString:BaseURLString];

NSDictionary *parameters = @{ @"Token" : @"123456"};

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

[manager GET:@"/list-21.aspx?" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
    self.someDictionary = responseObject[@"User"];
    [self.tableView reloadData];

} failure:^(NSURLSessionDataTask *task, NSError *error) {
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Films"
                                                        message:[error localizedDescription]
                                                       delegate:nil
                                              cancelButtonTitle:@"Ok"
                                              otherButtonTitles:nil];
    [alertView show];
}];

person GuyWhoReadsStockoverflow    schedule 20.11.2014    source источник


Ответы (2)


Вы можете использовать подход делегирования.

Создайте отдельный класс (Sync.h и Sync.m), который содержит только приведенный выше код создания AFHTTPSessionManager, параметров и запуска соединения. Создайте метод делегата в этом классе. Теперь из вашего другого класса (mainController) создайте объект вышеуказанного класса и sync.delegate = self. Как только вы получите ответ/ошибку. Делегируйте определенные методы, которые реализованы в mainController.

Ниже приведен пример: SyncManager.h

#import <UIKit/UIKit.h>
@protocol SyncDelegate<NSObject>

-(void)syncSuccess:(id) responseObject;
-(void)syncFailure:(NSError*) error;

@end

@interface SyncManager: UIViewController
{
}

-(void) serviceCall:(NSString*)url withParams:(NSDictionary*) params;
@end

SyncManager.m

@interface SyncManager ()

@end

@implementation SyncManager 

-(void) serviceCall:(NSString*)url withParams:(NSDictionary*) params {
    NSURL *baseURL = [NSURL URLWithString:url];
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
    [manager GET:@"/list-21.aspx?" parameters:parameters success:^(NSURLSessionDataTask *task, id      responseObject) {
        [self.delegate syncSuccess:responseObject];
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        [self.delegate syncFailure:error];
    }];
}
@end

ViewController.m

-(void)fetchdata {
    NSDictionary *dictionary = @{@"name":@"Arun"};
    SyncManager *sync = [[SyncManager alloc] init];
    sync.delegate = self;
    [sync serviceCall:@"www.google.com" withparams:dictionary]; 
}

-(void)syncSuccess:(id) responseObject {
    // Parse your data
}

-(void)syncFailure:(NSError*) error {
    //display Error
}
person Arun Gupta    schedule 20.11.2014
comment
Гу спасибо за ответ, не могли бы вы привести пример делегата. Также могу ли я поставить все вызовы API для AFNetworking, поэтому у меня может быть более одного метода? - person GuyWhoReadsStockoverflow; 20.11.2014
comment
добавил пример выше - person Arun Gupta; 20.11.2014
comment
Привет, спасибо, например. Я пробовал это, но получаю сообщение об ошибке в строке self.delgate о том, что делегат свойства не найден для типа объекта SyncManager. - person GuyWhoReadsStockoverflow; 21.11.2014
comment
Упустил одну вещь. Вам также необходимо импортировать делегата в viewControllerClass. Ниже приведена строка для того же. В файле ViewController.h в строке ниже добавьте своего делегата в ‹› скобках @interface ViewController: UIViewController‹SyncDelegate› - person Arun Gupta; 21.11.2014
comment
@ArunGupta я получаю сообщение об ошибке, что свойство «делегат» не найдено для типа объекта SyncManager в этой строке в Sync Manager.m --› [self.delegate syncSuccess:responseObject]; Пожалуйста, предложите мне - person ChenSmile; 18.04.2015
comment
Можете ли вы показать нам свой код как класса syncManager, так и vieecontroller, откуда вы его вызываете. - person Arun Gupta; 18.04.2015
comment
@ArunGupta я пробовал то же, что и ты сказал мне в твоем ответе, но получаю ошибку. Пожалуйста, скажи мне, как я могу использовать метод делегата в классе, основанном на afnetworking - person ChenSmile; 20.04.2015
comment
@ArunGupta, не могли бы вы ответить мне. где я делаю ошибку - person ChenSmile; 20.04.2015
comment
Получил проблему. Добавьте строку ниже непосредственно перед методом getJsonData @property(nonatomic,weak) id ‹SyncDelegate› делегата; Извините, я тоже пропустил это в своем примере :( - person Arun Gupta; 20.04.2015
comment
Дайте мне знать, если будут поражены. - person Arun Gupta; 24.04.2015

Вы можете использовать NSNotificationCenter и передать ответ через него. У этого есть дополнительный бонус в том, что несколько классов могут слушать одновременно. Если данные влияют на пользовательский интерфейс, это дает им возможность соответствующим образом обновиться.

[manager GET:@"/list-21.aspx?" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
    self.someDictionary = responseObject[@"User"];
    [self.tableView reloadData];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"USER_DATA_ARRIVED" object:responseObject[@"User"]];

} failure:^(NSURLSessionDataTask *task, NSError *error) {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"USER_DATA_ARRIVED" object:nil];

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Films"
                                                    message:[error localizedDescription]
                                                   delegate:nil
                                          cancelButtonTitle:@"Ok"
                                          otherButtonTitles:nil];
    [alertView show];
}];

Добавьте наблюдателя для имени уведомления, и данные будут содержаться в notification.object, что в случае сбоя будет нулевым.

person Flexicoder    schedule 20.11.2014
comment
Хорошо, это имеет смысл, хотя большая часть данных не будет меняться так быстро, чтобы требовать мгновенного изменения/перезагрузки. Мой вопрос был больше связан с созданием одноэлементного класса, в котором я могу хранить все вызовы API и использовать их в любом классе контроллера. - person GuyWhoReadsStockoverflow; 20.11.2014
comment
Тогда, возможно, это был вопрос, который вы должны были задать;) Этот подход все еще можно использовать в синглтоне, как я их использую. Мои ViewControllers добавляют наблюдателей для любых вызовов, которые его интересуют - person Flexicoder; 21.11.2014
comment
Я сделал, и никто не ответил на вопрос, поэтому я перефразировал его - person GuyWhoReadsStockoverflow; 21.11.2014