【问题标题】:Parsing JSON with AFHTTPClient使用 AFHTTPClient 解析 JSON
【发布时间】:2013-03-22 20:22:41
【问题描述】:

我正在使用 AFNetworking 库通过 AFHTTPClient 解析 json。我可以验证 json 是否在客户端块中被解析,并将该数据发送到我的 json 模型。但是,当我尝试从块外部访问 json 模型时,我没有得到任何数据。如何将解析的 json 数据传递给 json 模型,然后在应用程序的其他地方访问该模型数据?

AFHTTPClient 子类/单例:

#import <Foundation/Foundation.h>
#import "AFHTTPClient.h"

@interface JsonClient : AFHTTPClient

+ (JsonClient *)sharedClient;

@end

#import "JsonClient.h"
#import "AFJSONRequestOperation.h"

static NSString *const kJsonBaseURLString = @"https://alpha-api.app.net/";

@implementation JsonClient

+ (JsonClient *)sharedClient {
    static JsonClient *_sharedClient = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedClient = [[JsonClient alloc] initWithBaseURL:[NSURL URLWithString:kJsonBaseURLString]];
    });

    return _sharedClient;
}

- (id)initWithBaseURL:(NSURL *)url {
    self = [super initWithBaseURL:url];

    if (!self) {
        return nil;
    }

    [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [self setDefaultHeader:@"Accept" value:@"application/json"];

    return self;
}

@end

JSON 模型数据:

#import <Foundation/Foundation.h>

@interface TheJson : NSObject

@property (nonatomic, copy) NSString *createdAt;
@property (nonatomic, copy) NSString *userText;

- (id)initWithDictionary:(NSDictionary *)dict;

@end

#import "TheJson.h"

@implementation TheJson

- (id)initWithDictionary:(NSDictionary *)dict {
    self = [super init];

    if (self) {
        self.createdAt = [dict objectForKey:@"created_at"];
        self.userText = [dict objectForKey:@"text"];
    }

    return self;
}

@end

ViewController 更新用户界面:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

#import "ViewController.h"
#import "JsonClient.h"
#import "TheJson.h"

@interface ViewController ()

@property (weak) IBOutlet UILabel *createdLabel;
@property (weak) IBOutlet UILabel *textLabel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (IBAction)fetchJsonData:(id)sender {

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

    [[JsonClient sharedClient] getPath:@"stream/0/posts/stream/global" parameters:nil
                               success:^(AFHTTPRequestOperation *operation, id JSON) {
                                   NSArray *postsFromResponse = [JSON valueForKeyPath:@"data"];
                                   NSDictionary *dictFromArray = postsFromResponse[0];

                                   TheJson *jsonObject = [[TheJson alloc] initWithDictionary:dictFromArray];
                                   NSLog(@"createdAt is %@", jsonObject.createdAt);
                                   NSLog(@"text from user is %@", jsonObject.userText);

                                   [self updateInterface];
                                   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

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

- (void)updateInterface {
    TheJson *thejson;
    [_createdLabel setText:thejson.createdAt];
    [_textLabel setText:thejson.userText];
}

@end

【问题讨论】:

    标签: objective-c json nsdictionary objective-c-blocks afnetworking


    【解决方案1】:

    您还没有将新的 jsonObject 从块中传递出去,也没有将它存储在任何地方。一个短期的答案是声明updateInterface 将jsonObject 作为参数。

    所以你的updateInterface 变成updateInterface: 是这样的:

    - (void)updateInterface:(TheJson*)thejson {
        [_createdLabel setText:thejson.createdAt];
        [_textLabel setText:thejson.userText];
    }
    

    ...然后在你的块中,你这样调用这个方法:

    [self updateInterface:jsonObject];
    

    从长远来看,如果您的应用包含许多此类对象和/或需要在任意时间保留它们,您可能需要考虑在下载它们时如何存储和组织这些对象。

    【讨论】:

    • 您介意发布一些示例代码吗?我从看到人们谈论的例子中学到最好的东西。谢谢。
    • 是的,我刚刚添加了一个将对象直接传递给您的 updateInterface: 方法的示例。希望对您有所帮助。
    • 在 json 模型中创建一个委托并使用它将数据传递给视图控制器怎么样?
    • 你可以。对于这类事情,听起来比必要的复杂吗?也许你可以举一个例子来说明你的意思。
    • 我只是想知道。我现在会坚持你的方法。如果它不符合我的需求,我可以随时发布另一个问题。感谢您的帮助!
    猜你喜欢
    • 2012-07-07
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 2013-06-24
    • 2018-09-12
    相关资源
    最近更新 更多