AFNetworking 2.0 - How to pass response to another

2019-06-14 03:34发布

问题:

I am wondering how can I call AFHTTPSessionManagern from different class. Currently I use this code to get the response but I am not sure how to convert this to singleton class which requires parameters and postback link. I am receiving and processing JSON code only.

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];
}];

回答1:

You can use the Delegation approach.

Create a separate class (Sync.h and Sync.m) which only contains above code of creating AFHTTPSessionManager, Parameters and starting the connection. Create delegate method in this class. Now from your other class(mainController), create a object of above class and sync.delegate = self. Once you receive repsonse/error. Delegate to the defined methods which are implemented in mainController.

Below is the example: 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
}


回答2:

You can use NSNotificationCenter and pass the response via that. This has the added bonus that multiple classes can be listening at the same time. If the data affects UI, it gives them the opportunity to update accordingly.

[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];
}];

Add an observer for the notification name, and the data will be contained in notification.object, which if it failed would be nil