After user choose image from the iPhone library with UIImagePickerController
, I want to upload it to my server using ASIHTTPRequest
library.
I know that with ASIHTTPRequest
I can upload a file with the file's URl, but how do I get the image URL?
I know I can get the image UIImagePickerControllerReferenceURL
, that look like this:
"assets-library://asset/asset.JPG?id=F2829B2E-6C6B-4569-932E-7DB03FBF7763&ext=JPG"
is this the URL I need to use?
There are lots of answers that suggest UIImageJPEGRepresentation or UIImagePNGRepresentation. But these solutions will convert the original file while this question is actually about saving the file AS IS.
It looks like uploading the file directly from assets library is impossible. But it can be accessed using PHImageManager to get the actual image data. Here's how:
Swift 3 (Xcode 8, only for iOS 8.0 and higher)
1) Import the Photos framework
import Photos
2) In the imagePickerController(_:didFinishPickingMediaWithInfo:) get the asset URL
3) Fetch assets using fetchAssets(withALAssetURLs:options:)
4) Get the actual image data with requestImageData(for:options:resultHandler:). In the result handler of this method you will have the data as well as URL to the file (the URL can be accessed on Simulator, but unfortunately is not accessible on the device - in my tests startAccessingSecurityScopedResource() always returned false). However this URL is still useful to find out the file name.
Example code:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
dismiss(animated: true, completion: nil)
if let assetURL = info[UIImagePickerControllerReferenceURL] as? URL,
let asset = PHAsset.fetchAssets(withALAssetURLs: [assetURL], options: nil).firstObject,
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first,
let targetURL = Foundation.URL(string: "file://\(documentsPath)") {
PHImageManager.default().requestImageData(for: asset, options: nil, resultHandler: { (data, UTI, _, info) in
if let imageURL = info?["PHImageFileURLKey"] as? URL,
imageData = data {
do {
try data.write(to: targetURL.appendingPathComponent(imageURL.lastPathComponent), options: .atomic)
self.proceedWithUploadFromPath(targetPath: targetURL.appendingPathComponent(imageURL.lastPathComponent))
} catch { print(error) }
}
}
})
}
}
This will give you the file AS IS including its correct name and you can even get its UTI to determine correct mimetype (in addition to determining it via file extension) while preparing multipart body for upload.
There are two ways
1:
You can upload the image using the imagePickerController delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
//Upload your image
}
2:
You can save the picked image url and upload later using this
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *imageUrl = [NSString stringWithFormat:@"%@",[info valueForKey:UIImagePickerControllerReferenceURL]];
//Save the imageUrl
}
-(void)UploadTheImage:(NSString *)imageUrl{
NSURL *url = [[NSURL alloc] initWithString:imageUrl];
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset){
ALAssetRepresentation *rep = [myasset defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
UIImage *myImage = nil;
if (ref) {
myImage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];
//upload the image
}
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror){
};
ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
[assetslibrary assetForURL:url resultBlock:result block failureBlock:failureblock];
}
Notes: Please make sure the scope of ALAssetsLibrary
object while using ARC.Better to use the ALAssetsLibrary
object as a singleton.
Save the photo in Document directory and use that url to upload.For example
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Test.jpg"];
[UIImageJPEGRepresentation(img, 1.0) writeToFile:jpgPath atomically:YES];
upload this image as [request setFile:jpgPath forKey:@"image"]
;
To get the image UIImagePickerControllerReferenceUR. This Sample Code is given below
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *representation = [myasset defaultRepresentation];
NSString *fileName = [representation filename];
NSLog(@"fileName : %@",fileName);
CGImageRef ref = [representation fullResolutionImage];
ALAssetOrientation orientation = [[myasset valueForProperty:@"ALAssetPropertyOrientation"] intValue];
UIImage *image = [UIImage imageWithCGImage:ref scale:1.0 orientation:(UIImageOrientation)orientation];
};
ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];
[assetslibrary assetForURL:imageURL
resultBlock:resultblock
failureBlock:nil];
}
NOTE: It works only in iOS 5 and later.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With