issue with UIImagePickerController - objective C - ios

as the title i have problem with the picker controller. i'm using a virtual machine to program in objective c, xcode version 9.2, and iOS 11.2. My app is an Address Book, when the user create a new contact he is able to pick a photo from one camera (if run on a device) o select a photo from photo roll. i manage this feature with the following code:
-(void) imagePickerController:(UIImagePickerController *)_picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if (CFStringCompare((CFStringRef) mediaType, kUTTypeImage, 0) ==
kCFCompareEqualTo) {
image = [info objectForKey:UIImagePickerControllerOriginalImage];
if(image==nil)
image = [info objectForKey:UIImagePickerControllerEditedImage];
if(image==nil)
image = [info objectForKey:UIImagePickerControllerCropRect];
if(picker.sourceType == UIImagePickerControllerSourceTypeCamera){
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
PHAsset *asset = nil;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult != nil && fetchResult.count > 0) {
// ottengo l'ultima foto
asset = [fetchResult lastObject];
}
if (asset) {
// ottengo le info della foto tramite l'asset
PHImageRequestOptions * imageRequestOptions = [[PHImageRequestOptions alloc] init];
imageRequestOptions.synchronous = YES;
[[PHImageManager defaultManager]
requestImageDataForAsset:asset
options:imageRequestOptions
resultHandler:^(NSData *imageData, NSString *dataUTI,
UIImageOrientation orientation,
NSDictionary *info)
{
NSLog(#"info = %#", info);
if ([info objectForKey:#"PHImageFileURLKey"]) {
imagepath = [NSString stringWithFormat:#"%#", [info objectForKey:#"PHImageFileURLKey"]];
}
}];
}
}
else {
NSURL *url = [[NSURL alloc] init];
url = [info valueForKey:UIImagePickerControllerImageURL];
imagepath = [url absoluteString];
}
}
[picker dismissViewControllerAnimated:YES completion:NULL]; }
in the first part i check that the user select a photo instead a video, then i save image in an uiimage variable (correctly in both case), at last i check sorcetype of image picker controller and if it is set to sourcetype camera i save photo in photo roll and i obtain with asset last photo path from photo roll (if you know easier way i appreciate), else i save image path as NSStringwith absoluteString of url.
i obtain in both methods a path like: file:///Users/dannycasa/Library/Developer/CoreSimulator/Devices/F9730203-BFD1-4C22-BC52-DC2FD6E736C3/data/Containers/Data/Application/57839B62-0573-49D7-896A-3606007F264B/tmp/34AE1FDA-0B1F-4310-8C7A-CD91CF46104D.jpeg
the problem is that when i try to show image in another view controller with:
NSData *data = [NSData dataWithContentsOfFile:self.contact.profileImageUrl];
image = [[UIImage alloc] initWithData:data];
or
NSURL *url = [[NSURL alloc] initWithString:self.contact.profileImageUrl];
NSData *data = [NSData dataWithContentsOfUrl:url];
image = [[UIImage alloc] initWithData:data];
image is always null! In both view controller (new contact and show contact view controller), i import Photos/Photos.h and MobileCoreServices/MobileCoreServices.h.
Any suggestions?

Related

save custom camera capture image iOS Xcode

I am new to iPhone, I want to save image into the album & I want that image path.
I did this already.
Now, I want a custom name for image & store image with that name.
I used below code but I am not getting any image into the album.
Can anybody guide me where am I wrong ?
#pragma mark - Image Picker Controller delegate methods
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
// Todo to use custom name comment this line.
//UIImageWriteToSavedPhotosAlbum(self.imageView.image,nil,nil,nil);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:#"savedImage.png"];
UIImage *image = imageView.image; // imageView is my image from camera
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:savedImagePath atomically:NO];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
});
}
You can Store Image with Custom name like this :
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
//save image in Document Derectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(#"Get Path : %#",documentsDirectory);
//create Folder if Not Exist
NSError *error = nil;
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/MyFolder"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder
NSString *customePhotoName=#"MyPhotoName";
NSString* path= [dataPath stringByAppendingString:[NSString stringWithFormat:#"/%#.png",customePhotoName]];
NSData* imageData = UIImagePNGRepresentation(chosenImage);
[imageData writeToFile:path atomically:YES];
NSLog(#"Save Image Path : %#",path);
In one of my project I did this:
let directory = "yourDirectoryName"
let fileName = "file.png"
let directoryPath = NSHomeDirectory() + "/Library/Caches/\(directory)"
do {
try NSFileManager.defaultManager().createDirectoryAtPath(directoryPath, withIntermediateDirectories: true, attributes: nil)
UIImagePNGRepresentation(image)?.writeToFile(directoryPath+fileName), atomically: true)
} catch let error as NSError {}
Code works in Swift 2.3. I hope, this is what you want.
Verify if NSData and UIImage objects are proper, set "atomically" as YES, check out the below code I use:
//Save your image with a completion selector
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
//Completion selector
- (void) image: (UIImage *) image
didFinishSavingWithError: (NSError *) error
contextInfo: (void *) contextInfo
{
if(error)
{
NSLog(#"save error :%#", [error localizedDescription]);
}
else if (!error)
{
PHAsset *asset = [self fetchImageAsset];
}
}
//Fetch image based on create date or whatever naming system you follow
- (nullable PHAsset *)fetchImageAsset
{
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
PHAsset *lastAsset = [fetchResult lastObject];
return lastAsset;
}

Replacing ALAssertLibrary to get the filename

Im using the following code to access filename of the image that I gotta upload. I need both filename alongside the file path and size.
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *imageAsset)
{
ALAssetRepresentation *imageRep = [imageAsset defaultRepresentation];
NSLog(#"[imageRep filename] : %#", [imageRep filename]);
[_imageNameArray addObject:[imageRep filename]];
};
[_uploadTbleView reloadData];
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:refURL resultBlock:resultblock failureBlock:nil];
The problem that Im facing is,
Xcode throws a warning message that ALAssetsLibraryAssetForURLResultBlock is deprecated. How can I replace the above code to get the filename ?
I tried using PHAsset but every time when Im selecting the file, it has got the same file name called asset.jpg for all image files.
You can try this:
PHAsset *asset = nil;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult != nil && fetchResult.count > 0) {
// get last photo from Photos
asset = [fetchResult lastObject];
}
if (asset) {
// get photo info from this asset
PHImageRequestOptions * imageRequestOptions = [[PHImageRequestOptions alloc] init];
imageRequestOptions.synchronous = YES;
[[PHImageManager defaultManager]
requestImageDataForAsset:asset
options:imageRequestOptions
resultHandler:^(NSData *imageData, NSString *dataUTI,
UIImageOrientation orientation,
NSDictionary *info)
{
NSLog(#"info = %#", info);
if ([info objectForKey:#"PHImageFileURLKey"]) {
// path looks like this -
// file:///var/mobile/Media/DCIM/###APPLE/IMG_####.JPG
NSURL *path = [info objectForKey:#"PHImageFileURLKey"];
}
}];
}

How to copy image from device into sandbox of application?

I need to copy image from the device into the sandbox of the app! Say in Library/Cache folder! How do I do it? I searched in the internet i didnt find the solution. Please help!
EDIT:
#pragma mark - ZYQAssetPickerController Delegate
-(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets{
ALAssetsLibrary *lib=[ALAssetsLibrary new];
for (int i=0; i<assets.count; i++) {
ALAsset *asset=assets[i];
FileOP *fileMgr=[[FileOP alloc]init];
NSString *baseDir=[fileMgr GetDocumentDirectory];
//STORING FILE INTO LOCAL
[lib assetForURL:asset.defaultRepresentation.url
resultBlock:^(ALAsset *asset){
ALAssetRepresentation *repr = [asset defaultRepresentation];
CGImageRef cgImg = [repr fullResolutionImage];
NSString *fname = repr.filename;
UIImage *img = [UIImage imageWithCGImage:cgImg];
NSData *data = UIImagePNGRepresentation(img);
[data writeToFile:[baseDir stringByAppendingPathComponent:fname]
atomically:YES];
//FOR LOCAL URL OF THE IMAGE
NSString *imageURL = [baseDir stringByAppendingPathComponent:fname];
NSLog(#"%# URL OF IMAGE ",imageURL);
[[ImageArray sharedImageArray]setImageUrl:imageURL atIndex:i];
//NSLog(#"%# is the shared array",[[ImageArray sharedImageArray] getImageUrlAtIndex:i];
}
failureBlock:^(NSError *error){
}];
}
NSLog(#"COPIED %lu FILE INTO LOCAL MEMORY",(unsigned long)assets.count);
//NEED TO STORE THE PATH OF THE SELECTED IMAGE FILES INTO SOME ARRAY HERE
}
You can do it like that :
In .h, implement the UIImagePickerControllerDelegate delegate :
#interface yourClass : NSObject <UIImagePickerControllerDelegate>
In .m, create a method fired when you click on a button. It will open your photo library and save the picked image into the cache folder :
- (IBAction)pickFromAlbum:(id)sender
{
UIImagePickerController *pickerController = [UIImagePickerController new];
pickerController.delegate = self;
pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:pickerController animated:YES completion:nil];
}
Then implement the delegate method :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Get image into a variable
UIImage *takenImage = [info objectForKey:UIImagePickerControllerOriginalImage];
// Get the cache folder
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDir = [dirPaths objectAtIndex:0];
// Save image into cache folder
NSData *data;
data = [NSData dataWithData:UIImageJPEGRepresentation(takenImage, 1.0f)]; // 1.0f = quality 100%
[data writeToFile:[cacheDir stringByAppendingPathComponent:#"fileName.jpeg"] atomically:YES];
// Hide the picker
[picker dismissViewControllerAnimated:YES completion:nil];
}

iOS: I am able to save image but new image name returns nil

Hi I am trying to buil and interface which gives user options to select an existing image or take new from camera. Selecting existing image works fine and I am able to get the image file name. But when I try to take new image I am able save image to library but can not get its file name. It returns nil. Here is my code:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"Dismissing camera ui...");
[self.cameraUI dismissViewControllerAnimated:YES completion:nil];
NSLog(#"Getting media url...");
NSURL *mediaURL = [info objectForKey:UIImagePickerControllerMediaURL];
if(mediaURL) {
NSLog(#"This is a video = %#", mediaURL);
} else {
NSLog(#"This is a photo...");
NSLog(#"Getting media type...");
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
NSLog(#"Selected mediaType : %#", mediaType);
UIImage *originalImage;
if (self.source == UIImagePickerControllerSourceTypeCamera) {
// Handle a still image capture
if (CFStringCompare ((CFStringRef) mediaType, kUTTypeImage, 0) == kCFCompareEqualTo) {
originalImage = (UIImage *) [info objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"Saving new image...");
if (self.source != UIImagePickerControllerSourceTypePhotoLibrary) {
UIImageWriteToSavedPhotosAlbum(originalImage, nil, nil , nil);
}
} else {
// Handle a movie capture
}
}
NSLog(#"Getting reference url...");
NSURL *referenceURL = [info objectForKey:UIImagePickerControllerReferenceURL];
ALAssetsLibrary *assetLibrary = [ALAssetsLibrary new];
[assetLibrary assetForURL:referenceURL
resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *assetRep = [asset defaultRepresentation];
NSString *filename = [assetRep filename];
NSLog(#"File name = %#", filename);
if(self.selectedMediaNames == nil)
self.selectedMediaNames = [[NSMutableArray alloc] init];
[self.selectedMediaNames addObject:filename];
[self.tableView reloadData];
[self.activitIndicator stopAnimating];
[self.activitIndicator setHidden:true];
}
failureBlock:^(NSError *error) {
NSLog(#"%#", error);
}];
}
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
My goal is use this image name for upload the image to server.
I am still getting nil but I have solved my problem by saving image to a temp directory and use this path for upload:
NSString *path = [NSTemporaryDirectory()
stringByAppendingPathComponent:#"upload-image.tmp"];
NSData *imageData = UIImageJPEGRepresentation(originalImage, 1.0);
[imageData writeToFile:path atomically:YES];

Get image name from UIImageWriteToSavedPhotosAlbum in ios [duplicate]

This question already has answers here:
Getting image name of iphone photo library
(2 answers)
Closed 9 years ago.
I've searched how to get the name of the saved image takes from the camera, but i didn't find something simple.
this is my code :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if( [picker sourceType] == UIImagePickerControllerSourceTypeCamera){
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
[library writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error )
{
NSLog(#"IMAGE SAVED TO PHOTO ALBUM");
[library assetForURL:assetURL resultBlock:^(ALAsset *asset )
{
NSLog(#"we have our ALAsset!");
NSLog(#"%#", assetURL);
}
failureBlock:^(NSError *error )
{
NSLog(#"Error loading asset");
}];
}];
}
}
I you have the answer, i will happy to test it .
Thanks in advance.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *resourceURL;
[picker dismissViewControllerAnimated:YES completion:nil];
UIImage *image =[[UIImage alloc] init];
image =[info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSURL *imagePath = [info objectForKey:#"UIImagePickerControllerReferenceURL"];
NSString *imageName = [imagePath lastPathComponent];
resourceURL = [info objectForKey:UIImagePickerControllerReferenceURL];
NSData *imageData;
NSString *extensionOFImage =[imageName substringFromIndex:[imageName rangeOfString:#"."].location+1 ];
if ([extensionOFImage isEqualToString:#"jpg"])
{
imageData = UIImagePNGRepresentation(image);
}
else
{
imageData = UIImageJPEGRepresentation(image, 1.0);
}
int imageSize=imageData.length/1024;
NSLog(#"imageSize--->%d", imageSize);
if (imageName!=nil) {
NSLog(#"imageName--->%#",imageName);
}
else
{
NSLog(#"no image name found");
}
}
If you are using ASSerts
-(void)assetPickerController:(WSAssetPickerController *)sender didFinishPickingMediaWithAssets:(NSArray *)assets
{
[self dismissViewControllerAnimated:YES completion:^{
if (assets.count < 1) return;
//self.pageControl.numberOfPages = assets.count;
int index = 0;
for (ALAsset *asset in assets) {
// NSString *imageName = [[asset defaultRepresentation] filename];
UIImage *image = [[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage];
// (#"%#", [[asset defaultRepresentation] filename]);
NSData *imageData = UIImagePNGRepresentation(image);
int imageSize=imageData.length/1024;
(either)
NSURL *imagePath = [asset objectForKey:#"UIImagePickerControllerReferenceURL"];
// NSURL *imagePath = [NSURL URLWithString:[asset ob]];
NSString *imageName = [imagePath lastPathComponent];
(or)
NSLog(#"%#",[[asset defaultRepresentation] filename]);
index++;
}
}];
}
Try following code. I have used this in one of my previous project and its working for me :
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
_selectedImage = info[UIImagePickerControllerEditedImage];
self.photoView.image = _selectedImage;
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
// define the block to call when we get the asset based on the url (below)
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *imageAsset)
{
ALAssetRepresentation *imageRep = [imageAsset defaultRepresentation];
NSLog(#"[imageRep filename] : %#", [imageRep filename]);
};
// get the asset library and fetch the asset based on the ref url (pass in block above)
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:refURL resultBlock:resultblock failureBlock:nil];
[picker dismissViewControllerAnimated:YES completion:NULL];
}

Resources