Listing files of a background asset

Is there a way to enumerate all files within a folder of an asset pack or just all files in general?

My application is using the Apple demo code to load a file from an Apple hosted asset pack:

let descriptor = try AssetPackManager.shared.descriptor(for: "NAV/NavData.db3")
defer {
  try descriptor.close()
}
                
if let path = path(for: descriptor) {
  self.database = try Database(path: path)
}

As my "Navigation Data" is updated each month with an updated asset pack I would like to have the name of the .db3 file reflect the current data cycle (e.g. NAV2601.db3, NAV2602.db3, ...)

Ideally I would like to iterate over all files within the NAV folder of the current asset pack and pick the most recent one.

Unfortunately, neither the AssetPackManager nor the AssetPack object seem to include an API for this.

It would be cool to have something like:

let files = try AssetPackManager.shared.files(for: "NAV/")
for file in files {
//Check and load
}
Answered by Frameworks Engineer in 872795022

Hello! There’s not currently an API to do that directly, but you can achieve the same thing with AssetPackManager.url(for:). If you pass a directory path, such as NAV/, to that method, then you can use the standard methods on FileManager from Foundation, including contentsOfDirectory(atPath:), to explore the contents of the directory at the returned URL. For example:

let url = try AssetPackManager.shared.url(for: "NAV")
let itemsInDirectory = try FileManager.default.contentsOfDirectory(atPath: url.path(percentEncoded: false))
for itemName in itemsInDirectory {
    let fullURL = url.appending(component: itemName)
    // Do something with the item at fullURL…
}

If a dedicated method in Background Assets to list the contents of a directory inside your asset packs would be useful, then please file a feedback report with details about your use case (what you mentioned in your original post should suffice) and reply to this thread with the feedback ID.

Let us know if you need further assistance!

I am also explicitly not using the contents(at:searchingInAssetPackWithID:options:) method, as this returns Data objects directly, which aren't useful in this case, as I need the actual file path to initialise these SQLite databases.

Accepted Answer

Hello! There’s not currently an API to do that directly, but you can achieve the same thing with AssetPackManager.url(for:). If you pass a directory path, such as NAV/, to that method, then you can use the standard methods on FileManager from Foundation, including contentsOfDirectory(atPath:), to explore the contents of the directory at the returned URL. For example:

let url = try AssetPackManager.shared.url(for: "NAV")
let itemsInDirectory = try FileManager.default.contentsOfDirectory(atPath: url.path(percentEncoded: false))
for itemName in itemsInDirectory {
    let fullURL = url.appending(component: itemName)
    // Do something with the item at fullURL…
}

If a dedicated method in Background Assets to list the contents of a directory inside your asset packs would be useful, then please file a feedback report with details about your use case (what you mentioned in your original post should suffice) and reply to this thread with the feedback ID.

Let us know if you need further assistance!

Thank you for this solution, this is way simpler than what I was trying to do.

For anyone who wants this behaviour for themselves, I have put the solution above in a small reusable AssetPackManager extension:

import System
import BackgroundAssets

@available(iOS 26, macOS 26, tvOS 26, *)
@available(watchOS, unavailable)
extension AssetPackManager {
    
    /// Performs a shallow search of the specified directory within all asset packs and returns the paths of any contained items.
    /// - Parameter path: The relative path to the asset pack directory whose contents you want to enumerate.
    /// - Returns: A list of `URL` objects, that identify the contents of this asset pack folder
    /// - Throws: When the path isn’t relative or when some other error occurs while retrieving the folder content.
    public nonisolated func contentsOfPack(atPath path: String) throws -> [URL] {
        let url = try AssetPackManager.shared.url(for: FilePath(stringLiteral: path))
        let itemsInDirectory = try FileManager.default.contentsOfDirectory(atPath: url.path(percentEncoded: false))
        
        var result: [URL] = []
        result.reserveCapacity(itemsInDirectory.count)
        
        for itemName in itemsInDirectory {
            let fullURL = url.appending(component: itemName)
            result.append(fullURL)
        }
        
        return result
    }
}
Listing files of a background asset
 
 
Q