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"];
}
}];
}
Related
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?
This is deprecated, what could be the updated code?
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:referenceURL resultBlock:^(ALAsset *asset) {
ALAssetRepresentation *rep = [asset defaultRepresentation];
Use below code to get all picture from Gallery:
First you need to import Photo framework.
#import <Photos/Photos.h>
Take Authorization before getting image:
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status)
{
switch (status) {
case PHAuthorizationStatusAuthorized:
[self performSelectorOnMainThread:#selector(getAllPictures) withObject:nil waitUntilDone:NO];
// [self getAllPictures];
NSLog(#"PHAuthorizationStatusAuthorized");
break;
case PHAuthorizationStatusRestricted:
NSLog(#"PHAuthorizationStatusRestricted");
break;
case PHAuthorizationStatusDenied:
NSLog(#"PHAuthorizationStatusDenied");
break;
default:
break;
}
}];
-(void)getAllPicture
{
NSLog(#"Started...");
PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.synchronous = YES;
PHFetchOptions *allPhotosOptions = [PHFetchOptions new];
allPhotosOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:allPhotosOptions];
for (PHAsset *asset in result) {
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setValue:asset forKey:#"assest"];
[YOUR_ARRAY insertObject:dic atIndex:0];
dic = nil;
}
NSLog(#"Completed...");
}
You can retrive image from below code:
PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.synchronous = YES;
PHImageManager *manager = [PHImageManager defaultManager];
[manager requestImageForAsset:YOUR_ARRAY[INDEX_ARRAY][#"assest"]
targetSize:CGSizeMake(self.view.frame.size.width/3, 200)
contentMode:PHImageContentModeDefault
options:requestOptions
resultHandler:^void(UIImage *image, NSDictionary *info) {
YOUR_IMAGE_VIEW.image = image;
}];
I wrote simple library to get photos from camera roll. Unfortunately can't read some of them. I can't preview or convert to NSData
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.includeAssetSourceTypes = PHAssetSourceTypeUserLibrary;
PHFetchResult *allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:options];
PHImageRequestOptions *requestOptionForPhotos = [[PHImageRequestOptions alloc] init];
requestOptionForPhotos.networkAccessAllowed = YES;
for(PHAsset *asset in allPhotosResult) {
[[PHImageManager defaultManager]
requestImageForAsset:asset
targetSize:CGSizeMake(100, 100)
contentMode:PHImageContentModeAspectFill
options:requestOptionForPhotos
resultHandler:^(UIImage *result, NSDictionary *info) {
NSData *data = UIImagePNGRepresentation(result);
NSString *base = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; // for some of photos there is nil
}];
}
I have a method which retrieves information about a PHAsset, and it works, but when it comes to reading information of hundreds of assets it can be quite slow.
What is the best way to read information about an asset such as filesize and meta-data?
My current code is:
- (void) getAssetInfo: (NSUInteger*) assetIndex {
NSNumber *_assetIndex = [NSNumber numberWithUnsignedInteger: assetIndex];
PHFetchOptions *fetchOptions;
fetchOptions.sortDescriptors = #[ [NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES], ];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithOptions:fetchOptions];
PHAsset *asset = [fetchResult objectAtIndex: assetIndex];
PHImageManager *imageManager = [PHImageManager defaultManager];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
options.synchronous = YES;
options.version = PHImageRequestOptionsVersionCurrent;
[asset requestContentEditingInputWithOptions:options
completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSString *fileInfo;
NSString *assetURL = nil;
if (contentEditingInput.avAsset != nil){
AVURLAsset *avurlasset_ = (AVURLAsset*) contentEditingInput.avAsset;
assetURL = [avurlasset_.URL absoluteString];
} else {
assetURL = [contentEditingInput.fullSizeImageURL absoluteString];
}
if (assetURL != nil){
uint64_t fileSize;
NSString *filePathFull = [assetURL substringWithRange: NSMakeRange(7, [assetURL length] - 7)];
NSFileManager * filemanager = [[NSFileManager alloc]init];
if([filemanager fileExistsAtPath:filePathFull]){
fileSize = [[filemanager attributesOfItemAtPath:filePathFull error:nil] fileSize];
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy,MM,dd,HH,mm,ss"];
NSArray *assembled_FI = [NSArray arrayWithObjects:
(NSNumber*) _assetIndex,
assetURL,
assetURL.lastPathComponent,
(NSNumber*)[NSNumber numberWithUnsignedLongLong: fileSize],
(NSString*) [dateFormatter stringFromDate:asset.creationDate],
nil];
}
}];
}
There is a small library for Swift 3 recently added to GitHub called AssetManager.
It simplifies the access to assets and allows for very fast data extraction.
The link to AssetManager can be found here: https://github.com/aidv/AssetManager
I need to get information about an asset without loading it into memory which might take a long time if the asset is very large.
As I will be iterating through all assets available in my device, it might take a very long time.
I am using the following code to load an asset in to an NSData object and also retrieve some information about it:
- (NSData*)getAssetInfo: (NSUInteger*) assetIndex {
PHFetchOptions *fetchOptions;
fetchOptions.sortDescriptors = #[ [NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES], ];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithOptions:fetchOptions];
__block NSData *iData = nil;
PHAsset *asset = [fetchResult objectAtIndex: assetIndex];
PHImageManager *imageManager = [PHImageManager defaultManager];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
options.synchronous = YES;
options.version = PHImageRequestOptionsVersionCurrent;
#autoreleasepool {
[imageManager requestImageDataForAsset:asset options:options resultHandler:^(NSData *imgData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
//NSLog(#"requestImageDataForAsset returned info(%#)", info);
NSURL *url = [info valueForKey: #"PHImageFileURLKey"];
NSString *urlAsString = [url absoluteString];
gAssetFilename = [urlAsString lastPathComponent];
gAssetCreationDate = asset.creationDate;
iData = imgData;
}];
}
if (iData != nil) {
return iData;
}
else{
NSLog(#"OOPS!");
return nil;
}
}
This works but as I said, it might take a very long time.
Is it possible to get the size of the asset as well other information about the asset without first fully load it into memory?