NSItemProvider to PHAsset - ios

I'm building an app and I need to get the PHAsset of an image from the NSItemProvider.
The NSURL I'm getting is for example:
file:///Users/user/Library/Developer/CoreSimulator/Devices/84BDFE8E-127E-4677-83B8-208227CCBC16/data/Media/PhotoData/OutgoingTemp/A4D845E7-17E3-4C35-8993-027092D3604A.JPG
And I need to be able to get a PHAsset from that URL so I can use PHPhotoLibrary to work with the image.
I tried:
let imageAssetToDelete = PHAsset.fetchAssetsWithALAssetURLs([imageURL], options: nil)
Where imageURL is an NSURL with the previous posted URL but it always returns an empty array.

Related

How can I retrieve the metadata of PHAsset?

I am getting the user selected image in PHAsset format. and I want to get the image path.
My goal is to upload the image to Firebase and based their docs, I need to have the image path.
I found from researching that I need to get the metadata of the image first and store it in local file and then I can retrieve the URL. Is it correct?
My question here is (If the above correct), how can I get the metadata of PHAsset image format?
If you want to retrive the image file Path from your PHAsset address then use this function:
[asset requestContentEditingInputWithOptions:[PHContentEditingInputRequestOptions new] completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
NSURL *imageURL = contentEditingInput.fullSizeImageURL;
}];
asset=PHAsset *asset

Get file path of saved image to camera roll iOS (Obj-c)

I used UIImageWriteToSavedPhotosAlbum to save image to Camera Roll, but I want to get a reference to get back to the same image. Is it possible? I have a link (albeit in Japanese) that says it's possible to get the file path, but as of what I understand this is during selection (using imagePicker) and not before/after taking a picture. What I want is to get the reference of the image, save it in CoreData, and the use it later to fetch the image.
Edit: It seems as if there is an answer already but in the comments it says that ALAssetsLibrary is already deprecated and we should use PHPhotoLibrary instead.
You Can Get All the Photos, Videos and Other Data With Using PHAsset Library. Here is Code to get All Videos in Array .
//For Video
allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:nil];
For Image you Can use this
//For Images
allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
and You can Display it Using PHAsset in UiTableview or Any Other Control.
Here is the URL of Demo ,
AVPlayer Demo (Fetch Video With PHAsset Library)
just pass the file name and extension to fetch the image
+(UIImage *)loadImage:(NSString *)fileName ofType:(NSString *)extension {
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
UIImage * result = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/%#.%#", documentsDirectoryPath, fileName, extension]];
return result; }

Swift PHAsset from NSURL

I am working on PHAsset and NSURL on Swift.
I have an image url, for example file:///var/mobile/Media/DCIM/100APPLE/IMG_0043.JPG.
How can i make a PHAsset from this NSURL in Swift?
A PHAsset object represents an image or video file that appears in the Photos app, including iCloud Photos content. To display or edit assets, use the PHAsset class to fetch asset objects for the photos or videos you want to work with. An asset object is immutable and contains only the metadata for the photo or video it represents.
Thus you can not make PHAsset object.
Here is only one constructor for making object.
let asset = PHAsset()
There is no constructor for NSURL :-
This is what we frequently use:-
let imgData = NSData(contentsOfURL: (NSURL(string: "file:///var/mobile/Media/DCIM/100APPLE/IMG_0043.JPG"))!)
let image = UIImage(data: imgData!)

Copy video from Resource to UIPasteboard

I am Developing a custom keyboard with Keyboard Extension.
I want to copy video from my resource folder to UIPasteboard. For that i am using below code but no luck
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath = [bundle pathForResource:#"SampleVideo_1280x720_1mb" ofType:#"mp4"];
NSURL *movieURL = [NSURL fileURLWithPath:moviePath];
NSData *data = [NSData dataWithContentsOfURL:movieURL];
[[UIPasteboard generalPasteboard]setPersistent:YES];
[[UIPasteboard generalPasteboard] setData:data forPasteboardType:(NSString *)kUTTypeVideo];
Can you please help me this?
And one more thing is it Possible to do?
Thanks in advance.
The pasteboardType you are using (kUTTypeVideo) is for a type of movie that has no sound. This will not work. If you copied an mp4 file to the pasteboard using that pasteboardType, and then say, pasted it into an iMessage chat field, it'll show that it's an unknown and unplayable format.
Instead, use kUTTypeQuickTimeMovie or kUTTypeMPEG4. This will work.
Also, no need to setPersistent to Yes; this is the general pasteboard which is a system pasteboard that transcends the space-time of any app, and so you don't need to do that. :)
Try this code. It worked for me.
let pb = UIPasteboard.generalPasteboard()
let url: NSURL = NSBundle.mainBundle().URLForResource("\(tempArray[indexPath.row])", withExtension: "mp4")!
let data1: NSData = try! NSData(contentsOfURL: url, options: NSDataReadingOptions.DataReadingMappedIfSafe)
let data: NSData = NSData(contentsOfURL: url)!
print(data)
pb.persistent = true
pb.setData(data1, forPasteboardType: "public.mpeg-4")
And also if u want to get the URL of the video from the NSBundle you need to add the video locally.

How can i get the name of image picked through photo library in iphone?

I am picking an image from photo library in iphone application. How will i retrieve the actual image name.
in .h class
UIImageView * imageView;
UIButton * choosePhotoBtn;
in .m class
-(IBAction) getPhoto:(id) sender
{
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if((UIButton *) sender == choosePhotoBtn)
{
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
else
{
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
[self presentModalViewController:picker animated:YES];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissModalViewControllerAnimated:YES];
imageView.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
}
How will i get the actual name of image ?
I m new in iphone. Please help me.
Thanks in advance.
import AssetsLibrary in your file:
#import <AssetsLibrary/AssetsLibrary.h>
And, in - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
put
// get the ref url
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];
so you'll get the image name in log.
*don't forget to add existing framework: AssetsLibrary.framework
Steps:
In the project navigator, select your project
Select your target
Select the 'Build Phases' tab
Open 'Link Binaries With Libraries' expander
Click the '+' button
Select your framework
(optional) Drag and drop the added framework to the 'Frameworks' group
Source:
http://www.raywenderlich.com/forums/viewtopic.php?f=2&p=34901
&
How to "add existing frameworks" in Xcode 4?
If you are building for iOS 9+ target, you will see a bunch of deprecation warnings with ALAssetsLibrary, i.e.:
'assetForURL(_:resultBlock:failureBlock:)' was deprecated in iOS 9.0: Use fetchAssetsWithLocalIdentifiers:options: on PHAsset to fetch assets by local identifier (or to lookup PHAssets by a previously known ALAssetPropertyAssetURL use fetchAssetsWithALAssetURLs:options:) from the Photos framework instead
As the warning describes, you should use PHAsset. Using swift 2.x, for example, you will need to add import Photos to your file first. Then, in the didFinishPickingMediaWithInfo UIImagePickerControllerDelegate method use fetchAssetsWithALAssetURLs to get the filename:
if let imageURL = info[UIImagePickerControllerReferenceURL] as? NSURL {
let result = PHAsset.fetchAssetsWithALAssetURLs([imageURL], options: nil)
let filename = result.firstObject?.filename ?? ""
}
This will set filename to be something like, "IMG_0007.JPG".
Simple Swift implementation:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let referenceUrl = info[UIImagePickerControllerReferenceURL] as? NSURL {
ALAssetsLibrary().assetForURL(referenceUrl, resultBlock: { asset in
let fileName = asset.defaultRepresentation().filename()
//do whatever with your file name
}, failureBlock: nil)
}
}
}
Remember about: import AssetsLibrary
In Objective C, use the Photos framework and import Photos/Photos.h
Then, in your imagePickerController function
add the following to get the filename of the image from the photo library
NSURL *refURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *result = [PHAsset fetchAssetsWithALAssetURLs:#[refURL] options:nil];
NSString *filename = [[result firstObject] filename];
Though you may be able to retrieve the last path component and use it like a file name, it is not advisable to do so. These filenames are assigned by the system for iTunes to understand while syncing and are not meant for programmers to access as they could be replaced by some other images in future syncs.
A good round about for this is to assign the current Date as filenames, while saving to images picked from the gallery. You may save it in your documents or library directory and use a mapping PList file to map images to their filename.
Alternatively, you can also assign unique numbers as filenames and access the images using these values.
Objective C implementation that works on iOS 10. ALAssetsLibrary seems to be deprecated so you should use PHAsset:
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
PHAsset *phAsset = [[PHAsset fetchAssetsWithALAssetURLs:#[imageURL] options:nil] lastObject];
NSString *imageName = [phAsset valueForKey:#"filename"];
UIImage *photo = [info valueForKey:UIImagePickerControllerOriginalImage];
NSLog(#"Picked image: %# width: %f x height: %f",imageName, photo.size.width, photo.size.height);
[picker dismissViewControllerAnimated:YES completion:nil];
}
As of Swift 3 and iOS8+ the .filename is not accessible any more. It is still available through self.valueForKey("filename"), but not quite legal though.
However, I found this answer in the question "iOS8 Photos Framework: How to get the name(or filename) of a PHAsset?" to be short, simple, and legal.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any])
{
let imageUrl = info[UIImagePickerControllerReferenceURL] as! NSURL
let imageName = imageUrl.lastPathComponent
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let photoURL = NSURL(fileURLWithPath: documentDirectory)
let localPath = photoURL.appendingPathComponent(imageName!)
let image = info[UIImagePickerControllerOriginalImage]as! UIImage
let data = UIImagePNGRepresentation(image)
do
{
try data?.write(to: localPath!, options: Data.WritingOptions.atomic)
}
catch
{
// Catch exception here and act accordingly
}
self.dismiss(animated: true, completion: nil);
}
var fileName: String = "Attachment"
if let imageURL = info[UIImagePickerControllerReferenceURL] as? URL {
let assets = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil)
let assetResource = PHAssetResource.assetResources(for: assets.firstObject!)
fileName = assetResource.first?.originalFilename ?? "Attachment"
}
print(fileName)

Resources