4

我正在关注 Apple 的示例代码“ ExampleappusingPhotosframework ”。

在 PHAssets/PHAssetCollection 的主题中,我注意到存在“文件夹”的可能性。这些可以从被创建为 Mac 的照片应用程序或较旧的 iPhoto 应用程序等出现。...

有可能存在一个文件夹数量为 PHAssetCollection,并且该文件夹可能包含未知级别的嵌套文件夹,最后以专辑结尾。

因此,如果我在照片库中有嵌套文件夹,即使上面的示例项目也会崩溃。大多数应用程序似乎只是忽略并且根本不显示这些文件夹。

举个例子,假设这个例子存在:

在此处输入图像描述

文件夹级别 1 > 文件夹级别 2 > 自定义相册 > Image1, Image2

iOS 照片应用程序如何处理它:

在此处输入图像描述

任务

在 Root Album 列表中的用户相册下,应该可以看到“Folder Level 1”。点击后,我想列出所有子文件夹中的所有图像,无论子级别如何.....

视图加载

override func viewDidLoad() {
    super.viewDidLoad()

    let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(self.addAlbum))
    self.navigationItem.rightBarButtonItem = addButton


    // Create a PHFetchResult object for each section in the table view.
    let allPhotosOptions = PHFetchOptions()
    allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
    allPhotos = PHAsset.fetchAssets(with: allPhotosOptions)
    smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
    userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil)
    PHPhotoLibrary.shared().register(self)

}

cellForRowAt

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    switch Section(rawValue: indexPath.section)! {
        case .allPhotos:
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.allPhotos.rawValue, for: indexPath)
            cell.textLabel!.text = NSLocalizedString("All Photos", comment: "")
            return cell

        case .smartAlbums:
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.collection.rawValue, for: indexPath)
            let collection = smartAlbums.object(at: indexPath.row)
            cell.textLabel!.text = collection.localizedTitle
            return cell

        case .userCollections:
            let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.collection.rawValue, for: indexPath)
            let collection = userCollections.object(at: indexPath.row)

            cell.textLabel!.text = collection.localizedTitle
            return cell
    }
}

转场

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    guard let destination = (segue.destination as? UINavigationController)?.topViewController as? AssetGridViewController
        else { fatalError("unexpected view controller for segue") }
    let cell = sender as! UITableViewCell

    destination.title = cell.textLabel?.text

    switch SegueIdentifier(rawValue: segue.identifier!)! {
        case .showAllPhotos:
            destination.fetchResult = allPhotos
        case .showCollection:

            // get the asset collection for the selected row
            let indexPath = tableView.indexPath(for: cell)!
            let collection: PHCollection
            switch Section(rawValue: indexPath.section)! {
                case .smartAlbums:
                    collection = smartAlbums.object(at: indexPath.row)
                case .userCollections:
                    collection = userCollections.object(at: indexPath.row)
                default: return // not reached; all photos section already handled by other segue
            }

            // configure the view controller with the asset collection
            guard let assetCollection = collection as? PHAssetCollection
                else { fatalError("expected asset collection") }
            destination.fetchResult = PHAsset.fetchAssets(in: assetCollection, options: nil)
            destination.assetCollection = assetCollection
    }
}

问题

资产集合?canContainCollections似乎是决定因素。但是,无论子级别/子文件夹如何,我将如何获取文件夹中包含的所有 PHAsset?(这不可能是不可能的,因为即使股票应用程序在 1 级内也有“所有照片”)

4

1 回答 1

3

使用当前的开发人员 API (PhotoKit),没有简单的方法(例如使用单个请求)来列出文件夹(及其子文件夹/相册)中的所有资产。但是,您可以递归枚举文件夹中的所有专辑及其子文件夹,然后将结果放入单个数组中。但是,这可能会很慢,具体取决于嵌套结构中包含的级别和资产的数量。请注意,任何级别的文件夹也可以包含一个专辑(例如,在“文件夹级别 1”上,除了文件夹“文件夹级别 2”之外,还可能有一个专辑)。Apple 的照片应用程序没有使用 PhotoKit - 所以我认为他们有办法通过一个请求来做到这一点。

于 2017-02-09T08:41:16.413 回答