我试图在这里找到一个类似的问题,但是找不到,所以,如何保存使用.fileimporter导入的音频文件,并将其保存在documents目录中的文件夹中。另外,如何检索它们并在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()
}
}
}
}
发布于 2021-12-28 17:50:28
保存的问题在于您试图将文件保存为一个目录。
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()
}
}
}
}
https://stackoverflow.com/questions/70508923
复制相似问题