首页 > 解决方案 > Swift 中的目录不一致

问题描述

我有以下代码来获取目录并创建可以保存视频的路径:

func getOutputDirectory() -> String {
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                                                .userDomainMask,
                                                                true)
    return documentDirectory[0]
}

func append(toPath path: String, withPathComponent pathComponent: String) -> String? {
    if var pathURL = URL(string: path) {
        pathURL.appendPathComponent(pathComponent)
        return pathURL.absoluteString
    }
    return nil
}

当我想加载包含录制视频的列表时,我会调用:

func getListOfMovies() -> [String] {
    do {
        let dir = getOutputDirectory()
        let files = try FileManager().contentsOfDirectory(atPath: dir)
        var paths: [String] = []
        for file in files {
            paths.append(append(toPath: dir, withPathComponent: file)!)
        }
        return paths
    }
    catch {
            print("Could not load files")
    }
    return []
}

奇怪的是,每次我加载列表时,我都会得到不同的路径,当我尝试播放视频时它没有显示。

这是具有两个不同路径的同一文件的示例:

file:///var/mobile/Containers/Data/Application/622EE247-1695-4E40-B261-50A310F45ADB/Documents/18%252520Jul%2525202021%252520at%25252017:28:00.mov

file:///var/mobile/Containers/Data/Application/F28FBA1C-952F-4BD6-BFCA-9C5DEE8C1478/Documents/18%252520Jul%2525202021%252520at%25252017:28:00.mov

要播放视频,我有以下内容View

struct PlayVideo: View {
    var moviePath: URL?
    
    init(filePath: String) {
        moviePath = getURL(path: filePath)
    }
    var body: some View {
        VideoPlayer(player: AVPlayer(url: moviePath!))
            .frame(height: 400)
    }
}

func getURL(path: String) -> URL? {
    return URL(fileURLWithPath: path)
}

遵循 vadian 的以下建议并更改getListOfMovies()

func getListOfMovies() -> [String] {
    do {
        let files = try FileManager.default.contentsOfDirectory(at: documentDirectoryURL(), includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
        var names: [String] = []
        for file in files {
            names.append(file.lastPathComponent)
        }
        return names
    }
    catch {
        print("Unexpected error loading files: \(error).")
    }
    return []
}

终于工作了。

标签: swiftavplayer

解决方案


这种行为是正常的和有意的。容器的名称会定期更改。Documents始终只保存结构中的文件名,并在您要加载文件时获取文件夹的实际 URL

但是代码中有一个致命URL(string:)的错误,就是从文件系统路径创建 URL 的 API 错误。你必须使用URL(fileURLWithPath:)

尽管如此,我还是建议重构代码以使用与 URL 相关的 API

func documentDirectoryURL() -> URL {
    return try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
}

func fileURL(for filename: String) -> URL {
    return documentDirectoryURL().appendingPathComponent(filename)
}

推荐阅读