user3109249
user3109249

Reputation:

upload picked image in objective-c

I'm new to objective-c. I need the image picked in the first function to be uploaded in the second one:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
    self.imageView.image = chosenImage;

    [picker dismissViewControllerAnimated:YES completion:NULL];

}

- (IBAction)uploadPic:(UIButton *)sender {
    // COnvert Image to NSData
    NSData *dataImage = UIImageJPEGRepresentation([UIImage imageNamed:@"yourImage"], 1.0f);

//added after editing

    // set your URL Where to Upload Image
    NSString *urlString = @"http://url";

    // set your Image Name
    NSString *filename = @"uploaded_file";

    // Create 'POST' MutableRequest with Data and Other Image Attachment.
    NSMutableURLRequest* request= [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];
    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
    NSMutableData *postbody = [NSMutableData data];
    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@.jpg\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    [postbody appendData:[NSData dataWithData:dataImage]];
    [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:postbody];

    // Get Response of Your Request
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
    NSLog(@"Response  %@",responseString);
//end editing
    }

The added code, in btween editing comments, is the one that I use to upload the image

Upvotes: 1

Views: 1934

Answers (3)

Rob
Rob

Reputation: 437382

You should use neither UIImageJPEGRepresentation nor UIImagePNGRepresentation. Those will lose the image's meta-data, make the file larger (or if you choose a JPEG compression factor to make the NSData smaller, it will degrade the image), etc.

I'd suggest that you save the UIImagePickerControllerReferenceURL and, then, when the user chooses to save the image, that you go back to the Photos framework and retrieve the underlying NSData of the image.

So, make sure to import the Photos framework:

@import Photos;

Also, define a property to capture the URL:

@property (nonatomic, strong) NSURL *imageReferenceURL;

And then capture this URL when you get the image:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
    self.imageView.image = chosenImage;
    self.imageReferenceURL = info[UIImagePickerControllerReferenceURL];

    [picker dismissViewControllerAnimated:YES completion:nil];
}

And when you go to upload the picture, retrieve the original asset's NSData from the Photos framework:

- (IBAction)uploadPic:(UIButton *)sender {
    PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[self.imageReferenceURL] options:nil];
    PHAsset *asset = [result firstObject];
    if (asset) {
        PHImageManager *manager = [PHImageManager defaultManager];
        [manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
            // insert your code for uploading here, referencing the `imageData` here rather than `dataImage`.

            // Or, I might recommend AFNetworking:
            //
            // For example, if your web service was expecting a `multipart/form-data` POST and was
            // going to return a JSON response, you could do something like:

            NSString *urlString = @"http://192.168.0.10/udazz/2.0/2.2/ios/1.0/actions.php?targ=user&subTarg=post&txtComment=123456&txtType=ff";
            NSDictionary *parameters = @{@"targ"       : @"user",
                                         @"subTarg"    : @"post",
                                         @"txtComment" : @"123456",
                                         @"txtType"    : @"ff"};

            NSURL *fileURL     = info[@"PHImageFileURLKey"];
            NSString *filename = [fileURL lastPathComponent];
            NSString *mimeType = [self mimeTypeForPath:filename];

            AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
            // manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // if response is string rather than JSON, uncomment this line 
            [manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                [formData appendPartWithFileData:imageData name:@"userfile" fileName:filename mimeType:mimeType];
            } success:^(NSURLSessionDataTask *task, id responseObject) {
                NSLog(@"responseObject = %@", responseObject);
            } failure:^(NSURLSessionDataTask *task, NSError *error) {
                NSLog(@"error = %@", error);
            }];
        }];
    }
}

Or, if you want to use your own upload code, just adjust it to use NSURLSession (because NSURLConnection is now deprecated and you should never do synchronous network requests, anyway):

- (IBAction)uploadPic:(UIButton *)sender {
    PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:@[self.imageReferenceURL] options:nil];
    PHAsset *asset = [result firstObject];
    if (asset) {
        PHImageManager *manager = [PHImageManager defaultManager];
        [manager requestImageDataForAsset:asset options:nil resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
            // upload the `imageData`

            NSURL *fileURL = info[@"PHImageFileURLKey"];
            NSString *filename = [fileURL lastPathComponent];
            NSString *mimeType = [self mimeTypeForPath:filename];

            NSString *urlString = @"http://192.168.0.10/udazz/2.0/2.2/ios/1.0/actions.php?targ=user&subTarg=post&txtComment=123456&txtType=ff";

            NSMutableURLRequest* request= [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
            [request setHTTPMethod:@"POST"];
            NSString *boundary = @"---------------------------14737809831466499882746641449";
            NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
            [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
            NSMutableData *postbody = [NSMutableData data];
            [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
            [postbody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
            [postbody appendData:imageData];
            [postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

            NSURLSessionTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:postbody completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                NSLog(@"Response  %@",responseString);
            }];
            [task resume];
        }];
    }
}

By the way, my routine for programmatically determining the mime-type (because you really can't just assume the image is a JPEG; it could be a PNG, amongst other types, too) is as follows:

- (NSString *)mimeTypeForPath:(NSString *)path {
    // get a mime type for an extension using MobileCoreServices.framework

    CFStringRef extension = (__bridge CFStringRef)[path pathExtension];
    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL);
    assert(UTI != NULL);

    NSString *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType));
    assert(mimetype != NULL);

    CFRelease(UTI);

    return mimetype;
}

If you need to support iOS versions that predate the Photos framework, then use the ALAssetsLibrary to get the NSData. If you need example of how to do that (only if you need to support iOS versions before 8.0), let me know.

Upvotes: 2

Karishma
Karishma

Reputation: 11

I have done your requirement in my demo project. I have picked image using UIIMagePicker delegate function

@interface ViewController ()
{
    UIImage *chooseImage;
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSDate *time = [NSDate date];
    NSDateFormatter* df = [NSDateFormatter new];
    [df setDateFormat:@"ddMMyyyy-hhmmss"];
    NSString *timeString = [df stringFromDate:time];
   NSString *fileName = [NSString stringWithFormat:@"%@", timeString];
    
    chooseImage = info[UIImagePickerControllerEditedImage];
    

    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    documentsDirectoryPath = [paths objectAtIndex:0];
    
    NSLog(@"View Controller Path:%@",documentsDirectoryPath);
    
    
    savedImagePath = [documentsDirectoryPath
                      stringByAppendingPathComponent:[NSString stringWithFormat: @"%@-%d.png", fileName, num]];
    
    num += 1;
    
    NSData *imageData = UIImagePNGRepresentation(chooseImage);
    [imageData writeToFile:savedImagePath atomically:NO];
    
    
    [picker dismissViewControllerAnimated:YES completion:NULL];
    [self displayImage];
    
   }

-(void)displayImage
{
    self.imageView.image = chooseImage;
}

and from that method i have called another function->displayImage, which i am using for displaying image in UIImageView. Here below is code.

Upvotes: 0

Midhun MP
Midhun MP

Reputation: 107121

You are assigning the picked image to your imageView. So you can access it using the image property of that UIImageView.

You can access like:

- (IBAction)uploadPic:(UIButton *)sender
{
    NSData *dataImage = UIImageJPEGRepresentation(self.imageView.image, 1.0f);
    // Do your stuff here
}

Upvotes: 0

Related Questions