swift “-[UIDocumentPickerViewController initWithDocumentTypes:inMode:]只能在Import或Open模式下调用”

z4iuyo4d  于 2023-04-04  发布在  Swift
关注(0)|答案(2)|浏览(336)

我试图通过允许用户在他们的文件应用程序中选择一个位置来放置导出的zip文件,从而启用从SwiftUI应用程序导出数据的功能。当我尝试DocumentPickerView时,我遇到了这个错误。我已经查看了UIDocumentMenuViewController initWithDocumentTypes:inMode: can only be called with mode Import or Open,但即使他接受了答案,我似乎也无法解决如何调整语法以符合修改后的init
下面是我的代码:

struct DocumentPickerView: UIViewControllerRepresentable {
    let completion: (URL) -> Void
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<DocumentPickerView>) -> UIDocumentPickerViewController {
        let exportPicker = UIDocumentPickerViewController(documentTypes: [kUTTypeZipArchive as String], in: .exportToService)
        exportPicker.delegate = context.coordinator
        exportPicker.modalPresentationStyle = .formSheet
        return exportPicker
    }
    
    func updateUIViewController(_ uiViewController: UIDocumentPickerViewController, context: UIViewControllerRepresentableContext<DocumentPickerView>) {
    }
    
    func makeCoordinator() -> DocumentPickerCoordinator {
        return DocumentPickerCoordinator(completion: completion)
    }
}

class DocumentPickerCoordinator: NSObject, UIDocumentPickerDelegate {
    let completion: (URL) -> Void
    
    init(completion: @escaping (URL) -> Void) {
        self.completion = completion
    }
    
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        guard let exportURL = urls.first else {
            print("No URL selected for export")
            return
        }
        
        completion(exportURL)
    }
}

我的导出函数看起来像这样:

func exportDataAsZip(to url: URL) {
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        
        // Creating a ZIP archive
        guard SSZipArchive.createZipFile(atPath: url.path, withContentsOfDirectory: documentsDirectory.path) else {
            print("Failed to create ZIP archive")
            return
        }
        
        // Exporting images from Core Data
        let fileManager = FileManager.default
        let managedObjectContext = PersistenceController.shared.container.viewContext
        let fetchRequest: NSFetchRequest<CapturedImage> = CapturedImage.fetchRequest()
        do {
            let images = try managedObjectContext.fetch(fetchRequest)
            for image in images {
                if let imageData = image.image, let timestamp = image.timestamp {
                    let dateFormatter = ISO8601DateFormatter()
                    let dateString = dateFormatter.string(from: timestamp)
                    let imageUrl = url.appendingPathComponent("\(dateString).jpg")
                    try imageData.write(to: imageUrl)
                }
            }
        } catch {
            print("Failed to fetch images from Core Data")
            return
        }
        
        // Adding images to the ZIP archive
        let imageUrls = try! fileManager.contentsOfDirectory(at: url, includingPropertiesForKeys: nil)
        for imageUrl in imageUrls {
            if imageUrl.pathExtension == "jpg" {
                let success = SSZipArchive.createZipFile(atPath: url.path, withFilesAtPaths: [imageUrl.path])
                if !success {
                    print("Failed to add image to ZIP archive")
                }
            }
        }
        
        print("Exported data to: \(url.path)")
    }
}

我使用sheet修饰符调用视图:

.sheet(isPresented: $isShowingExportSheet, onDismiss: nil, content: {
    DocumentPickerView(completion: { url in
        exportDataAsZip(to: url)
    })
})

感谢任何意见!

rhfm7lfc

rhfm7lfc1#

当您希望使用UIDocumentPickerViewController进行导出时,您需要使用init(forExporting:)init(forExporting:asCopy:)初始化器。如果您需要支持iOS 13或更早版本,则使用init(url:in:)init(urls:in:)
旧的初始化器init(documentTypes:in:)只用于导入,而不是导出。
你的整个设置有点落后。你的代码当前在那里选择一个文件,并使用所选的URL调用完成回调。该设置用于导入。对于导出,你需要从要导出的文件的URL开始,然后使用你希望导出的URL创建UIDocumentPickerViewController。你不需要带有URL的完成块。

相关问题