Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if image exists in Photos

Tags:

ios

swift

I have an album of images that is managed by a remote server. I would like to give the user an option to download the album and store it to a custom album in Photos. But since the album is dynamic (photos get added to it) the user can download it multiple times. I don't want to download the same pictures multiple times, only the new ones.

Is it possible to associate some metadata (unique id) when I store the image in the Photo app? And then check if that image already exists?

I am using the Photos Framework to create the custom album and save the photos.

Edit: Here is my code for creating the custom album and saving photos

/** Returns the first album from the photos app with the specified name. */
static func getAlbumWithName(name: String, completion: (album: PHAssetCollection?) -> Void) {

    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "localizedTitle = %@", name)
    let fetchResult = PHAssetCollection.fetchAssetCollectionsWithType(PHAssetCollectionType.Album, subtype: PHAssetCollectionSubtype.Any, options: fetchOptions)

    if fetchResult.count > 0 {

        guard let album = fetchResult.firstObject as? PHAssetCollection else {return}
        completion(album: album)

    } else {

        PHPhotoLibrary.sharedPhotoLibrary().performChanges({

            PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle(name)

            }, completionHandler: { (result, error) in

                if result {

                    FileUtils.getAlbumWithName(name, completion: completion)

                } else {

                    completion(album: nil)

                }


        })

    }

}

/** Adds an image to the specified photos app album */
private static func addImage(image: UIImage, toAlbum album: PHAssetCollection, completion: ((status: Bool) -> Void)?) {

    PHPhotoLibrary.sharedPhotoLibrary().performChanges({

        let assetRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
        let assetPlaceholder = assetRequest.placeholderForCreatedAsset
        let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: album)
        albumChangeRequest?.addAssets([assetPlaceholder!])


    }) { (status, error) in

        completion?(status: status)

    }

}
like image 675
xlogic Avatar asked Apr 07 '16 07:04

xlogic


1 Answers

All you need to do is read "localIdentifier" from the asset placeholder. I've augmented your code to return the identifier in the completion handler. You may like to deal with those optionals.

private static func addImage(image: UIImage, toAlbum album: PHAssetCollection, completion: ((status: Bool, identifier: String?) -> Void)?) {

    var localIdentifier: String?
    PHPhotoLibrary.sharedPhotoLibrary().performChanges({

        let assetRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
        let assetPlaceholder = assetRequest.placeholderForCreatedAsset
        let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: album)
        albumChangeRequest?.addAssets([assetPlaceholder!])
        localIdentifier = assetPlaceholder?.localIdentifier

    }) { (status, error) in

        completion?(status: status, identifier: localIdentifier)

    }
}

When you want to read that asset again your load image method might look something like this (I haven't used your conventions or variable names). This will read the asset synchronously but I'm sure you can spot the async option.

internal func loadPhoto(identifier: String) -> UIImage? {
    if assetCollection == nil {
        return nil
    }

    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "localIdentifier = %@", identifier)
    let fetchResult = PHAsset.fetchAssetsInAssetCollection(assetCollection, options: fetchOptions)
    if fetchResult.count > 0 {
        if let asset = fetchResult.firstObject as? PHAsset {
            let options = PHImageRequestOptions()
            options.deliveryMode = .HighQualityFormat
            options.synchronous = true
            var result: UIImage?
            PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: CGSize(width: asset.pixelWidth, height: asset.pixelHeight), contentMode: .AspectFit, options: options, resultHandler: {(image: UIImage?, _: [NSObject: AnyObject]?) -> Void in
                result = image
            })
            return result
        }
    }
    return nil
}
like image 140
RowanPD Avatar answered Oct 15 '22 07:10

RowanPD