在后台下载数据的同时,从 JSON 中下载数据并存储到 CoreData 和 Display

Posted

技术标签:

【中文标题】在后台下载数据的同时,从 JSON 中下载数据并存储到 CoreData 和 Display【英文标题】:Download data from JSON and store to CoreData and Display in the same time when data downloads in background 【发布时间】:2015-04-09 07:25:41 【问题描述】:

我在将数据显示到 tableview 的同时从 JSON 解析数据并存储到 CoreData 但我遇到的问题是数据仅在下载完成后才显示但我不想这样我想下载后台数据并在处理下载时显示数据我该怎么做呢

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    arrayData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    NSError *error;
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    context = [appDelegate managedObjectContext];

    for (int i = 0; i < [arrayData count]; i++) 

        idNum = [arrayData objectAtIndex:i][@"id"];
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Discount"];
        [request setPredicate:[NSPredicate predicateWithFormat:@"cID = %@",idNum]];
        [request setFetchLimit:1];
        NSUInteger count = [context countForFetchRequest:request error:&error];
        if (count == NSNotFound) 
            NSLog(@"ERROR");
        else if (count == 0) 
            NSLog(@"New Data Coming");

            name  = [arrayData objectAtIndex:i][@"name"];
            summary = [arrayData objectAtIndex:i][@"summary"];
            region = [arrayData objectAtIndex:i][@"region"];
            imageURL = [arrayData objectAtIndex:i][@"images"][@"logo"];

            id  benefits1 = [arrayData objectAtIndex:i][@"benefits"];
            benefiteString = [NSString stringWithFormat:@"%@ %@",[benefits1 objectAtIndex:0][@"key"],[benefits1 objectAtIndex:0][@"value"]];
            NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
            dateUpdate = [arrayData objectAtIndex:i][@"updated_at"];
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
            [dateFormatter setDateFormat: @"yyyy-MM-dd'T'HH:mm:ss.sssZ"];
            NSDate *date =[dateFormatter dateFromString:dateUpdate];
            [dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
            NSLog(@"DAte : %@",date);
            Discount * d = [NSEntityDescription insertNewObjectForEntityForName:@"Discount" inManagedObjectContext:context];
            d.name = name;
            d.summary = summary;
            d.regions = region;
            d.cID = idNum;
            d.imageLogo = data;
            d.updated_at = date;
            d.benefits = benefiteString;
            if (![context save:&error]) 
                NSLog(@"Getting error while saving data");
            
            else
                NSLog(@"Saved");
            
        

    
    [sharedAppDelegate dismissGlobalHUD];
    [listTableView reloadData];


-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return [_myArray count];

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    customCellClass = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (customCellClass == nil)
    
        customCellClass = [[CellCustom alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    
    customCellClass.nameLabel.text = [[_myArray objectAtIndex:indexPath.row]name];
    customCellClass.cityLabel.text =[[_myArray objectAtIndex:indexPath.row]regions];
    customCellClass.detailLabel.text = [[_myArray objectAtIndex:indexPath.row]summary];

    NSData * d = [[_myArray objectAtIndex:indexPath.row]imageLogo];
    customCellClass.mainImage.image = [UIImage imageWithData:d];

    customCellClass.benefitsLabel.text = [[_myArray objectAtIndex:indexPath.row]benefits];
    [sharedAppDelegate dismissGlobalHUD];
    return customCellClass;


-(void)dataDidSave


    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Discount" inManagedObjectContext:context]; [fetchRequest setEntity:entity];
    [fetchRequest setEntity:entity];
    NSError *error = nil;
    NSArray *result = [context executeFetchRequest:fetchRequest error:&error];

    self.myArray = result;
    [listTableView reloadData];

-(void)viewWillAppear:(BOOL)animated

    [sharedAppDelegate showGlobalProgressHUDWithTitle:@"Loading..."];
    [self dataDidSave];

【问题讨论】:

【参考方案1】:

在 connectionDidFinishLoading 中:尝试这样的事情:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ 
   // Process your data and then incrementally call 
      dispatch_async(dispatch_get_main_queue(),^ 
           [listTableView reloadData];
      );
    
);

【讨论】:

是的,下载完成后,它正在添加到数组并显示,但是有没有一种方法必须在后台进行下载并异步显示下载 您的 connectionDidFinishLoading: 可能正在由主线程执行。您可以通过记录 [NSThread isMainThread] 来检查这一点。如果是这样,我会将 connectionDidFinishLoading: 的整个处理程序扔到后台队列中,并将您的 UI 更新从该队列中排入队列。 我没有告诉你你有这个解决方案的任何样本 查看我粘贴的示例代码。 UI 更新只能发生在主线程(线程 1)上。在 XCode 中,您可以在 connectionDidFinishLoading 上放置一个断点,您将能够看到哪个线程正在运行。很有可能您实际上是在线程 1 上运行的,这意味着 UITableView 刷新要等到该线程上的所有处理完成后才会发生。解决方案是将繁重的数据处理移至后台线程,并根据需要增量调度主线程(线程 1)以刷新表。 只需复制并将其放入 didfinishloading 中?

以上是关于在后台下载数据的同时,从 JSON 中下载数据并存储到 CoreData 和 Display的主要内容,如果未能解决你的问题,请参考以下文章

023医疗项目-模块二:药品目录的导入导出-从数据库中查出数据用XSSF导出excel并存放在虚拟目录最后下载(包括调试)

iOS Swift 在后台下载大量小文件

颤振 | Dio Package ...在后台下载大文件

完成后在后台下载并唤醒应用程序

C语言中如何从TXT文件中读出数据并存放到线性链表中

在后台下载多个文件(仅限 iOS 7)