Uploading image from gallery with AFNetworking 3.0

By : Ricardo
Source: Stackoverflow.com
Question!

I checked the code example to upload images via multipart. But I don't know how get the @"file://path/to/image.jpg" value.

This is what I tried:

-(void) uploadAvatar:(NSString*)file
success:(void (^)())success failure:(void (^)())failure {


    NSString* url = [NSString stringWithFormat:@"%@%@%@", res, kApiRest, kApiServiceAvatar];
    //NSString* filepath = [NSString stringWithFormat:@"%@%@", res, kApiRest];



    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileURL:[NSURL fileURLWithPath:file] name:@"file" fileName:@"image.jpg" mimeType:@"image/*" error:nil];
    } error:nil];

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

    NSURLSessionUploadTask *uploadTask;
    uploadTask = [self.manager
                  uploadTaskWithStreamedRequest:request
                  progress:^(NSProgress * _Nonnull uploadProgress) {
                      // This is not called back on the main queue.
                      // You are responsible for dispatching to the main queue for UI updates
                      dispatch_async(dispatch_get_main_queue(), ^{
                          //Update the progress view
//                          [progressView setProgress:uploadProgress.fractionCompleted];
                      });
                  }
                  completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                      if (error) {
                          NSLog(@"Error: %@", error);
                          failure();

                      } else {
                          NSLog(@"%@ %@", response, responseObject);
                          success();
                      }
                  }];

    [uploadTask resume];
}


#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [self dismissViewControllerAnimated:YES completion:nil];

    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
    UIImage *imageToUse;

    // Imagen
    if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) {
        imageToUse = (UIImage *) [info objectForKey: UIImagePickerControllerEditedImage];
        imageToUse = [imageToUse scaleToMaxWidth:kAvatarSize];


        NSData* fileHD = UIImagePNGRepresentation(imageToUse);
        APIAvatar* api = [[APIAvatar alloc] initWithUser:_user.jid password:_user.pass];
        //I have the NSData object fileHD, how can I get the path?
        [api uploadAvatar:[fileHD ] success:<#^(void)success#> failure:<#^(void)failure#>]
    } 
}
By : Ricardo


Answers

Try this solution

-(void) uploadAvatar:(NSData*)fileData
success:(void (^)())success failure:(void (^)())failure {


    NSString* url = [NSString stringWithFormat:@"%@%@%@", res, kApiRest, kApiServiceAvatar];
    //NSString* filepath = [NSString stringWithFormat:@"%@%@", res, kApiRest];



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

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

    NSURLSessionUploadTask *uploadTask;
    uploadTask = [self.manager
                  uploadTaskWithStreamedRequest:request
                  progress:^(NSProgress * _Nonnull uploadProgress) {
                      // This is not called back on the main queue.
                      // You are responsible for dispatching to the main queue for UI updates
                      dispatch_async(dispatch_get_main_queue(), ^{
                          //Update the progress view
//                          [progressView setProgress:uploadProgress.fractionCompleted];
                      });
                  }
                  completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                      if (error) {
                          NSLog(@"Error: %@", error);
                          failure();

                      } else {
                          NSLog(@"%@ %@", response, responseObject);
                          success();
                      }
                  }];

    [uploadTask resume];
}


#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [self dismissViewControllerAnimated:YES completion:nil];

    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
    UIImage *imageToUse;

    // Imagen
    if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) {
        imageToUse = (UIImage *) [info objectForKey: UIImagePickerControllerEditedImage];
        imageToUse = [imageToUse scaleToMaxWidth:kAvatarSize];


        NSData* fileHD = UIImagePNGRepresentation(imageToUse);
        APIAvatar* api = [[APIAvatar alloc] initWithUser:_user.jid password:_user.pass];
        //I have the NSData object fileHD, how can I get the path?
        [api uploadAvatar: fileHD success:<#^(void)success#> failure:<#^(void)failure#>]
    } 
}

Update

If you want set headers, manager's headers are ignored. Instead they should be set on request object.

[request setValue:@"myheader1" forHTTPHeaderField:@"key1"];
[request setValue:@"myheader2" forHTTPHeaderField:@"key2"];
By : Rajatp


In my experience when the build stays greyed out and (processing) for longer than a few minutes it will stay forever like that. Best to just re-upload and wait for the new build to process. It does take a bit of time to show up for testing though.



This has happened to me a few times already i.e. when a binary doesn't finish processing due to connection drop or other issues (on apple side).

Just upload a new build and use that build for release or test flight. Don't worry about the build that never finishes. Just ignore it and move on.

If you are still seeing build 2 as the latest under testfligth section, then logout, clear your browser cache, log back in and see. Clearly your build 3 is the latest one. itunesconnect is super flaky.

Use apple support as a last resort. They will take days to solve something as simple as this.

By : Sam B


This video can help you solving your question :)
By: admin