【问题标题】:How can I write a file in a folder located at Apple's Files App in SwiftUI?如何在 SwiftUI 中位于 Apple Files App 的文件夹中写入文件?
【发布时间】:2020-06-12 15:44:14
【问题描述】:

我按照 Swift 项目 UsingFiles github 及其 video 在我的 SwiftUI 项目中写入文件。 UsingFiles 项目可以将文件写入文件 APP,然后在文件 APP 中可以看到正在写入的文件。但是我按照下面的代码,在Files APP中看不到文件。

let file = "\(UUID().uuidString).txt"
let contents = "Some text..."

let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = dir.appendingPathComponent(file)

do {
    try contents.write(to: fileURL, atomically: false, encoding: .utf8)
}
catch {
    print("Error: \(error)")
}

UsingFiles 写入文件是file:///Users/fmac/Library/Developer/CoreSimulator/Devices/11111111-881E-488A-9571-E61B83EB6062/data/Containers/Data/Application/11111111-AF89-4B15-B3B5-E13A63A19F8D/Documents/E018F056-83EA-4D70-87C4-16F755AA404A.txt

我的写作文件是file:///Users/fmac/Library/Developer/CoreSimulator/Devices/11111111-881E-488A-9571-E61B83EB6062/data/Containers/Data/Application/11111111-B191-4ACD-98B1-004E619C2EC7/Documents/C9E0F52E-040F-4647-94A3-88E0DA171AB5.txt

我可以在UsingFiles目录下找到UsingFiles的写入文件,如下:

但是我在我的 SwiftUI 项目的 Files APP 中找不到写入文件。 SwiftUI 中的代码有问题吗?为什么我在Files APP中找不到写入文件?

【问题讨论】:

  • “我在Files APP中找不到写入文件”是什么意思?您的文件显示在 onMyPhone 位置
  • @Leo,我的意思是文件不在 onMyPhone 中。我在手机上找不到文件。
  • 您已发布文件的屏幕截图。它在您的文档目录中。
  • 您的文件不在文件应用程序中。它已经在您的文档中。您必须学习如何浏览/列出您的文件
  • 无法以编程方式将文件保存在 APP Bundle 之外。您需要让用户选择位置stackoverflow.com/questions/46456481/…

标签: ios swift swiftui


【解决方案1】:

我使用 UIActivityViewController 在手机上保存文件。 这很简单而且很有效。

import SwiftUI

struct ContentView: View {

    var body: some View {
        Button(action: wirtieFile) {
            Image(systemName: "square.and.arrow.up")
        }
    }

    func wirtieFile() -> Void{
        let file = "test.txt"
        let dir = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(file)
        let contents = "test..."
        do {
           try contents.write(to: dir!, atomically: true, encoding: .utf8)
        } catch {
           print(error.localizedDescription)
        }
        var filesToShare = [Any]()
        filesToShare.append(dir!)
        let av = UIActivityViewController(activityItems: filesToShare, applicationActivities: nil)
        UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
    }
}

【讨论】:

    【解决方案2】:

    正如我已经在 cmets 中发布的那样,您不能以编程方式将文件保存在您的 APP Bundle 之外。您可以使用UIDocumentInteractionController 并要求用户选择应该写入文件的位置。

    因此,如果您使用 SwiftUI,这将比常规 Storyboard 方法复杂一些,正如您在 post 中看到的那样,因为您需要为 UIDocumentInteractionController 实现 UIViewControllerRepresentable


    struct DocumentInteractionController: UIViewControllerRepresentable {
    
        fileprivate var isExportingDocument: Binding<Bool>
        fileprivate let viewController = UIViewController()
        fileprivate let documentInteractionController: UIDocumentInteractionController
    
        init(_ isExportingDocument: Binding<Bool>, url: URL) {
            self.isExportingDocument = isExportingDocument
            documentInteractionController = .init(url: url)
        }
    
        func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentInteractionController>) -> UIViewController { viewController }
    
        func updateUIViewController(_ controller: UIViewController, context: UIViewControllerRepresentableContext<DocumentInteractionController>) {
            if isExportingDocument.wrappedValue && documentInteractionController.delegate == nil {
                documentInteractionController.uti = documentInteractionController.url?.typeIdentifier ?? "public.data, public.content"
                documentInteractionController.name = documentInteractionController.url?.localizedName
                documentInteractionController.presentOptionsMenu(from: controller.view.frame, in: controller.view, animated: true)
                documentInteractionController.delegate = context.coordinator
                documentInteractionController.presentPreview(animated: true)
            }
        }
    
        func makeCoordinator() -> Coordintor { .init(self) }
    }
    

    及其协调员:

    class Coordintor: NSObject, UIDocumentInteractionControllerDelegate {
        let documentInteractionController: DocumentInteractionController
        init(_ controller: DocumentInteractionController) {
            documentInteractionController = controller
        }
        func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController { documentInteractionController.viewController }
    
        func documentInteractionControllerDidDismissOptionsMenu(_ controller: UIDocumentInteractionController) {
            controller.delegate = nil
            documentInteractionController.isExportingDocument.wrappedValue = false
        }
    }
    

    现在您可以创建 DocumentInteraction 视图及其预览:

    struct DocumentInteraction: View {
        @State private var isExportingDocument = false
        var body: some View {
            VStack {
                Button("Export Document") { self.isExportingDocument = true }
                .background(DocumentInteractionController($isExportingDocument,
                    url: Bundle.main.url(forResource: "sample", withExtension: "pdf")!))
            }
        }
    }
    
    struct DocumentInteraction_Previews: PreviewProvider {
        static var previews: some View { DocumentInteraction() }
    }
    

    你也需要这些助手:

    extension URL {
        var typeIdentifier: String? { (try? resourceValues(forKeys: [.typeIdentifierKey]))?.typeIdentifier }
        var localizedName: String? { (try? resourceValues(forKeys: [.localizedNameKey]))?.localizedName }
    }
    

    Sample project

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      • 2010-11-14
      • 2015-09-03
      • 2018-12-30
      相关资源
      最近更新 更多