Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何在UIView标签中显示JSON数据_Objective C_Json_Ios7_Uiview_Afnetworking 2 - Fatal编程技术网

Objective c 如何在UIView标签中显示JSON数据

Objective c 如何在UIView标签中显示JSON数据,objective-c,json,ios7,uiview,afnetworking-2,Objective C,Json,Ios7,Uiview,Afnetworking 2,我在互联网上看到的每一个教程和示例都展示了如何从某个url获取JSON并在Tableview中显示它。这不是我的问题,我知道如何使用AFNetworking框架或本机API做到这一点 我的问题是,在下载JSON之后,我想在UIView标签中显示其中的一些内容。实际上,当我试图找到一种方法来解决iOS8中无法缓存的问题时,我已经成功地做到了这一点。但我没有意识到它是同步的 工厂 + (Factory *)responseJson { static Factory *shared = nil

我在互联网上看到的每一个教程和示例都展示了如何从某个url获取JSON并在Tableview中显示它。这不是我的问题,我知道如何使用AFNetworking框架或本机API做到这一点

我的问题是,在下载JSON之后,我想在UIView标签中显示其中的一些内容。实际上,当我试图找到一种方法来解决iOS8中无法缓存的问题时,我已经成功地做到了这一点。但我没有意识到它是同步的

工厂

+ (Factory *)responseJson
{
    static Factory *shared = nil;

    shared = [[Factory alloc] init];

    NSHTTPURLResponse *response = nil;
    NSString *jsonUrlString = [NSString stringWithFormat:@"http://urltojson.com/file.json"];
    NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSError *error = nil;

    NSURLRequest *request = [NSURLRequest requestWithURL:url
                                             cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                         timeoutInterval:10.0];
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if (error) {
       NSLog(@"error");
    } else {
        //-- JSON Parsing
        NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
        //NSLog(@"Result = %@",result);
        shared.responseJson = result;
    }

    return shared;
}
+(Factory *)sharedFactory {
    static Factory *sharedFactory = nil;
    dispatch_once_t onceToken;
    dispatch_once(&onceToken, {
        sharedFactory = [[Factory alloc] init];
    });
}

-(void)fetchDataInBackgroundWithCompletionHandler:(void(^)(NSURLResponse *response, 
                                                           NSData *data, 
                                                           NSError *error)
                                                           completion {
    NSHTTPURLResponse *response = nil;
    NSString *jsonUrlString = [NSString stringWithFormat:@"http://urltojson.com/file.json"];
    NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSURLRequest *request = [NSURLRequest requestWithURL:url
                                             cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                         timeoutInterval:10.0];

    NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:request 
                                       queue:downloadQueue 
                           completionHandler:completion];
}
我的问题是,有没有可能使用网络来做同样的事情?我是否缺少一些在TableView中需要调用的方法

[self.tableView reloadData]; 
我想使用这个框架,因为我需要检查可达性,它似乎已经实现了

按要求编辑以显示更多代码

ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self factoryLoad];
    [self setupView];
}
- (void)factoryLoad
{
    Factory *shared = [Factory responseJson];
    self.titles = [shared.responseJson valueForKeyPath:@"data.title"];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.collectionView reloadData];

    });
}

- (void)setupView
{
    self.issueTitleLabel.text = [self.titles objectAtIndex:0];
}
-(void)factoryLoad {
    [[Factory sharedFactory] fetchDataInBackgroundWithCompletionHandler:^(void)(NSURLResponse *response, NSData *data, NSError *error){
        if(!error) {
            NSError *error2;
            NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error2];

            if(error2){ /* handle error */ }

            self.titles = [serializedData valueForKeyPath:@"data.title"];
            [Factory sharedFactory].responseJSON = serializedData;
        }
        else {
            // handle error
        }
    }];
}

你发布的代码中有几个奇怪的地方

Factory看起来是一个单例类,应该在dispatch_中实例化一次,以确保线程安全。 在ViewController.m中,您在主线程上调用factoryLoad,随后在主线程上调用sendSynchronousRequest。警告不要在主线程上调用此函数,因为它会阻塞线程,使应用程序对用户输入无响应。 您不应在NSJSONSerialization JSONObjectWithData:中将nil作为错误参数传递。 在您的情况下,我建议将数据的获取与单例对象的构造分开

工厂

+ (Factory *)responseJson
{
    static Factory *shared = nil;

    shared = [[Factory alloc] init];

    NSHTTPURLResponse *response = nil;
    NSString *jsonUrlString = [NSString stringWithFormat:@"http://urltojson.com/file.json"];
    NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    NSError *error = nil;

    NSURLRequest *request = [NSURLRequest requestWithURL:url
                                             cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                         timeoutInterval:10.0];
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if (error) {
       NSLog(@"error");
    } else {
        //-- JSON Parsing
        NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
        //NSLog(@"Result = %@",result);
        shared.responseJson = result;
    }

    return shared;
}
+(Factory *)sharedFactory {
    static Factory *sharedFactory = nil;
    dispatch_once_t onceToken;
    dispatch_once(&onceToken, {
        sharedFactory = [[Factory alloc] init];
    });
}

-(void)fetchDataInBackgroundWithCompletionHandler:(void(^)(NSURLResponse *response, 
                                                           NSData *data, 
                                                           NSError *error)
                                                           completion {
    NSHTTPURLResponse *response = nil;
    NSString *jsonUrlString = [NSString stringWithFormat:@"http://urltojson.com/file.json"];
    NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSURLRequest *request = [NSURLRequest requestWithURL:url
                                             cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                         timeoutInterval:10.0];

    NSOperationQueue *downloadQueue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:request 
                                       queue:downloadQueue 
                           completionHandler:completion];
}
现在,您应该能够创建对数据的引用,并保证下载请求已完成,因此数据将存在

ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self factoryLoad];
    [self setupView];
}
- (void)factoryLoad
{
    Factory *shared = [Factory responseJson];
    self.titles = [shared.responseJson valueForKeyPath:@"data.title"];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.collectionView reloadData];

    });
}

- (void)setupView
{
    self.issueTitleLabel.text = [self.titles objectAtIndex:0];
}
-(void)factoryLoad {
    [[Factory sharedFactory] fetchDataInBackgroundWithCompletionHandler:^(void)(NSURLResponse *response, NSData *data, NSError *error){
        if(!error) {
            NSError *error2;
            NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error2];

            if(error2){ /* handle error */ }

            self.titles = [serializedData valueForKeyPath:@"data.title"];
            [Factory sharedFactory].responseJSON = serializedData;
        }
        else {
            // handle error
        }
    }];
}

这将保证在您尝试访问任何下载的信息之前,下载已完成。然而,我在这里留下了一些东西,包括任何类型的活动指示器,向用户显示应用程序正在后台做一些重要的事情。剩下的,嗯,留给读者作为练习。

好的,我对Morgan Chen的答案以及如何阻止进行了更深入的调查

示例代码进行了一些修改,但我认为它可以正常工作,是更好的代码

在工厂里

在ViewController.m中,我在viewDidLoad上调用此方法


那么,您尝试在哪里将数据放入标签?在viewDidLoad中。对于异步获取方法,我尝试过将获取方法放入ViewWillDisplay并在viewDidLoad中设置所有标签,但没有成功。您能否编辑问题并显示用于设置标签文本的代码?如果异步获取数据并在完成处理程序外部设置标签文本,则可能试图将文本设置为一个实际不存在的值,因为数据尚未获取。在收到数据之前,您不能使用该数据。我理解这一点。我想我会将网络代码保存在ViewController中。是的,我知道在主线程上进行同步调用是不好的,但在这种情况下,我只在应用程序启动时获取一次数据并将其缓存,因此它不会真正阻止任何内容。无论如何,这段代码并没有真正帮助我,因为我试图实现AFNetworking的可达性方法。