diff --git a/App/App_iOS.swift b/App/App_iOS.swift index 54cd06c8..c233daea 100644 --- a/App/App_iOS.swift +++ b/App/App_iOS.swift @@ -41,6 +41,7 @@ struct Kiwix: App { .environmentObject(navigation) .modifier(AlertHandler()) .modifier(OpenFileHandler()) + .modifier(SaveContentHandler()) .onChange(of: scenePhase) { newValue in guard newValue == .inactive else { return } try? Database.viewContext.save() diff --git a/Views/ViewModifiers/SaveContentHandler.swift b/Views/ViewModifiers/SaveContentHandler.swift index c1ebce55..5c9aa320 100644 --- a/Views/ViewModifiers/SaveContentHandler.swift +++ b/Views/ViewModifiers/SaveContentHandler.swift @@ -19,6 +19,9 @@ import SwiftUI struct SaveContentHandler: ViewModifier { private let saveContentToFile = NotificationCenter.default.publisher(for: .saveContent) + #if os(iOS) + @State private var urlAndContent: (URL, URLContent)? = nil + #endif func body(content: Content) -> some View { content.onReceive(saveContentToFile) { notification in @@ -27,18 +30,80 @@ struct SaveContentHandler: ViewModifier { return } #if os(macOS) - let savePanel = NSSavePanel() - savePanel.canCreateDirectories = true - savePanel.nameFieldStringValue = url.lastPathComponent - savePanel.begin { (response: NSApplication.ModalResponse) in - if case .OK = response, - let urlContent = ZimFileService.shared.getURLContent(url: url), - let destinationURL = savePanel.url { - try? urlContent.data.write(to: destinationURL) - savePanel.close() - } + savePanelFor(url: url) + #else + if let urlContent = ZimFileService.shared.getURLContent(url: url) { + urlAndContent = (url, urlContent) + } else { + urlAndContent = nil } #endif } +#if os(iOS) + .sheet( + isPresented: Binding.constant($urlAndContent.wrappedValue != nil), + onDismiss: { + if let (url, _) = urlAndContent, + let tempURL = url.tempFileURL() { + try? FileManager.default.removeItem(at: tempURL) + } + urlAndContent = nil + }, content: { + if let (url, urlContent) = urlAndContent { + if let tempURL = url.tempFileURL(), + (try? urlContent.data.write(to: tempURL)) != nil { + ActivityViewController(activityItems: [tempURL]) + } + } + } + ) +#endif + } + + #if os(macOS) + private func savePanelFor(url: URL) { + let savePanel = NSSavePanel() + savePanel.canCreateDirectories = true + savePanel.nameFieldStringValue = url.lastPathComponent + savePanel.begin { (response: NSApplication.ModalResponse) in + if case .OK = response, + let urlContent = ZimFileService.shared.getURLContent(url: url), + let destinationURL = savePanel.url { + try? urlContent.data.write(to: destinationURL) + savePanel.close() + } + } + } + #endif +} + +#if os(iOS) +struct ActivityViewController: UIViewControllerRepresentable { + + var activityItems: [Any] + @Environment(\.dismiss) var dismissAction + func makeUIViewController(context: UIViewControllerRepresentableContext) -> UIActivityViewController { + let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil) + controller.modalPresentationStyle = .pageSheet + controller.completionWithItemsHandler = { (activityType, completed, returnedItems, error) in + self.dismissAction() + } + return controller + } + + func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) { + } +} + +#endif + +extension URL { + fileprivate func tempFileURL() -> URL? { + let directory = FileManager.default.temporaryDirectory + if #available(macOS 13.0, iOS 16.0, *) { + return directory.appending(path: lastPathComponent) + } else { + return directory.appendingPathComponent(lastPathComponent) + } } }