我正在开发一个iOS应用程序(最新的Swift、iOS、Xcode版本的atm写作),它需要重命名位于任何地方(本地存储、外部存储、云等)的音频文件(稍后修改其元数据)。
  
  
   当试图重命名某个文件夹中的文件时,在物理设备上进行测试时会出现问题
   
    在我的iPhone上
   
   ,该应用程序在模拟器上测试时按预期操作。在我的实体iPhone上,我收到一个错误日志,说我没有权限这样做。
  
  
   
    âfilename.mp3â couldnât be moved because you donât have permission to access ârandomFolder".
   
  
  
   我在谷歌上搜索并询问了GPT,了解了
   
    FileCoordinator
   
   ,
   
    UIDocumentPickerViewController
   
   ,
   
    startAccessingSecurityScopedResource
   
   。我也看到了
   
    this video
   
   ,并最终遵循了这一点
   
    other one
   
   .
  
  
   我有一些代码:
  
  
   这是文档选择器,然后我从
   
    .sheet
   
   在另一个视图上。
  
  struct DocumentPicker: UIViewControllerRepresentable {
    @Binding var newName: String
    @EnvironmentObject private var bookmarkController: BookmarkController
    
    func makeUIViewController(context: Context) -> UIDocumentPickerViewController {
        let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes)
        documentPicker.delegate = context.coordinator
        return documentPicker
    }
    
    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: Context) {
        print("updateUIViewController documentPicker")
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(self, newName)
    }
    class Coordinator: NSObject, UIDocumentPickerDelegate {
        var parent: DocumentPicker
        var newName: String
        
        init(_ parent: DocumentPicker, _ newName: String = "") {
            self.parent = parent
            self.newName = newName
        }
        
        func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
            // save bookmark
            print("documentPicker \(urls[0])")
            parent.bookmarkController.addBookmark(for: urls[0])
            
            // Rename the file
            var error: NSError?
            
            NSFileCoordinator().coordinate(readingItemAt: urls[0], options: [], error: &error) { coordinatedURL in
                do {
                    //                let data = try Data(contentsOf: newURL)
                    print("urls[0]: \(urls[0])")
                    print("coordinatedURL: \(coordinatedURL)")
                    print("renamedURL: \(newName)")
                    try renameFile(at: coordinatedURL, to: newName)
} catch  {
                    print("Error: \(error.localizedDescription)")
                }   
            }
        }
    }
}
  
   重命名功能:
  
  
/// Rename selected file from browser
func renameFile(at fileURL: URL, to newName: String) throws {
    let fileExtension = fileURL.pathExtension
    let directory = fileURL.deletingLastPathComponent()
    // Create a new URL with the updated name and the original extension
    let renamedURL = directory.appendingPathComponent(newName).appendingPathExtension(fileExtension)
    try FileManager.default.moveItem(at: fileURL, to: renamedURL)
}
  
   我有一个
   
    BookmarkController
   
   与我上面提到的第二个视频中的位置相同,这样我的URL就会被标记为书签以供以后使用。它在这里:
  
  import SwiftUI
import MobileCoreServices
class BookmarkController: ObservableObject {
    @Published var urls: [URL] = []
    
    init() {
        loadAllBookmarks()
    }
    
    func addBookmark(for url: URL) {
        print("adding bookmark for \(url)")
        do {
            guard url.startAccessingSecurityScopedResource() else {
                print("Failed to obtain access to the security-scoped resource.")
                return
            }
            
            defer { url.stopAccessingSecurityScopedResource() }
            
            let bookmarkData = try url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil)
            
            let uuid = UUID().uuidString
            try bookmarkData.write(to: getAppSandboxDir().appendingPathComponent(uuid))
            
            urls.append(url)
        } catch {
            print("Error Adding Bookmark: \(error.localizedDescription)")
        }
    }
    
    func loadAllBookmarks() {
        // Get all the bookmark files
        let files = try? FileManager.default.contentsOfDirectory(at: getAppSandboxDir(), includingPropertiesForKeys: nil)
        // Map over the bookmark files
        self.urls = files?.compactMap { file in
            do {
                let bookmarkData = try Data(contentsOf: file)
                var isStale = false
                // Get the URL from each bookmark
                let url = try URL(resolvingBookmarkData: bookmarkData, bookmarkDataIsStale: &isStale)
                
                guard !isStale else {
                    // Handle stale bookmarks
                    return nil
                }
                print("loaded bookmark: \(url)")
                // Return URL
                return url
            } catch {
                print("Error Loading Bookmark: \(error.localizedDescription)")
                return nil
            }
        } ?? []
    }
    
    private func getAppSandboxDir() -> URL {
        // TODO ver 0 index
        FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    }
}
  
   在我的设备上运行时,我看到
   
    url.startAccessingSecurityScopedResource
   
   投掷:
  
  
   
    Failed to obtain access to the security-scoped resource.
   
  
  
   我还尝试过访问父目录,如下所示:
  
  
   
    let parentURL = url.deletingLastPathComponent()
   
  
  
   然后使用
   
    parentURL
   
   相反,它也失败了。
  
  
  
   我注意到我的应用程序没有显示在
   
    设置->隐私&安全性->文件和文件夹
   
   列表在用户同意的情况下,我的应用程序没有触发任何对话框添加到此处。
  
  
   在中玩弄权利
   
    Info.plist
   
   和Capabilities也没有帮助,但我不太确定应该添加哪些。
  
  
   所以:
  
  
   我看到的权限问题和我的应用程序没有出现在iPhone的“文件和文件夹”隐私设置中,可能是因为我的应用是用不在苹果开发者程序中的开发者帐户签名的吗?这是我最后的想法,因为我不明白我还应该尝试什么。
  
  
   任何建议和帮助都将不胜感激。
谢谢