我正在开发一个消息客户端(如Whatsapp或Line)。 我在麻烦,因为我需要支持多下载文件(和上传),显示进度条到每个消息有当前的下载过程。 多下载和上传过程已经开发(并且工作正常),当我尝试向消息进度条显示进度时,问题就出现了。多个下载进度条目标c
我的“解决方案” (我不知道是否有更好的方式来做到这一点)是增加一个字段“上传”等“下载”到CoreData消息实体,它保存上传百分比或者下载百分比,并更新该字段每个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]; }
我不知道这是否是不够了解我的问题,所以我我会问两个主要问题:
- 这是一个很好的方式来管理与多个进度条的多重下载吗?我的意思是,将进展存入实体......或者,我该怎么做?
- 为什么我上传或下载文件时,我的应用程序冻结?也许我对CoreData有太多的访问权限?
非常感谢!
我想你在主线程中工作好心在后台线程中做这些任务,这样上传和下载时你的应用程序不会冻结 –