Search code examples
iosobjective-cxcodeafnetworking

AFNetworking Upload multiple files in sequence


I want to upload files sequentially. To be uploaded to the server one, then the second and so on. When I run the following code, all the files seem to be loaded at once. In addition, I can not track the progress in MBHudProgress.

Can I somehow make it so that I get a response from the file loader that the previous file is loaded and can I load the next one?

for (id item in imagesArray) {
    NSLog(@"item %@", item);
    NSData *imageData =  UIImagePNGRepresentation(item);

    NSString *urlUpload = @"https://domain/api/wp-json/wp/v2/media?access_token=";
    urlUpload = [urlUpload stringByAppendingString:[Lockbox unarchiveObjectForKey:@"access_token"]];


    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.mode = MBProgressHUDModeAnnularDeterminate;
    hud.label.text = @"Uploaded photo";


    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:urlUpload parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData:imageData name:@"file" fileName:@"filename.png" mimeType:@"image/png"];
    } error:nil];

    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

    NSURLSessionUploadTask *uploadTask;
    uploadTask = [manager
                  uploadTaskWithStreamedRequest:request
                  progress:^(NSProgress * _Nonnull uploadProgress) {

                      dispatch_async(dispatch_get_main_queue(), ^{

                          hud.progress = uploadProgress.fractionCompleted;
                      });
                  }
                  completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                      [hud hideAnimated:YES];


                      if (error) {
                          NSLog(@"Error: %@", error);
                      } else {
                          NSLog(@"%@ %@", response, responseObject);







                              if ([responseObject objectForKey:@"id"] == nil ||
                                  [[responseObject objectForKey:@"id"] isEqual:[NSNull null]] ||
                                  [responseObject objectForKey:@"id"] == [NSNull null]) {
                                  NSLog(@"NO ID %@", responseObject);
                              } else {
                                  NSLog(@"ID: %@", [responseObject objectForKey:@"id"]);
                                  NSLog(@"source_url: %@", [responseObject objectForKey:@"source_url"]);
                              }






                      }
                  }];

    [uploadTask resume];

}

Solution

  • As I understand, you want to upload image one by one. After first image is uploaded, start upload next image.

    In my opinion, you can use recursive in this case. Take a look at my code below.

    // Use recursive to upload an array items
    - (void)startUploadItems:(NSMutableArray*)items {
      if (items.count < 1) {
        return;
      }
    
      [self startUploadItem:items[0] completion:^(BOOL success) {
        [items removeObjectAtIndex:0];
    
        [self startUploadItems:items];
      }];
    }
    
    // Use to upload a single item.
    - (void)startUploadItem:(id)item completion:(void(^)(BOOL success))completion {
      NSLog(@"item %@", item);
      NSData *imageData =  UIImagePNGRepresentation(item);
    
      NSString *urlUpload = @"https://domain/api/wp-json/wp/v2/media?access_token=";
      urlUpload = [urlUpload stringByAppendingString:[Lockbox unarchiveObjectForKey:@"access_token"]];
    
    
      MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
      hud.mode = MBProgressHUDModeAnnularDeterminate;
      hud.label.text = @"Uploaded photo";
    
    
      NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:urlUpload parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileData:imageData name:@"file" fileName:@"filename.png" mimeType:@"image/png"];
      } error:nil];
    
      AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    
      NSURLSessionUploadTask *uploadTask;
      uploadTask = [manager
                    uploadTaskWithStreamedRequest:request
                    progress:^(NSProgress * _Nonnull uploadProgress) {
    
                      dispatch_async(dispatch_get_main_queue(), ^{
    
                        hud.progress = uploadProgress.fractionCompleted;
                      });
                    }
                    completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                      [hud hideAnimated:YES];
    
    
                      if (error) {
                        NSLog(@"Error: %@", error);
                      } else {
                        NSLog(@"%@ %@", response, responseObject);
    
                        if ([responseObject objectForKey:@"id"] == nil ||
                            [[responseObject objectForKey:@"id"] isEqual:[NSNull null]] ||
                            [responseObject objectForKey:@"id"] == [NSNull null]) {
                          NSLog(@"NO ID %@", responseObject);
                        } else {
                          NSLog(@"ID: %@", [responseObject objectForKey:@"id"]);
                          NSLog(@"source_url: %@", [responseObject objectForKey:@"source_url"]);
                        }
                      }
    
                      if (completion) {
                        completion(!error);
                      }
                    }];
    
      [uploadTask resume];
    }
    

    Usage:

    [self startUploadItems:imagesArray];