2017-04-09 1 views
0

Ich habe eine iPad App, wo ich eine Liste von Bildern und eine Fortschrittsbalkenaktualisierungen herunterladen, wie die Bilder heruntergeladen werden. Ich kann nicht scheinen, dass die Fortschrittsbalken und Bild-Downloads übereinstimmen. Der Fortschrittsbalken wird immer beendet, bevor die Bilder heruntergeladen werden. Ich habe eine Methode UpdateProgressBar, die den Fortschrittsbalken jedes Mal erhöhen sollte, wenn ein Bild heruntergeladen wird.Progress Bar Updates nicht synchron mit Bild-Downloads

-(void)DownloadPhoto{ 
    NSMutableArray *failedDownloads = [[NSMutableArray alloc]init]; 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
     listPhoto = [CoreDataRead GetPhotoList:[self selectedAccountGuid]]; 
     dispatch_group_t downloadGroup = dispatch_group_create(); 
     for (Photo *item in listPhoto) { 
      NSString *imageName = item.photoName; 
      NSString *myURL = [NSString stringWithFormat:@"%@%@", @"http://acimagedownload.com/photos/", imageName]; 
      NSURL  *url  = [NSURL URLWithString:myURL]; 
      NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

      dispatch_group_enter(downloadGroup); 
      [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 

      if (connectionError == nil && data != nil) 
      { 
       if (data != nil) 
       { 
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsDirectory = [paths objectAtIndex:0]; 
        NSString* path = [documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:@"%@%@",item.guid, @".png"]]; 

         [data writeToFile:path atomically:YES]; 
         NSLog(@"Photo Downloaded %@!", @""); 
        } 
        else 
        { 
         NSLog(@"image is not downloaded"); 
        } 
       } 
       else if (connectionError != nil) 
       { 
        [failedDownloads addObject:myURL]; 
        NSLog(@"Error %@",[connectionError description]); 
       } 
       else 
       { 
        [failedDownloads addObject:myURL]; 
        NSLog(@"Image Download Failed %@!", @""); 
       } 
       dispatch_group_leave(downloadGroup); 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        [self UpdateProgressBar]; 
       }); 
      }]; 
      dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER); 
     } 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self DownloadVideo]; 
     }); 
    }); 
} 

-(void)UpdateProgressBar{ 
    currentTask = currentTask + 1; 
    NSLog(@"Current Task %@!", [@(currentTask) stringValue]); 
    float progressPercentage = (float)currentTask/(float)taskCount; 
    [self.progressBar setProgress:progressPercentage animated:YES]; 
    if(currentTask == taskCount){ 
     [self ShowDoneAlert]; 
    } 
} 
+0

'NSURLConnection'' sendAsynchronousRequest' war in iOS 9 veraltet. (In der Tat war fast jeder Teil von NSURLConnection veraltet.) Es ist nicht ratsam, neue Entwicklungen mit APIs zu machen, die vor zwei großen OS-Versionen veraltet waren. Ich schlage vor, den Code mit 'NSURLSession' neu zu schreiben. –

+0

Der Code in UpdateProgressBar scheint ein angemessener Teil dieser Frage. – danh

+0

Ich habe den UpdateProgressBar-Code hinzugefügt. –

Antwort

0

Es ist schwer, ohne zu sehen, die updateProgressBar Methode zu sagen, warum Sie dieses Verhalten bekommen, aber eine Sache, die mir aufgefallen ist, dass Ihr dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER); innerhalb der Schleife ist.

Also, was passiert ist, gehen Sie in die erste Iteration der Schleife und am Ende davon, stoppt die Thread-Ausführung und wartet auf die erste dispatch_group_leave. Danach geht es weiter zur nächsten Iteration und so weiter.

Wenn dies das gewünschte Verhalten ist (aber ich bezweifle es, ich denke, dass Sie eigentlich möchten, dass Ihre Downloads parallel ausgeführt werden) sollten Sie wahrscheinlich eine dispatch_semaphore_t oder sogar eine serielle Warteschlange verwenden.

+0

Ich möchte, dass sie nacheinander laufen. Ich ließ sie parallel laufen und ich hatte Probleme. –

+0

Ich habe das Problem gefunden. Die Zählung war falsch. Sobald ich die Zählung korrigiert hatte, funktionierte es richtig. –

+0

Irgendwelche Tipps zu einer Download-Strategie? Ich kann zwischen 0 bis 150 Bilder herunterladen. Zwei zur Zeit? Ich stelle mir vor, dass 150 Threads, die gleichzeitig Bilder herunterladen, keine gute Idee wären. –