【问题标题】:Multiple downloading progress bar objective c多个下载进度条目标c
【发布时间】:2014-01-22 12:16:27
【问题描述】:

我正在开发一个消息客户端(如 Whatsapp 或 Line)。 我遇到了麻烦,因为我需要支持多个下载文件(和上传),在每条具有当前下载过程的消息中显示一个进度条。 多下载和上传过程已经开发(并且工作正常),当我尝试在消息进度栏中显示该进度时出现问题。

我的“解决方案”(不知道有没有更好的办法)是在CoreData的Message实体中添加一个“uploaded”和其他“downloaded”的字段,保存上传百分比或下载百分比,并在每次 NSURLConnection 调用时更新该字段(在上传过程中,在下载中不同):

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite

但如果我尝试在该方法中更新 CoreData 上下文,我的用户界面就会冻结。

好的,那是我的问题,我给你看代码:

  • 这是我的核心数据消息实体:

    @property (nonatomic, retain) NSString *ident;
    @property (nonatomic, retain) NSString *localId;
    @property (nonatomic, retain) NSString *body;
    @property (nonatomic, retain) NSString *contentSize;
    @property (nonatomic, retain) NSNumber *uploaded;
    @property (nonatomic, retain) NSNumber *downloaded;
    @property (nonatomic, retain) Avatar *avatar;
    @property (nonatomic, retain) Thumbnail *thumbnail;
    
  • 这是我的类来管理每个 HTTP 连接,在这里我尝试更新该实体。

    @implementation HTTPConnection
    //SOME CODE...
    - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
    {
        if (self.localId) {
            float progress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
            [self performSelectorOnMainThread:@selector(saveProgressInDatabase:) withObject:[NSNumber numberWithFloat:progress] waitUntilDone:YES];
        }
    }
    
    - (void)saveProgressInDatabase:(NSNumber *)progress
    {
        NSManagedObjectContext *context = [[[AppDelegate alloc]init]managedObjectContext];
    
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:MESSAGE_ENTITY
                                              inManagedObjectContext:context];
        [fetchRequest setEntity:entity];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"localId = %@", self.localId];
        [fetchRequest setPredicate:predicate];
    
        NSError *coreError = nil;
        NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&coreError];
    
        Message *currentMessage = [fetchedObjects objectAtIndex:0];
        [currentMessage setUploaded:progress];
    
        [context save:&coreError];
    
        [[NSNotificationCenter defaultCenter] postNotificationName:UPLOAD_UPDATED_NOTIFICATION object:self];
    }
    
  • 这里我显示消息列表并在表格视图中发送消息:

    @implementation TimelineViewController
    //SOME CODE...
    - (void)viewWillAppear:(BOOL)animated
    {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(updateTable)
                                                 name:UPLOAD_UPDATED_NOTIFICATION
                                               object:nil];
    }
    
    - (void)updateTable
    {
        NSError *error;
        [[self fetchedResultsController] performFetch:&error];
    
        if ([[_fetchedResultsController sections]count]>0) {
            [table reloadData];
    
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([table numberOfRowsInSection:[[_fetchedResultsController sections]count]-1] - 1) inSection:[[_fetchedResultsController sections]count]-1];
    
            [table scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
        }
    }
    
    //SOME CODE...
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        Message *info = [_fetchedResultsController objectAtIndexPath:indexPath];
    
        //MORE CODE...
    
        if ([info contentSize]!=NULL) {
            [cell.progressBar setHidden:NO];
            [cell.progressBar setProgress:[[info uploaded]floatValue]];
        }
    }
    
    //CODE...
    
    - (IBAction)sendMessageAction:(id)sender
    {
        CommandServices *services = [[CommandServices alloc]init];
        [services sendMessageToGroup:message withMedia:attachedMedia withLocalId:localId];
    }
    

我不知道这是否足以理解我的问题,所以我要问两个主要问题:

  1. 这是用多个进度条管理多次下载的好方法吗?我的意思是,将进度保存到实体中......或者,我该怎么做?
  2. 为什么我的应用程序在我上传或下载文件时冻结?也许我对 CoreData 的访问过多?

非常感谢!

【问题讨论】:

  • 我认为您在主线程中工作请在后台线程中执行这些任务,这样您的应用在上传和下载时不会冻结

标签: ios objective-c uitableview core-data nsurlconnection


【解决方案1】:

我的猜测是您应该使用以下代码来获取 NSManagedObjectContext:

AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [app managedObjectContext];

代替:

NSManagedObjectContext *context = [[[AppDelegate alloc]init]managedObjectContext];

【讨论】:

  • 是的,我同意你的看法。这是获取 NSManagedObjectContext 的更好方法,但这并不能解决我的问题。感谢您的帮助。
【解决方案2】:

嗯...在考虑了我的问题几天后,我意识到我进行了太多的数据库访问,因此我的应用程序冻结了。 我解决了它传递给我的 HTTPConnection 对象的问题,这是我想要管理的进度条的一个实例。我只在完成后保存进度下载/上传。

这就是我的解决方案:

在 HTTP 连接中:

+ (void)setProgressBar:(UIProgressView *)progress
{
    [downloadConnection setProgressBar:progress];
}

//CODE...

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
    float progress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
    if (self.progressBar) {
        self.progressBar.progress = progress;
    }
    if (progress == 1.0) {
        [self saveProgressInDatabase:[NSNumber numberWithFloat:progress]];
    }
}

在我的消息列表中:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    Message *info = [_fetchedResultsController objectAtIndexPath:indexPath];

    //MORE CODE...

    if (([info contentSize]!=NULL)&&([[info uploaded]floatValue]<1.0))  {
        [HTTPConnection setProgressBar:cell.progressBar];
        [cell.progressBar setHidden:NO];
    } }

感谢您的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    相关资源
    最近更新 更多