【问题标题】:Parse JSON response with AFNetworking使用 AFNetworking 解析 JSON 响应
【发布时间】:2014-03-24 14:36:21
【问题描述】:

我在 Objective-C 中使用AFNetworking 设置了一个 JSON 帖子,并正在使用以下代码将数据发送到服务器:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"name": deviceName, @"model": modelName, @"pin": pin};
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:@"Content-Type" forHTTPHeaderField:@"application/json"];
[manager POST:@"SENSORED_OUT_URL" parameters:parameters

success:^(AFHTTPRequestOperation *operation, id responseObject)
{
    NSLog(@"JSON: %@", responseObject);
}

failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
    NSLog(@"Error: %@", error);
}];

我正在通过同一请求接收信息,并希望将数据发送到NSString。我将如何使用AFNetworking 来做到这一点?

【问题讨论】:

  • 我认为您在 setValue:forHTTPHeaderField 调用中将“Content-Type”和“application/json”颠倒了

标签: ios objective-c json xcode5 afnetworking


【解决方案1】:

responseObject 是 NSArray 或 NSDictionary。您可以在运行时使用isKindOfClass: 进行检查:

if ([responseObject isKindOfClass:[NSArray class]]) {
    NSArray *responseArray = responseObject;
    /* do something with responseArray */
} else if ([responseObject isKindOfClass:[NSDictionary class]]) {
    NSDictionary *responseDict = responseObject;
    /* do something with responseDict */
}

如果您确实需要 JSON 的字符串,可以通过查看 operation.responseString 来获得。

【讨论】:

  • 如何访问操作对象?在 AFNetworking 3.0 中。
【解决方案2】:

在这种情况下,当 Web 服务以 JSON 响应时,AFNetworking 将为您进行序列化,responseObject 很可能是 NSArrayNSDictionary 对象。

这样的对象应该比带有JSON 内容的字符串更有用。

【讨论】:

  • 嘿 - AFNetworking 已经在 responseObject.responseString 中提供了字符串。您的答案会起作用,但无需再次解析 NSData 对象:)
  • 嘿@Aaron,感谢您指出这一点,我很傻。我终于要睡了:)
  • 伙计,我太愚蠢了。也许是啤酒,也许是因为我主要是一名 Android 开发人员,但谢谢。
【解决方案3】:

在我的情况下,它看起来像(也许它可以帮助)

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:url parameters:params
      success:^(AFHTTPRequestOperation *operation, id responseObject) {
          NSDictionary *jsonDict = (NSDictionary *) responseObject;
          //!!! here is answer (parsed from mapped JSON: {"result":"STRING"}) ->
          NSString *res = [NSString stringWithFormat:@"%@", [jsonDict objectForKey:@"result"]];
      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          //....
      }
 ];

还可以检查响应对象的类型(例如 https://stackoverflow.com/a/21962445/3628317 答案)

【讨论】:

    【解决方案4】:

    我发现像这样子类化 AFHTTPClient 效果最好:

    //  MyHTTPClient.h
    
    #import <AFNetworking/AFHTTPClient.h>
    
    @interface MyHTTPClient : AFHTTPClient
    
    + (instancetype)sharedClient;
    
    @end
    
    //  MyHTTPClient.m
    
    #import "MyHTTPClient.h"
    
    #import <AFNetworking/AFJSONRequestOperation.h>
    
    static NSString *kBaseUrl = @"http://api.blah.com/yada/v1/";
    
    @implementation MyHTTPClient
    
    + (instancetype)sharedClient {
        static id instance;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[self alloc] init];
        });
        return instance;
    }
    
    - (id)init {
        if (self = [super initWithBaseURL:[NSURL URLWithString:kBaseUrl]]) {
            self.parameterEncoding = AFJSONParameterEncoding;
    
            [self setDefaultHeader:@"Accept" value:@"application/json"]; // So AFJSONRequestOperation becomes eligible for requests.
            [self registerHTTPOperationClass:[AFJSONRequestOperation class]]; // So that it gets used for postPath etc.
        }
        return self;
    }
    
    @end
    

    重要的一点是:

    • 设置“接受”以使 AFJSONRequestOperation 符合条件。
    • 将 AFJSONRequestOperation 添加到 http 操作类。

    那么你可以这样使用它:

    #import "MyHTTPClient.h"
    
    @implementation UserService
    
    + (void)createUserWithEmail:(NSString *)email completion:(CreateUserCompletion)completion {
        NSDictionary *params = @{@"email": email};
        [[MyHTTPClient sharedClient] postPath:@"user" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
            completion([responseObject[@"userId"] intValue], YES);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            completion(0, NO);
        }];
    }
    
    @end
    

    这样做的好处在于,您的 responseObject 会自动为您将 JSON 解析为字典(或数组)。很干净。

    (这是用于 afnetworking 1.x)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 2017-02-28
      相关资源
      最近更新 更多