Swift 中的目录不一致
Inconsistent directories in 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 []
}
终于成功了。
这种行为是正常的,是有意为之的。容器的名称会定期更改。始终只保存结构中的文件名,并在您要加载文件时将实际的 URL 放入 Documents
文件夹
但是代码中有一个致命的错误,URL(string:)
是错误的API从文件系统路径创建一个URL。你必须使用 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)
}
我有以下代码来获取一个目录并创建一个我可以保存视频的路径:
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 []
}
终于成功了。
这种行为是正常的,是有意为之的。容器的名称会定期更改。始终只保存结构中的文件名,并在您要加载文件时将实际的 URL 放入 Documents
文件夹
但是代码中有一个致命的错误,URL(string:)
是错误的API从文件系统路径创建一个URL。你必须使用 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)
}