Exporting: Refactor out zip exporting into a separate class
Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
parent
d556729705
commit
1dac181803
|
@ -39,6 +39,7 @@
|
||||||
6FDEF806218725D200D8FBF6 /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */; };
|
6FDEF806218725D200D8FBF6 /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */; };
|
||||||
6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */; };
|
6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */; };
|
||||||
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; };
|
6FE254FB219C10800028284D /* ZipImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FA219C10800028284D /* ZipImporter.swift */; };
|
||||||
|
6FE254FF219C60290028284D /* ZipExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE254FE219C60290028284D /* ZipExporter.swift */; };
|
||||||
6FF4AC1F211EC472002C96EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC1E211EC472002C96EB /* Assets.xcassets */; };
|
6FF4AC1F211EC472002C96EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC1E211EC472002C96EB /* Assets.xcassets */; };
|
||||||
6FF4AC22211EC472002C96EB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC20211EC472002C96EB /* LaunchScreen.storyboard */; };
|
6FF4AC22211EC472002C96EB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC20211EC472002C96EB /* LaunchScreen.storyboard */; };
|
||||||
6FFA5D8921942F320001E2F7 /* PacketTunnelSettingsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C472183C6A3000F85AD /* PacketTunnelSettingsGenerator.swift */; };
|
6FFA5D8921942F320001E2F7 /* PacketTunnelSettingsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C472183C6A3000F85AD /* PacketTunnelSettingsGenerator.swift */; };
|
||||||
|
@ -127,6 +128,7 @@
|
||||||
6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; };
|
6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = "<group>"; };
|
||||||
6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WgQuickConfigFileWriter.swift; sourceTree = "<group>"; };
|
6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WgQuickConfigFileWriter.swift; sourceTree = "<group>"; };
|
||||||
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
|
6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = "<group>"; };
|
||||||
|
6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = "<group>"; };
|
||||||
6FF4AC14211EC46F002C96EB /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
6FF4AC14211EC46F002C96EB /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
6FF4AC1E211EC472002C96EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
6FF4AC1E211EC472002C96EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
6FF4AC21211EC472002C96EB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
6FF4AC21211EC472002C96EB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
|
@ -269,6 +271,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
6FE254FA219C10800028284D /* ZipImporter.swift */,
|
6FE254FA219C10800028284D /* ZipImporter.swift */,
|
||||||
|
6FE254FE219C60290028284D /* ZipExporter.swift */,
|
||||||
6FDEF801218646B900D8FBF6 /* ZipArchive.swift */,
|
6FDEF801218646B900D8FBF6 /* ZipArchive.swift */,
|
||||||
6FDEF7F421863B6100D8FBF6 /* 3rdparty */,
|
6FDEF7F421863B6100D8FBF6 /* 3rdparty */,
|
||||||
);
|
);
|
||||||
|
@ -520,6 +523,7 @@
|
||||||
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
|
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
|
||||||
6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */,
|
6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */,
|
||||||
6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */,
|
6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */,
|
||||||
|
6FE254FF219C60290028284D /* ZipExporter.swift in Sources */,
|
||||||
6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
|
6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
|
||||||
6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */,
|
6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */,
|
||||||
6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,
|
6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,
|
||||||
|
|
|
@ -32,6 +32,12 @@ class ErrorPresenter {
|
||||||
case ZipImporterError.noTunnelsInZipArchive:
|
case ZipImporterError.noTunnelsInZipArchive:
|
||||||
return ("No tunnels in zip archive", "No .conf tunnel files were found inside the zip archive.")
|
return ("No tunnels in zip archive", "No .conf tunnel files were found inside the zip archive.")
|
||||||
|
|
||||||
|
// Exporting a zip file
|
||||||
|
case ZipArchiveError.cantOpenOutputZipFileForWriting:
|
||||||
|
return ("Unable to create zip archive", "Could not create a zip file in the app's document directory.")
|
||||||
|
case ZipExporterError.noTunnelsToExport:
|
||||||
|
return ("Nothing to export", "There are no tunnels to export")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
os_log("ErrorPresenter: Error not presented: %{public}@", log: OSLog.default, type: .error, "\(error)")
|
os_log("ErrorPresenter: Error not presented: %{public}@", log: OSLog.default, type: .error, "\(error)")
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -63,20 +63,7 @@ class SettingsTableViewController: UITableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
func exportConfigurationsAsZipFile(sourceView: UIView) {
|
func exportConfigurationsAsZipFile(sourceView: UIView) {
|
||||||
guard let tunnelsManager = tunnelsManager, tunnelsManager.numberOfTunnels() > 0 else {
|
guard let tunnelsManager = tunnelsManager else { return }
|
||||||
showErrorAlert(title: "Nothing to export", message: "There are no tunnels to export")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var inputsToArchiver: [(fileName: String, contents: Data)] = []
|
|
||||||
for i in 0 ..< tunnelsManager.numberOfTunnels() {
|
|
||||||
guard let tunnelConfiguration = tunnelsManager.tunnel(at: i).tunnelConfiguration() else { continue }
|
|
||||||
if let contents = WgQuickConfigFileWriter.writeConfigFile(from: tunnelConfiguration) {
|
|
||||||
let name = tunnelConfiguration.interface.name
|
|
||||||
assert(name != tunnelsManager.tunnel(at: i - 1).name)
|
|
||||||
inputsToArchiver.append((fileName: "\(name).conf", contents: contents))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let destinationDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
guard let destinationDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -87,16 +74,19 @@ class SettingsTableViewController: UITableViewController {
|
||||||
os_log("Failed to delete file: %{public}@ : %{public}@", log: OSLog.default, type: .error, destinationURL.absoluteString, error.localizedDescription)
|
os_log("Failed to delete file: %{public}@ : %{public}@", log: OSLog.default, type: .error, destinationURL.absoluteString, error.localizedDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let count = tunnelsManager.numberOfTunnels()
|
||||||
|
let tunnelConfigurations = (0 ..< count).compactMap { tunnelsManager.tunnel(at: $0).tunnelConfiguration() }
|
||||||
do {
|
do {
|
||||||
try ZipArchive.archive(inputs: inputsToArchiver, to: destinationURL)
|
try ZipExporter.exportConfigFiles(tunnelConfigurations: tunnelConfigurations, to: destinationURL)
|
||||||
|
} catch (let error) {
|
||||||
|
ErrorPresenter.showErrorAlert(error: error, from: self)
|
||||||
|
}
|
||||||
|
|
||||||
let activityVC = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
|
let activityVC = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
|
||||||
// popoverPresentationController shall be non-nil on the iPad
|
// popoverPresentationController shall be non-nil on the iPad
|
||||||
activityVC.popoverPresentationController?.sourceView = sourceView
|
activityVC.popoverPresentationController?.sourceView = sourceView
|
||||||
activityVC.popoverPresentationController?.sourceRect = sourceView.bounds
|
activityVC.popoverPresentationController?.sourceRect = sourceView.bounds
|
||||||
present(activityVC, animated: true)
|
present(activityVC, animated: true)
|
||||||
} catch (let error) {
|
|
||||||
showErrorAlert(title: "Unable to export", message: "There was an error exporting the tunnel configuration archive: \(String(describing: error))")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func showErrorAlert(title: String, message: String) {
|
func showErrorAlert(title: String, message: String) {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// Copyright © 2018 WireGuard LLC. All Rights Reserved.
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
enum ZipExporterError: Error {
|
||||||
|
case noTunnelsToExport
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZipExporter {
|
||||||
|
static func exportConfigFiles(tunnelConfigurations: [TunnelConfiguration], to destinationURL: URL) throws {
|
||||||
|
|
||||||
|
guard (!tunnelConfigurations.isEmpty) else { throw ZipExporterError.noTunnelsToExport }
|
||||||
|
|
||||||
|
var inputsToArchiver: [(fileName: String, contents: Data)] = []
|
||||||
|
|
||||||
|
var lastTunnelName: String = ""
|
||||||
|
for tunnelConfiguration in tunnelConfigurations {
|
||||||
|
if let contents = WgQuickConfigFileWriter.writeConfigFile(from: tunnelConfiguration) {
|
||||||
|
let name = tunnelConfiguration.interface.name
|
||||||
|
if (name.isEmpty || name == lastTunnelName) { continue }
|
||||||
|
inputsToArchiver.append((fileName: "\(name).conf", contents: contents))
|
||||||
|
lastTunnelName = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try ZipArchive.archive(inputs: inputsToArchiver, to: destinationURL)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue