我正在開發一個消息客戶端(如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有太多的訪問權限?
非常感謝!
我想你在主線程中工作好心在後臺線程中做這些任務,這樣上傳和下載時你的應用程序不會凍結 –