Is there a way to know the ALAsset corresponding to an UIImage?
I use UIImageWriteToSavedPhotosAlbum for saving a photo and I need to identify it in my asset list
UPDATE :
I used writeImageToSavedPhotosAlbum instead of UIImageWriteToSavedPhotosAlbum
alAssetLibrary.writeImageToSavedPhotosAlbum(image.CGImage, orientation: orientation) { (url, error) -> Void in
alAssetLibrary.assetForURL(url, resultBlock: { (asset) -> Void in
//code
}, failureBlock: { (error) -> Void in
//code
})
}
I use UIImageWriteToSavedPhotosAlbum for saving a photo and I need to identify it in my asset list
If you need to identify the resulting asset, why are you using UIImageWriteToSavedPhotosAlbum? It is a "stupid" function.
If you want to save an image as an asset into the library in such a way that you have access to that asset, you need to save it a "smart" way, such ALAssetsLibrary's writeImageToSavedPhotosAlbum - which has a completion handler that hands you the URL of the resulting asset.
Related
I'm trying to download an image called "aaa.jpeg" in my s3 bucket using AWSMobileHubHelper. I found this function on their documentation site.
func downloadContent(content: AWSContent, pinOnCompletion: Bool) {
content.downloadWithDownloadType( .Always, pinOnCompletion: pinOnCompletion, progressBlock: {(content: AWSContent?, progress: NSProgress?) -> Void in
// Handle progress feedback
}, completionHandler: {(content: AWSContent?, data: NSData?, error: NSError?) -> Void in
if let error = error {
print("Failed to download a content from a server.)")
// Handle error here
return
}
// Handle successful download here
if let image = UIImage(data: data!){
self.imageView = image
}
})
}
Once the download is successful (it Did, There is no error message), I'm trying to assign the image to an imageView.
I can tell that the data has been downloaded successfully. I can print the data and see a familiar binary structure of an image. But for some reasons I can't assign the UIImage to the imageView. Because I can't convert the data to a UIImage.
I just want to know if this is the proper way to download image from s3 or am I missing something. Does "data" in the completion block carry the downloaded image? I can't seem to find any documentations on this.
Is this the correct function to use to download from S3?
Yes, the data contains the actual image data. You can put the downloaded data in an UIImageViewController and it should open up fine. Also, this is demonstrated in a Sample App which can be downloaded from the Mobile Hub Console.
I've got some live photos created JPEG and MOV files, now i want to import them into the app that would allow the user to save the live photos to their photo library. How can i go about doing this?
I've looked into this: https://github.com/genadyo/LivePhotoDemoSwift Which basically allows you to record video and turn it into a live photo. But since i've already created the "live photos", can i save them to the camera roll right away or do i need to follow a different route?
You can create a LivePhoto from separate elements from a LivePhoto by using PHLivePhoto.requestLivePhotoWithResourceFileURLs, you will then be able to save it to the library.
func makeLivePhotoFromItems(imageURL: NSURL, videoURL: NSURL, previewImage: UIImage, completion: (livePhoto: PHLivePhoto) -> Void) {
PHLivePhoto.requestLivePhotoWithResourceFileURLs([imageURL, videoURL], placeholderImage: previewImage, targetSize: CGSizeZero, contentMode: PHImageContentMode.AspectFit) {
(livePhoto, infoDict) -> Void in
if let lp = livePhoto {
completion(livePhoto: lp)
}
}
}
makeLivePhotoFromItems(imgURL, videoURL: movURL, previewImage: prevImg) { (livePhoto) -> Void in
// "livePhoto" is your PHLivePhoto object, save it/use it here
}
You will need the JPEG file URL, the MOV file URL, and a "preview" image (which is usually just the JPEG or a lighter version of it).
Full example working in a Playground here.
I'm trying to use the metadata property in writeImageDataToSavedPhotosAlbum to save a GIF to the iPhone's photo album and add date/time metadata so that the saved GIF appears in a different place in the user's photo album instead of the default location at the end of the photo album.
I've tried doing the following:
let metadata: [String: AnyObject]! = [kCGImagePropertyTIFFDictionary as String:
[kCGImagePropertyTIFFDateTime as String: dateTime!],
kCGImagePropertyExifDictionary as String:
[kCGImagePropertyExifDateTimeDigitized as String: dateTime!,
kCGImagePropertyExifDateTimeOriginal as String: dateTime!]]
library.writeImageDataToSavedPhotosAlbum(data, metadata: metadata, completionBlock: completionBlock)
and the debug print for the metadata variable shows:
["{TIFF}": {
DateTime = "2015:10:09 20:07:48";
}, "{Exif}": {
DateTimeDigitized = "2015:10:09 20:07:48";
DateTimeOriginal = "2015:10:09 20:07:48";
}]
However, it doesn't seem like setting the metadata worked because the GIF is still saved at the end of the photo album with the current timestamp instead of the timestamp that I'm trying to set.
It appears the Photos app does not sort based on the date in the image's metadata (most likely because that metadata can be stored on iCloud, it's potentially not available locally). Instead it appears to sort by the creationDate, which is a property defined on PHAsset. You can change that using the Photos framework. Something like this should do the trick:
PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in
let request = PHAssetChangeRequest(forAsset: asset)
request.creationDate = dateTime!
}, completionHandler: { (success: Bool, error: NSError?) -> Void in
dispatch_async(dispatch_get_main_queue()) {
//done
}
})
However, note that the Camera Roll or All Photos album does not sort them the same as the Years, Collections, and Moments view. For some reason Camera Roll/All Photos does not sort on the creationDate while Years, Collections, and Moments does. It doesn't use the photo metadata either, so I am not sure what it is examining to sort the photos for that album.
in an ios swift application,
I am using writeImageToSavedPhotosAlbum to save a UIImage on the iphone
let assets : ALAssetsLibrary = ALAssetsLibrary()
let imgRef : CGImage = myImage!.CGImage
let orientation : ALAssetOrientation = ALAssetOrientation(rawValue: myImage!.imageOrientation.rawValue)!
assets.writeImageToSavedPhotosAlbum(imgRef, orientation: orientation, completionBlock: nil)
Is there a way I can get the saved image filename? or maybe to set it myself?
Thank you for any help
If you look at the spec of the method you're using you will see that the completion block you aren't using is of type ALAssetsLibraryWriteImageCompletionBlock, which has the parameters NSURL *assetURL, NSError *error.
So specify a completion block and you get the asset URL from which you can derive some information.
You can get the file path information using the completion block parameter. Instead of passing nil pass the block like:
assets.writeImageToSavedPhotosAlbum(imgRef, orientation: orientation, completionBlock:
{ (path:NSURL!, error:NSError!) -> Void in
println("\(path)")
})
Check the ALAssetLibrary Class Reference for more information
i want to get some extra info about the images i'll share with the Share extension. I can create the UIImage from the url but when i want to obtain an ALAsset i get nil. Anyone had this problem?
itemProvider!.loadItemForTypeIdentifier(String(kUTTypeImage), options: nil, completionHandler: { (decoder: NSSecureCoding!, error: NSError!) -> Void in
if ALAssetsLibrary.authorizationStatus() == ALAuthorizationStatus.Authorized {
if let url = decoder as? NSURL {
ALAssetsLibrary().assetForURL(url, resultBlock: { (myasset:ALAsset!) -> Void in
println(url)
println(fm.fileExistsAtPath(url.path!))
println(myasset)
let location = myasset?.valueForProperty(ALAssetPropertyLocation) as CLLocation?
let date = myasset?.valueForProperty(ALAssetPropertyDate) as NSDate?
self.extensionContext?.completeRequestReturningItems([AnyObject](), completionHandler: nil)
}, failureBlock: { (myerror:NSError!) -> Void in
})
}
}
The output is
file:///var/mobile/Media/DCIM/102APPLE/IMG_2977.JPG
true
nil
the immediate issue is you are passing a file url in place of an asset url for this line: ALAssetsLibrary().assetForURL(url, resultBlock: { (myasset:ALAsset!) -> Void in.
Share extensions return the url to the path on the iphone's file system...something of the form: file:///..... These are not the same as the urls that an ALAsset require in the assetForURL method.
Unfortunately, though this makes the code more correct, it still doesn't fix the issue. I spent some time with many different approaches. Writing a new image to disk via the AssetsLibrary and the given file path will return an asset url upon completion which will work successfully - though you obviously don't want duplicate photos in your camera roll. (Note: there is no way to delete an ALAsset). You could probably hold onto the file path and delete the new image when you are done with it, but that is an extremely messy approach.
I ended up rewriting my approach given these limitations.