代码之家  ›  专栏  ›  技术社区  ›  swiftPunk

如何在Swift中以系统的方式为下一个用例保留选定的文件URL?

  •  1
  • swiftPunk  · 技术社区  · 1 年前

    我正在选择一个文件 fileImporter 并在应用程序中使用文件的URL。我想以某种方式保留或保存URL以供下次使用,而不必再次选择文件,因此我认为书签非常适合我使用这个 func s用于保存和阅读书签:

    func getAppDocumentDirectory() -> URL? {
        return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
    }
    
    
    func saveBookmark(url: URL, for bookmarkName: String) {
        
        if (url.startAccessingSecurityScopedResource()) {
            
            defer { url.stopAccessingSecurityScopedResource() }
            
            do {
                
                let bookmarkData = try url.bookmarkData(options: .minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
                
                if let unwrappedDocumentDirectory: URL = getAppDocumentDirectory() {
                    try bookmarkData.write(to: unwrappedDocumentDirectory.appendingPathComponent(bookmarkName))
                    print("Done!")
                }
                
            }
            catch let error {
                print(error.localizedDescription)
            }
            
        }
        else {
            print("Issue with accessing SecurityScopedResource!")
        }
        
    }
    
    func readBookmark(for bookmarkName: String, resultURL: (URL) -> Void) {
        
        do {
            
            if let unwrappedDocumentDirectory: URL = getAppDocumentDirectory() {
                
                let bookmarkURL: URL = unwrappedDocumentDirectory.appendingPathComponent(bookmarkName)
                
                if FileManager.default.fileExists(atPath: bookmarkURL.path) {
                    
                    let bookmarkData = try Data(contentsOf: bookmarkURL)
                    var isStale = false
                    let url = try URL(resolvingBookmarkData: bookmarkData, bookmarkDataIsStale: &isStale)
                    
                    if (!isStale) { resultURL(url) }
                    
                }
                else {
                    print("There is no such a bookmark exist! with name of:", bookmarkName)
                }
                
            }
            else {
                print("Issue with accessing App documentDirectory!")
            }
            
        }
        catch let error {
            print(error.localizedDescription)
        }
        
    }
    

    如果是少量文件,比如1-5个文件,我就不会有问题,那么我可以简单地使用file1、file2、file3、file4、file5 bookmarkName 但问题是,所选文件的数量可能会达到50或100个或更多,因此对我来说,跟踪1-200之间的书签名称(如file1、file2、file3等)将是一个大问题。。。,file200。对我来说,这看起来像是混乱的编码,我认为现在写的唯一可能的方法是按用户保存所选文件的数量,比如120个文件 UserDefaults 然后像这样循环120次:

    func readAll(value: Int) {
        
        for number in 1...value {
            
            readBookmark(for: "file" + String(number), resultURL: { myURL in
                
                print(myURL.lastPathComponent)
                
            })
            
        }
        
    }
    

    所以我的问题不是保存或阅读书签,而是如何以更系统的方式跟踪它们?

    1 回复  |  直到 1 年前
        1
  •  2
  •   Sweeper    1 年前

    如果我没理解错的话,你只想得到一个所有已保存书签的列表。

    书签只是 Data 。每个书签不必写入不同的文件。例如,您可以对 数据 阵列 使用 JSONEncoder ,并将其写入单个文件。然后,解码它会给你所有的书签。

    或者你可以编码一个 [String: Data] 如果你想让书签有与之关联的名称。

    第三种选择是将其存储为SwiftData模型,如

    @Model
    class Bookmark {
        var name: String
        var data: Data
    
        init(name: String, data: Data) {
            self.name = name
            self.data = data
        }
    }
    

    然后,你就可以从 ModelContext ,或a @Query .

    您仍然可以将每个书签存储为不同的文件。将它们全部存储在同一目录中,并使用 contentsOfDirectory 以取回它们。

    坦率地说,这与坚持任何其他类型的 数据 .