Objective c 如何在UIView标签中显示JSON数据
我在互联网上看到的每一个教程和示例都展示了如何从某个url获取JSON并在Tableview中显示它。这不是我的问题,我知道如何使用AFNetworking框架或本机API做到这一点 我的问题是,在下载JSON之后,我想在UIView标签中显示其中的一些内容。实际上,当我试图找到一种方法来解决iOS8中无法缓存的问题时,我已经成功地做到了这一点。但我没有意识到它是同步的 工厂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
+ (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的可达性方法。