xcode 通过 iOS swift 照片框架保存时如何命名照片

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29854165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 07:04:18  来源:igfitidea点击:

How to name a photo when saving via iOS swift photos framework

iosswiftxcodeframeworksphoto

提问by Wayne Fulcher

I am using Xcode 6.3with swift (I think version 1.2). My app downloads photos from a custom server on the web. Then I want it to save the photo with a given file name to the custom photo album, which was has created via the Photos Framework. I need to be able to control the photo/filename because I keep track of which photos I have downloaded in a database and later need to view them by name.

我正在使用Xcode 6.3swift(我认为是 1.2 版)。我的应用程序从网络上的自定义服务器下载照片。然后我希望它将具有给定文件名的照片保存到通过照片框架创建的自定义相册中。我需要能够控制照片/文件名,因为我会跟踪我在数据库中下载的照片,然后需要按名称查看它们。

I created a custom PhotoAlbum class that I am trying to wrap all of the logic for interacting with the photo albums in. Once I download a photo I can call the following code and it works as far as creating the album and saving the photo, but as you will notice in the savePhoto()method I don't know where/how to use the photoName variable to name the photo when saving. Eventually, I will also need to know how to retrieve the photo by name as well in the loadPhoto()method.

我创建了一个自定义 PhotoAlbum 类,我试图将与相册交互的所有逻辑包装起来。一旦我下载了一张照片,我就可以调用以下代码,它可以创建相册并保存照片,但是正如您将在savePhoto()方法中注意到的那样,我不知道在保存时在哪里/如何使用 photoName 变量来命名照片。最后,我还需要知道如何在loadPhoto()方法中按名称检索照片。

Thanks for any help/advice you can give me.

感谢您可以给我的任何帮助/建议。

let myAlbum = PhotoAlbum("MyAlbum") 

myAlbum.savePhoto(downloadedPhoto, 12)

class PhotoAlbum {

var albumName: String = ""
var albumExists: Bool = false
var assetCollection: PHAssetCollection!
var photosAsset: PHFetchResult!

init(albumName: String) {
    self.albumName = albumName
    self.initializeAlbum()
}

private func initializeAlbum() {

    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "title = %@", self.albumName)
    let collection: PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions)

    if let firstObject: AnyObject = collection.firstObject {
        self.albumExists = true
        self.assetCollection = collection.firstObject as! PHAssetCollection
        if let ac = self.assetCollection {
            self.photosAsset = PHAsset.fetchAssetsInAssetCollection(self.assetCollection, options: nil)
        }
        println("\(self.albumName) album exists")
    }
    else {
        var albumPlaceHolder: PHObjectPlaceholder!

        PHPhotoLibrary.sharedPhotoLibrary().performChanges({

            let request = PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle(self.albumName)
            albumPlaceHolder = request.placeholderForCreatedAssetCollection

        }, completionHandler: { (success: Bool, error: NSError!) in

            self.albumExists = success
            if success {
                let collection = PHAssetCollection.fetchAssetCollectionsWithLocalIdentifiers([albumPlaceHolder.localIdentifier], options: nil)
                self.assetCollection = collection.firstObject as! PHAssetCollection
                if let ac = self.assetCollection {
                    self.photosAsset = PHAsset.fetchAssetsInAssetCollection(self.assetCollection, options: nil)
                }
                println("\(self.albumName) album made")
            }
            else {
                println("Failed to create \(self.albumName) Album!!!!!!")
            }

        })
    }

}


func savePhoto(image: UIImage, photoID: Int) {
    let photoName = String(photoID)+".jpg"

    PHPhotoLibrary.sharedPhotoLibrary().performChanges({
        let assetRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
        let assetPlaceholder = assetRequest.placeholderForCreatedAsset
        let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection, assets: self.photosAsset)
        albumChangeRequest.addAssets([assetPlaceholder])
        }, completionHandler: { (success: Bool, error: NSError!) in

            print(success ? "image added" : "failed to add image")

    })
}

func loadPhoto(photoID: Int64) -> UIImage {
    let photoName = String(photoID)+".jpg"

    return UIImage(named: "no_photo")!
}

func renameAlbum(newAlbumName: String) {
    // need to create the new album and move all photos to that album then remove the old album

}

func reloadPhotos() {
    if let ac = self.assetCollection {
        self.photosAsset = PHAsset.fetchAssetsInAssetCollection(self.assetCollection, options: nil)
    }
}

回答by So Over It

Rather than 'naming' a file, you need to be taking a note of the localIdentifierproperty of the asset you are creating. localIdentifieris a persistent identifier (ie. it will be a consistent ID for the asset across restarts/reloads).

您需要记下localIdentifier正在创建的资产的属性,而不是“命名”文件。 localIdentifier是一个持久标识符(即,它将是重新启动/重新加载时资产的一致 ID)。

I've cobbled together some basic code that you could use to get the localIdentifierwhen saving an image, and retrieve and image by a localIdentifier. Hopefully this will get you going.

我拼凑了一些基本代码,您可以使用这些代码localIdentifier在保存图像时获取localIdentifier. 希望这会让你继续前进。

import UIKit
import Photos

class MRPhotosHelper {

    var manager = PHImageManager.defaultManager()

    func saveImageAsAsset(image: UIImage, completion: (localIdentifier:String?) -> Void) {

        var imageIdentifier: String?

        PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in
            let changeRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
            let placeHolder = changeRequest.placeholderForCreatedAsset
            imageIdentifier = placeHolder.localIdentifier
        }, completionHandler: { (success, error) -> Void in
            if success {
                completion(localIdentifier: imageIdentifier)
            } else {
                completion(localIdentifier: nil)
            }
        })
    }

    func retrieveImageWithIdentifer(localIdentifier:String, completion: (image:UIImage?) -> Void) {
        let fetchOptions = PHFetchOptions()
        fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.Image.rawValue)
        let fetchResults = PHAsset.fetchAssetsWithLocalIdentifiers([localIdentifier], options: fetchOptions)

        if fetchResults.count > 0 {
            if let imageAsset = fetchResults.objectAtIndex(0) as? PHAsset {
                let requestOptions = PHImageRequestOptions()
                requestOptions.deliveryMode = .HighQualityFormat
                manager.requestImageForAsset(imageAsset, targetSize: PHImageManagerMaximumSize, contentMode: .AspectFill, options: requestOptions, resultHandler: { (image, info) -> Void in
                    completion(image: image)
                })
            } else {
                completion(image: nil)
            }
        } else {
            completion(image: nil)
        }
    }
}

You could then do something like this:

然后你可以做这样的事情:

    // get a reference to our helper
    let helper = MRPhotosHelper()

    // a var to store the localIdentifier for the image we save
    var identifier:String?

    // save the image to library
    if let imageToSave = UIImage(named: "SomeImageName"){
        helper.saveImageAsAsset(imageToSave, completion: { (localIdentifier) -> Void in
            identifier = localIdentifier
        })
    }

    // other stuff

    // retrieve image from library at later date
    if let identifier = identifier {
        helper.retrieveImageWithIdentifer(identifier, completion: { (image) -> Void in
            let retrievedImage = image
        })
    }

You may want to check that you are back on the main thread in the completion closures before using to update the UI.

在用于更新 UI 之前,您可能需要检查您是否回到完成闭包中的主线程。