如何在SwiftUI中将文件写入Apple Files App的文件夹中?

cuxqih21  于 2023-02-15  发布在  Swift
关注(0)|答案(3)|浏览(220)

我按照Swift项目UsingFiles github和它的video在我的SwiftUI项目中写文件,UsingFiles项目可以写文件到Files APP中,写的文件可以在Files 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中的写文件?

ajsxfq5m

ajsxfq5m1#

我用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)
    }
}
g2ieeal7

g2ieeal72#

正如我已经在评论中发布的那样,你不能以编程方式将文件保存到你的应用程序包之外。你可以使用一个UIDocumentInteractionController,并要求用户选择文件应该写入的位置。
因此,如果您使用SwiftUI,这会比常规的故事板方法稍微复杂一些,正如您在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

bxjv4tth

bxjv4tth3#

尝试添加“应用程序支持iTunes文件共享”和“支持就地打开文档”到“info.plist”。并将它们的值更改为true。

相关问题