将 PHAsset 从一张专辑移动/复制到另一张专辑

Move/copy PHAsset from one album to another(将 PHAsset 从一张专辑移动/复制到另一张专辑)

本文介绍了将 PHAsset 从一张专辑移动/复制到另一张专辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将资产从一个相册移动到另一个相册.但我只能找到有关创建和删除资产的信息.我想移动而不是创建一个新副本并删除旧副本的原因是,我想保留资产的 localIdentifier 之类的数据位.如果我在另一个专辑中重新创建资产,它将被分配一个新的 localIdentifier,对吗?

I want to move an asset from one album to another. But I could only find information on creating and deleting assets. The reason I want to move instead of creating a new one and deleting the old copy is, I want to preserve the bits of data like the localIdentifier of the asset. If I recreate an asset in another album, it will be assigned a new localIdentifier, am I right?

但这似乎是不可能的.所以我至少求助于复制资产.但这也给我带来了麻烦.

But it seems it's not possible. So I resorted to copying the asset at least. But it's giving me trouble as well.

这是我的代码.

func copyAsset() {
    if let assets = getAssetsFromCollection(collectionTitle: "Old") {
        if getAssetColection("New") == nil {
            createCollection("New") { collection in
                if let collection = collection {
                    print("Collection created")
                    self.copyAssetsToCollection(assets, toCollection: collection)
                }
            }
        }
    }
}

/**
 Copy assets to album.

 - parameter assets:     Array of assets to copy.
 - parameter collection: The collection where the assets need to be copied.
 */
func copyAssetsToCollection(assets: [PHAsset], toCollection collection: PHAssetCollection) {
    PHPhotoLibrary.sharedPhotoLibrary().performChanges({
        let asset = assets.first!
        print(asset.localIdentifier)
        let assetChangeRequest = PHAssetChangeRequest(forAsset: asset)
        let assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset!

        let collectionChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: collection)!
        collectionChangeRequest.addAssets([assetPlaceholder])
    }, completionHandler: { success, error in
        if success {
            print("Photo copied to collection")
        } else {
            if let error = error {
                print("Error adding photos to collection: (error.code) - (error.localizedDescription)")
            }
        }
    })
}

/**
 Retrieve the album for the given title.

 - parameter title: Album title.

 - returns: Album if it exists. nil if it doesn't.
 */
func getAssetColection(title: String) -> PHAssetCollection? {
    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "title ==[cd] %@", title)
    if let collection = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .AlbumRegular, options: fetchOptions).firstObject {
        return collection as? PHAssetCollection
    }
    return nil
}

/**
 Get assets from a given album.

 - parameter title: Album title.

 - returns: An array of assets if they exist. nil if they don't.
 */
func getAssetsFromCollection(collectionTitle title: String) -> [PHAsset]? {
    var assets = [PHAsset]()
    if let collection = getAssetColection(title) {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.Image.rawValue)
        let fetchResult = PHAsset.fetchAssetsInAssetCollection(collection, options: fetchOptions)
        fetchResult.enumerateObjectsUsingBlock { object, index, stop in
            if let asset = object as? PHAsset {
                assets.append(asset)
            }
        }
        return assets
    }
    return nil
}

/**
 Create an album in Photos app.

 - parameter title:      Album title.
 - parameter completion: Album if successfully created. nil if it fails.
 */
func createCollection(title: String, completion: (collection: PHAssetCollection?) -> ()) {
    var albumPlaceholder: PHObjectPlaceholder!
    PHPhotoLibrary.sharedPhotoLibrary().performChanges({
        let request = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle(title)
        albumPlaceholder = request.placeholderForCreatedAssetCollection
    }, completionHandler: { success, error in
        if success {
            let fetchResult = PHAssetCollection.fetchAssetCollectionsWithLocalIdentifiers([albumPlaceholder.localIdentifier], options: nil)
            completion(collection: fetchResult.firstObject as? PHAssetCollection)
        } else {
            if let error = error {
                print("Failed to create album: (title) in Photos app: (error.code) - (error.localizedDescription)")
                completion(collection: nil)
            }
        }
    })
}

应用程序在 letassetPlaceholder = assetChangeRequest.placeholderForCreatedAsset! 行崩溃,以查找 placeholderForCreatedAssetnil 值.这意味着 PHAssetChangeRequest(forAsset:asset) 只能用于更改资产的元数据而不是复制它.

The app crashes at the line let assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset! for finding nil value for the placeholderForCreatedAsset. Which means PHAssetChangeRequest(forAsset: asset) can only be used to changing an asset's metadata and not duplicating it.

还有其他方法可以做到这一点吗?任何解决方法或黑客?我会非常感谢任何帮助.

Is there any other way to do this? Any workaround or hack? I'll really appreciate any help.

推荐答案

没有什么比将资产从一个相册复制到另一个相册的方法:在 iOS 照片库中,所有原始照片/视频都位于所有照片"/相机"中卷".相册仅包含对位于所有照片/相机胶卷"中的原始照片/视频的引用.这意味着您可以将一张照片分配给 n-Albums.要管理这些分配,请查看 PHAssetCollectionChangeRequest 类.要在相册中添加一张或多张照片/视频,请使用 addAssets:,要从相册中删除资产,请使用 removeAssets: 方法.

There is nothing like copying an asset from one album to another: In the iOS Photo Library all original photos/videos are located in "All Photos"/"Camera Roll". Albums contain only references to the original photo/video located in "All Photos/Camera Roll". This means you can assign one photo to n-Albums. To manage those assignments please have a look at the PHAssetCollectionChangeRequest class. To add one or several photos/video at an album use the addAssets:, to remove assets from an album use the removeAssets:method.

这篇关于将 PHAsset 从一张专辑移动/复制到另一张专辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:将 PHAsset 从一张专辑移动/复制到另一张专辑

基础教程推荐