AFNetworking 2.0 - 如何从子类 AFHTTPSessionManager 成功将响应传递给另一个类

Posted

技术标签:

【中文标题】AFNetworking 2.0 - 如何从子类 AFHTTPSessionManager 成功将响应传递给另一个类【英文标题】:AFNetworking 2.0 - how to pass response to another class on success from subclassed AFHTTPSessionManager 【发布时间】:2014-04-29 07:49:32 【问题描述】:

初学者 ios AFNetworking 2.0 Qns:将 AFHTTPSessionManager 子类化为“MyAPIManager”之类的东西并将我所有的 API 调用(GET/POST/PUT 等)放在这个自定义管理器类中,我在使用响应时遇到问题在另一个类(比如B类)中请求成功。

我知道我可以重构它并将 POST 调用部分提取到 B 类,以便我可以在回调中转储相关的 B 类方法,但这会变得混乱,尤其是在多个 API 调用的情况下。

我想将此响应(例如返回的 objectId)传递给另一个类,现在我只使用 B 类监听的 NSNotification,但这仍然感觉有点“hackish”,我想知道是否有更好的方法。

目前在 MyAPIManager 中:AFHTTPSessionManager:

- (void) POSTRecordJson:(NSDictionary *)json

[self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject) 
    NSLog(@"Posted JSON: %@", json.description);
    if ([responseObject isKindOfClass:[NSDictionary class]]) 
        NSLog(@"Response: %@", responseObject);
        //Notify objectId received
        [[NSNotificationCenter defaultCenter]
         postNotificationName:@"ReceivedObjectIdNotification"
         object:self
         userInfo:responseObject];
    
 failure:^(NSURLSessionDataTask *task, NSError *error) 
    NSLog(@"Error: %@", error);
];

我在 B 类中调用了:

MyApiManager *manager = [MyApiManager sharedInstance];
[manager POSTRecordJson:someJSONdict];

【问题讨论】:

【参考方案1】:

你可以做两件事..通过使用协议/委托或块..

但我个人更喜欢block soo..

先制作一个block Datatype

typedef void(^SuccessBlock)(id success); 示例

并添加带有块的参数

- (void) POSTRecordJson:(NSDictionary *)json success:(SuccessBlock)success

[self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject) 
    NSLog(@"Posted JSON: %@", json.description);
    if ([responseObject isKindOfClass:[NSDictionary class]]) 
        NSLog(@"Response: %@", responseObject);
        //Notify objectId received
        success(responseObject);

    
 failure:^(NSURLSessionDataTask *task, NSError *error) 
    NSLog(@"Error: %@", error);
];

并调用新函数..

MyApiManager *manager = [MyApiManager sharedInstance];
[manager POSTRecordJson:someJSONdict success:^(id result)
    NSDictionary *dictionary = (NSDictionary *)result;
    NSLog(@"response: %@",dictionary)
];

【讨论】:

【参考方案2】:

您可能希望将完成块传递给您的 -POSTRecordJson: 方法。

例如,您将重构您的方法以执行以下操作:

- (void) POSTRecordJson:(NSDictionary *)json completion:(void(^)(BOOL success, id response, NSError *error))completion

    [self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject) 

        NSLog(@"Posted JSON: %@", json.description);
        if ([responseObject isKindOfClass:[NSDictionary class]])
        
            NSLog(@"Response: %@", responseObject);

            if (completion) //if completion is NULL, calling it will crash your app so we always check that it is present.
            
                completion(YES, responseObject, nil);
            
        
     failure:^(NSURLSessionDataTask *task, NSError *error) 

        NSLog(@"Error: %@", error);

        if (completion)
        
            completion(NO, nil, error);
        

    ];

然后你可以像这样处理这个实现:

//assuming `manager` and `dictionary` exist.

[manager POSTRecordJson:dictionary completion^(BOOL success, id response, NSError *error) 

    if (success)
    
        //do something with `response`
    
    else
    
        //do something with `error`
    

];

但是,如果您是 AFNetworking 的初学者,并且希望采用一种出色的结构来处理 Web 服务,您应该查看this excellent blog post.

【讨论】:

很好,也感谢您处理错误情况!如果可以的话,我会接受更多...【参考方案3】:

在从服务器收到响应后,您可以使用块将响应发送回类:

- (void) POSTRecordJson:(NSDictionary *)json response:(void (^)(id response, NSError *error))responseBlock
    
    [self POST:@"classes/Record/" parameters:json success:^(NSURLSessionDataTask *task, id responseObject) 
        NSLog(@"Posted JSON: %@", json.description);
        if ([responseObject isKindOfClass:[NSDictionary class]]) 
            NSLog(@"Response: %@", responseObject);
           responseBlock(responseObject, nil);
        
     failure:^(NSURLSessionDataTask *task, NSError *error) 
        NSLog(@"Error: %@", error);
         responseBlock(nil, error);
    ];
    

【讨论】:

以上是关于AFNetworking 2.0 - 如何从子类 AFHTTPSessionManager 成功将响应传递给另一个类的主要内容,如果未能解决你的问题,请参考以下文章

如何从 AFnetworking 2.0 操作/NSURLSessioNDataTask 获取原始 JSON 响应?

AFNetworking 2.0 和请求标头

AFNetworking 2.0 - 强制缓存

AFNetworking 2.0 多部分请求正文空白

使用 AFNetworking 2.0 的 POST 请求 - AFHTTPSessionManager

通过 Afnetworking 2.0 从 URL 获取一半大小的 UIImage