如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?
Posted
技术标签:
【中文标题】如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?【英文标题】:Onecbowcibecbow Fhe Fhhecohwfhfwhqfohoh f 【发布时间】:2021-12-28 15:10:20 【问题描述】:我非常努力地在这里找到了类似的问题,但没有找到。那么,如何保存已使用 .fileimporter 导入的音频文件并将其保存在文档目录的文件夹中。另外如何检索它们并在 SwiftUI 的列表中显示它们的文件名?我希望我的问题足够清楚。这是我尝试过的代码。
import SwiftUI
extension FileManager
static func getDocumentsDirectory() -> URL
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
static let customFolderURL = FileManager.getDocumentsDirectory().appendingPathComponent("Music Files")
class Manager: ObservableObject
@Published var musicFiles: [URL] = []
init()
do
try FileManager.default.createDirectory(at: FileManager.customFolderURL, withIntermediateDirectories: true, attributes: nil)
catch
print("Failed to create folder")
func save(url: URL)
if url.startAccessingSecurityScopedResource()
do
let musicFile = try Data(contentsOf: url)
try musicFile.write(to: FileManager.customFolderURL, options: .atomic)
print("Success")
print(FileManager.customFolderURL)
catch
print("Failed to save the music file")
url.stopAccessingSecurityScopedResource()
else
print("Permission failed!")
func getMusicFiles()
do
let musicFiles = try FileManager.default.contentsOfDirectory(atPath: FileManager.customFolderURL.path)
print(musicFiles)
catch
print("Failed to retrieve items.")
struct MainView: View
@State private var isFileImporterShown = false
@State private var isMusicPlayerShown = false
@EnvironmentObject var manager: Manager
var body: some View
TabView
VStack
Button("Import Song")
isFileImporterShown.toggle()
.padding()
.fileImporter(isPresented: $isFileImporterShown, allowedContentTypes: [.audio], allowsMultipleSelection: true) result in
do
let url = try result.get().first!
if url.startAccessingSecurityScopedResource()
manager.save(url: url)
catch
Button("Show Player")
isMusicPlayerShown.toggle()
.padding()
.sheet(isPresented: $isMusicPlayerShown)
MusicPlayerView()
.tabItem
Image(systemName: "externaldrive")
Text("Load")
AllSongsListView()
.tabItem
Image(systemName: "music.note.list")
Text("Songs")
struct AllSongsListView: View
@EnvironmentObject var manager: Manager
var body: some View
NavigationView
List
.navigationTitle("Your Songs")
.onAppear
manager.getMusicFiles()
【问题讨论】:
【参考方案1】:保存的问题是您试图将文件保存为目录。
try musicFile.write(to: FileManager.customFolderURL, options: .atomic)
所以to
参数是文件夹路径而不是文件路径。
你需要像这样改变它:
let savePath = FileManager.customFolderURL.appendingPathComponent(url.lastPathComponent)
try musicFile.write(to: savePath, options: .atomic)
为了显示导入文件的列表,您可以执行以下操作:
List
ForEach(manager.musicFiles, id: \.self) file in
Text(file.lastPathComponent)
这是完整的例子:
import SwiftUI
extension FileManager
static func getDocumentsDirectory() -> URL
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
static let customFolderURL = FileManager.getDocumentsDirectory().appendingPathComponent("Music Files")
class Manager: ObservableObject
@Published var musicFiles: [URL] = []
static var shared = Manager()
init()
do
try FileManager.default.createDirectory(at: FileManager.customFolderURL, withIntermediateDirectories: true, attributes: nil)
catch
print("Failed to create folder:")
print(error)
func save(url: URL)
if url.startAccessingSecurityScopedResource()
do
let musicFile = try Data(contentsOf: url)
let savePath = FileManager.customFolderURL.appendingPathComponent(url.lastPathComponent)
try musicFile.write(to: savePath, options: .atomic)
print("Success")
musicFiles.append(savePath)
catch
print("Failed to save the music file:")
print(error)
url.stopAccessingSecurityScopedResource()
else
print("Permission failed!")
func getMusicFiles()
do
let musicFiles = try FileManager.default.contentsOfDirectory(atPath: FileManager.customFolderURL.path)
print(musicFiles)
catch
print("Failed to retrieve items.")
struct MainView: View
@State private var isFileImporterShown = false
@State private var isMusicPlayerShown = false
@ObservedObject var manager = Manager.shared
var body: some View
TabView
VStack
Button("Import Song")
isFileImporterShown.toggle()
.padding()
.fileImporter(isPresented: $isFileImporterShown, allowedContentTypes: [.audio], allowsMultipleSelection: true) result in
do
let url = try result.get().first!
if url.startAccessingSecurityScopedResource()
manager.save(url: url)
catch
print(error)
Button("Show Player")
isMusicPlayerShown.toggle()
.padding()
.sheet(isPresented: $isMusicPlayerShown)
Text("Musiker")
.tabItem
Image(systemName: "externaldrive")
Text("Load")
AllSongsListView()
.tabItem
Image(systemName: "music.note.list")
Text("Songs")
struct AllSongsListView: View
@ObservedObject var manager = Manager.shared
var body: some View
NavigationView
List
ForEach(manager.musicFiles, id: \.self) file in
Text(file.lastPathComponent)
.navigationTitle("Your Songs")
.onAppear
manager.getMusicFiles()
【讨论】:
以上是关于如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中使用 SFSafariViewController?
如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?