You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift实现从本地Files应用加载音乐文件至Player应用

加载Files应用中的音乐到自定义Player应用

要实现这个需求,需要结合iOS的文件访问机制和权限配置,以下是具体步骤:

1. 配置APP的文件访问权限

先在Info.plist中添加必要配置,让APP具备文件访问能力:

  • 添加UIFileSharingEnabled并设为YES:允许用户通过Files应用的「我的iPhone」目录访问APP的文档文件夹
  • 添加LSSupportsOpeningDocumentsInPlace并设为YES:支持直接访问原地文件(无需复制到APP沙盒)
  • 如果需要访问iCloud Drive中的音乐,添加NSUbiquitousContainers配置,填入你的iCloud容器ID(开发者后台获取)

2. 获取音乐文件的两种方式

方式一:让用户选择Files中的音乐(推荐,符合iOS权限规范)

iOS沙盒限制APP不能直接遍历整个Files应用,必须通过UIDocumentPickerViewController让用户主动选择文件,之后保存授权的文件路径,启动时自动加载:

// 打开文件选择器,仅允许选择音频文件
func openMusicPicker() {
    let picker = UIDocumentPickerViewController(documentTypes: ["public.audio"], in: .import)
    picker.delegate = self
    picker.allowsMultipleSelection = true
    present(picker, animated: true)
}

// 处理用户选择的文件
extension YourViewController: UIDocumentPickerDelegate {
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        // 保存文件的安全书签(避免APP重启后路径失效)
        urls.forEach { saveBookmark(for: $0) }
        // 加载文件到播放器
        loadMusicToPlayer(from: urls)
    }
}

// 保存文件安全书签
func saveBookmark(for url: URL) {
    do {
        let bookmarkData = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
        UserDefaults.standard.set(bookmarkData, forKey: "MusicBookmark_\(url.lastPathComponent)")
    } catch {
        print("保存书签失败:\(error)")
    }
}

// APP启动时恢复书签并加载音乐
func loadSavedMusicOnLaunch() {
    let defaults = UserDefaults.standard
    let savedKeys = defaults.dictionaryRepresentation().keys.filter { $0.starts(with: "MusicBookmark_") }
    var musicURLs = [URL]()
    
    savedKeys.forEach { key in
        guard let data = defaults.data(forKey: key) else { return }
        var isStale = false
        do {
            let url = try URL(resolvingBookmarkData: data, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
            if isStale { try saveBookmark(for: url) }
            url.startAccessingSecurityScopedResource()
            musicURLs.append(url)
            defer { url.stopAccessingSecurityScopedResource() }
        } catch {
            print("恢复书签失败:\(error)")
        }
    }
    
    loadMusicToPlayer(from: musicURLs)
}

// 将音乐文件加载到播放器的核心逻辑
func loadMusicToPlayer(from urls: [URL]) {
    // 遍历URL,提取文件名、时长等信息,添加到播放列表数据源
    for url in urls {
        let musicTitle = url.lastPathComponent.replacingOccurrences(of: ".\(url.pathExtension)", with: "")
        // 示例:添加到你的播放列表数组
        // playList.append(MusicModel(title: musicTitle, url: url))
    }
    // 刷新UI(比如tableView.reloadData())
}

方式二:遍历APP自身的文档目录(Files中「我的iPhone」下的APP文件夹)

如果用户已经把音乐文件放到你的APP专属文件夹中,可以直接用FileManager遍历该目录:

func loadMusicFromAppDocuments() {
    guard let docsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
    do {
        let allFiles = try FileManager.default.contentsOfDirectory(at: docsURL, includingPropertiesForKeys: nil)
        // 筛选音频文件
        let musicFiles = allFiles.filter { url in
            guard let uti = try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier else { return false }
            return UTTypeConformsTo(uti as CFString, kUTTypeAudio)
        }
        loadMusicToPlayer(from: musicFiles)
    } catch {
        print("读取文档目录失败:\(error)")
    }
}

注意事项

  • 必须遵守iOS权限规则,不能绕过用户授权直接访问Files中的任意文件,否则APP会被拒审
  • 安全书签(bookmark)是持久化访问用户授权文件的唯一可靠方式,直接保存文件路径会导致APP重启后无法访问
  • 如果需要支持后台扫描文件变化,可以结合NSMetadataQuery监听文档目录的变化

内容的提问来源于stack exchange,提问作者Pavel Mishanin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:20:41