获取 Swift 中子目录中资源的所有 URL

Get all URLs for resources in sub-directory in Swift

我正在尝试为我的 iOS 应用程序的子目录中的所有资源创建一个 URL 数组。我似乎无法找到正确的路径,我希望即使不知道名称也能检索 URL(即我不想将文件名硬编码到代码中)。

下面是层次结构的屏幕截图,我试图获取 'test' 文件夹中的所有文件:

非常感谢任何帮助,我尝试使用文件管理器和捆绑包主路径,但到目前为止还没有成功。

这是我目前唯一的代码:

let fileManager = FileManager.default
let path = Bundle.main.urls(forResourcesWithExtension: "pdf", subdirectory: "Files/test")

print(path)

我也试过这段代码,但是它打印了所有资源,我似乎无法指定子目录:

let fm = FileManager.default
let path = Bundle.main.resourcePath!

do {
    let items = try fm.contentsOfDirectory(atPath: path)

    for item in items {
        print("Found \(item)")
    }
} catch {
    // failed to read directory – bad permissions, perhaps?
}

根据@vadian 的回答,文件夹已从虚拟组更改为真实文件夹。使用以下代码,我能够获得资源列表:

let fileManager = FileManager.default
    let path = Bundle.main.resourcePath

    let enumerator:FileManager.DirectoryEnumerator = fileManager.enumerator(atPath: "\(path!)/Files/test")!
    while let element = enumerator.nextObject() as? String {
        if element.hasSuffix("pdf") || element.hasSuffix("jpg") { // checks the extension
            print(element)
        }
    }

请考虑黄色文件夹 是虚拟 ,而不是真实文件夹(尽管 Xcode 在项目目录中创建真实文件夹)。构建应用程序时,黄色文件夹中的所有文件都会移动到捆绑包中的 Resources 目录中。

捆绑包中的真实文件夹在项目导航器中

您可以按照以下步骤获取:

  1. 在您的项目文件夹中创建一个新文件夹,扩展名为 .bundle(例如:Images.bundle)。
  2. 将资源文件复制到该新文件夹中。
  3. 将该新文件夹拖到在 Xcode 中打开的项目中。
  4. 使用以下代码片段检索 URL:

    let urls = Bundle.main.urls(forResourcesWithExtension: nil, subdirectory: "Images.bundle")
    

您还可以在此处查看指南视频:https://youtu.be/SpMaZp0ReEo

我今天遇到了类似的问题。我需要在忽略其路径的包中检索资源文​​件的 URL。 我写了以下内容:

public extension Bundle {
/// Returns the file URL for the resource identified by the specified name, searching all bundle resources.
/// - Parameter resource: The name of the resource file, including the extension.
/// - Returns: The file URL for the resource file or nil if the file could not be located.
func recurseUrl(forResource resource: String) -> URL? {
    let contents = FileManager.default.allContentsOfDirectory(atPath: self.bundlePath)
    for content in contents {
        let fileNameWithPath = NSString(string: content)
        if let fileName = fileNameWithPath.pathComponents.last {
            if resource == fileName {
                return URL(fileURLWithPath: content)
            }
        }
    }
    return nil
}

基于此:

public extension FileManager {
/// Performs a deep search of the specified directory and returns the paths of any contained items.
/// - Parameter path: The path to the directory whose contents you want to enumerate.
/// - Returns: An array of String objects, each of which identifies a file or symbolic link contained in path. Returns an empty array if the directory does not exists or has no contents.
func allContentsOfDirectory(atPath path: String) -> [String] {
    var paths = [String]()
    do {
        let url = URL(fileURLWithPath: path)
        let contents = try FileManager.default.contentsOfDirectory(atPath: path)
        
        for content in contents {
            let contentUrl = url.appendingPathComponent(content)
            if contentUrl.hasDirectoryPath {
                paths.append(contentsOf: allContentsOfDirectory(atPath: contentUrl.path))
            }
            else {
                paths.append(contentUrl.path)
            }
        }
    }
    catch {}
    return paths
}

}

这实现了检索 URL 包资源中给定资源文件名的第一个匹配项的目标,所有目录范围。 我倾向于认为 Swift 的 func url(forResource name: String?, withExtension ext: String?) -> URL? 首先应该这样做。