7

Ich habe eine Aufgabe, mehrere Bilder einzeln auf den Server zu laden. Also verwende ich den Batch-Vorgang dafür. Jedes Mal, wenn ich die Upload-Prozedur starte, werden einige Operationen, besonders die erste abgeschlossen, sobald sie gestartet wird und das Image nicht hochgeladen wird, und dann wird der Batch-Upload-Prozess gut fortgesetzt, mit einem seltenen Fehler, die anderen Bilder zu verpassen.NSOperation Queue, die sich unnormal verhält

Der Code ich verwende ist wie folgt: -

-(void)callWSToUploadRxs{ 


    NSLog(@"the total assets maintained are %lu", (unsigned long)_arr_assetsMaintained.count); 

    NSMutableArray *mutableOperations = [NSMutableArray array]; 
    int imageUploadCount = (int)[self extractFullSizeImagesToUpload].count; 
    // second for loop is to initialize the operations and then queue them. 
    for (int i = 0; i<imageUploadCount; i++) { 


     NSData *imageData = UIImageJPEGRepresentation([_arr_originalImagesToSend objectAtIndex:i],1.0); 

     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
     [request setHTTPMethod:@"POST"]; 

     NSLog(@"the url constructed is %@", [NSString stringWithFormat:@"%@/%@/%@/%@",uploadRxUrl,@"4004DD85-1421-4992-A811-8E2F3B2E49F7",@"5293",[_arr_imageNames objectAtIndex:i]]); 
     [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@/%@/%@/%@.jpg",uploadRxUrl,@"4004DD85-1421-4992-A811-8E2F3B2E49F7",@"5293",[_arr_imageNames objectAtIndex:i]]]]; 
     [request setValue:@"binary/octet-stream" forHTTPHeaderField:@"Content-Type"]; 

     [request setHTTPBody:imageData]; 
     AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 

     [mutableOperations addObject:operation]; 
    } 

    currentUploadIndex++; 
    NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:mutableOperations progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) { 
     NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations); 

     NSIndexPath * indexOfImageTobeDeleted = [_selectedItemsIndexPaths objectAtIndex:0];//numberOfFinishedOperations-1 
     [_arr_assetsMaintained removeObjectAtIndex:indexOfImageTobeDeleted.item]; 
     [_arr_images removeObjectAtIndex:indexOfImageTobeDeleted.item]; 
     [_arr_fullSizeImages removeObjectAtIndex:indexOfImageTobeDeleted.item]; 
     [_arr_imageNames removeObjectAtIndex:indexOfImageTobeDeleted.item]; 

     if ([_arr_selectedCells containsObject:[NSString stringWithFormat:@"%ld",(long)indexOfImageTobeDeleted.item]] ) 
     { 
      [_arr_selectedCells removeObject:[NSString stringWithFormat:@"%ld",(long)indexOfImageTobeDeleted.item]]; 
      //[cell.img_selctedRxs setHidden:TRUE]; 


     } 
     countBeforeClearingAssets = countBeforeClearingAssets - 1; 
     //Reload the items of UICollectionView performBatchUpdates Block 
     [_albumImagesCollection performBatchUpdates:^{ 
      [_albumImagesCollection deleteItemsAtIndexPaths:@[indexOfImageTobeDeleted]]; 
     } completion:nil]; 

     _selectedItemsIndexPaths = [_albumImagesCollection indexPathsForSelectedItems]; 
     // [_selectedItemsIndexPaths removeObjectAtIndex:0]; 
     NSLog(@"the count of selected items after updation is %lu", (unsigned long)_selectedItemsIndexPaths.count); 


    } completionBlock:^(NSArray *operations) { 
     NSLog(@"All operations in batch complete"); 
     [self callWSToAddNoteForRxs]; 
     [_arr_originalImagesToSend removeAllObjects]; 
     [_arr_selectedCells removeAllObjects]; 
     currentUploadIndex = 0; 
     NSLog(@"the array of image names is %@",_arr_imageNames); 
    }]; 

    [[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO]; 

    // third is to maintain the progress block for each image to be uploaded one after the other. 
    for (AFHTTPRequestOperation *operation in mutableOperations){ 

     [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { 

      [_progressOverLayView setAlpha:0.7f]; 
      [_progressView setHidden:FALSE]; 
      [_progressView setProgress: totalBytesWritten*1.0f/totalBytesExpectedToWrite animated: YES]; 
      [_lbl_progressUpdate setHidden:FALSE]; 
      _lbl_progressUpdate.text = [NSString stringWithFormat:@"Image %d of %lu uploading", currentUploadIndex, mutableOperations.count]; 
      NSLog(@"Sent %lld of %lld bytes and progress is %f", totalBytesWritten, totalBytesExpectedToWrite, totalBytesWritten*1.0f/totalBytesExpectedToWrite); 
      if(totalBytesWritten >= totalBytesExpectedToWrite) 
      { 
       //progressView.hidden = YES; 
       [self setComplete]; 
      } 
     }]; 
    } 

} 

In diesem Code ist die erste Operation wird immer so schnell ausgeführt beginne ich das Hochladen der Bilder d.h nur 3 von 4 hochgeladen zu werden. Ein Bild wird immer weggelassen. Ebenfalls. Wenn ich nur ein Bild im Raster habe, wird dieses erfolgreich hochgeladen.

Danke.

+0

Hat jemand eine praktikable Lösung dafür? –

+0

Wird das Bild, das beim Upload-Vorgang nicht angezeigt wird, immer noch aus albumImagesCollection gelöscht? Und es ist auch das erste Bild, das weggelassen wird oder das letzte? – user2695712

+0

Ja, es wird weggelassen und der Completion-Block für dieses Bild wird ausgeführt, der es tatsächlich aus der Sammlungsansicht löscht. Es ist meist das erste Bild der beiden in 95% der Fälle und 2 Bilder im Falle von 4 oder mehr und so weiter. Haben Sie das Problem schon identifiziert? –

Antwort

2

Ein paar Gedanken ...

1) der Fortschritt Update-Block. Dadurch erfahren Sie nicht, welche Vorgänge abgeschlossen wurden. nur die Anzahl von ihnen, so bin ich verdächtig, dass sie möglicherweise nicht in der Reihenfolge abschließen, die der Code denkt, sie sind die ganze Zeit ....

2) der Abschlussblock dauert eine Reihe von Operationen .... I frage mich, ob dies einmal mit allen Operationen aufgerufen wird, oder mehrmals mit Arrays der Operationen, die abgeschlossen wurden? Sie können sich die Array-Länge ansehen, um zu sehen. Wenn es für Teilmengen von Operationen aufgerufen wird, ist dies der Ort, um die bereits hochgeladenen Assets zu entfernen und Bereinigungsarbeiten durchzuführen, da Sie wissen, welche Operationen beendet wurden.

3) Ich würde den Upload-Fortschrittsblock vor dem Hinzufügen der Operationen zur Warteschlange setzen; nur zur Sicherheit.

4) Ich konnte keine Dokumentation für die batchOperation-Methode finden und fragte mich, ob sie aus einer neueren Version von AFNetworking entfernt wurde - und wenn ja - vielleicht ist es eine fehlerhafte oder nicht gute API? Ich wäre versucht, meine eigenen Operationen in einer Schleife aus Gründen der Übersichtlichkeit zu erstellen. und dann eine kleine Statusverwaltung, um den Status des Stapels zu überprüfen und entsprechend zu handhaben.

5) Sie sagen, ein Bild wird immer weggelassen .... ist es stabil - immer das erste oder letzte? Verhält es sich auf dem Sim vs auf einem Zellennetz oder simulierte langsame/unzuverlässige Verbindung?

+0

lautet. 1. Er gibt an, welche Operation abgeschlossen ist: - currentUploadIndex ist die Variable. 2. Der Abschlussblock wird immer nur einmal ausgeführt, wenn alle Operationen abgeschlossen sind. 3. Wo sollte ich den Fortschrittsblock im Code behalten, wie von Ihnen vorgeschlagen? 4. Können Sie bitte einen kleinen Code für Ihren Ansatz zeigen? 5. Es ist sehr zufällig, aber verhält sich in jeder Art von Mobilfunknetz. Bitte schlagen Sie einen Ausweg vor. –