我试图通过允许用户在他们的文件应用程序中选择一个位置来放置导出的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)
})
})
感谢任何意见!
2条答案
按热度按时间rhfm7lfc1#
当您希望使用
UIDocumentPickerViewController
进行导出时,您需要使用init(forExporting:)
或init(forExporting:asCopy:)
初始化器。如果您需要支持iOS 13或更早版本,则使用init(url:in:)
或init(urls:in:)
。旧的初始化器
init(documentTypes:in:)
只用于导入,而不是导出。你的整个设置有点落后。你的代码当前在那里选择一个文件,并使用所选的URL调用完成回调。该设置用于导入。对于导出,你需要从要导出的文件的URL开始,然后使用你希望导出的URL创建
UIDocumentPickerViewController
。你不需要带有URL的完成块。xoshrz7s2#
要在SwiftUI中导出,可以使用fileExporter(isPresented:document:contentType:defaultFilename:onCompletion:)