]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
Exporting: Refactor out zip exporting into a separate class
authorRoopesh Chander <roop@roopc.net>
Thu, 15 Nov 2018 07:59:49 +0000 (13:29 +0530)
committerRoopesh Chander <roop@roopc.net>
Thu, 15 Nov 2018 08:09:56 +0000 (13:39 +0530)
Signed-off-by: Roopesh Chander <roop@roopc.net>
WireGuard/WireGuard.xcodeproj/project.pbxproj
WireGuard/WireGuard/UI/iOS/ErrorPresenter.swift
WireGuard/WireGuard/UI/iOS/SettingsTableViewController.swift
WireGuard/WireGuard/ZipArchive/ZipExporter.swift [new file with mode: 0644]

index 8630b588e8b59390aa7b8957533ef39486d7c161..1474a98e3e485f2e39356bf51b2021b3c10f57b5 100644 (file)
@@ -39,6 +39,7 @@
                6FDEF806218725D200D8FBF6 /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */; };
                6FDEF8082187442100D8FBF6 /* WgQuickConfigFileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF8072187442100D8FBF6 /* WgQuickConfigFileWriter.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 */; };
                6FF4AC22211EC472002C96EB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6FF4AC20211EC472002C96EB /* LaunchScreen.storyboard */; };
                6FFA5D8921942F320001E2F7 /* PacketTunnelSettingsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C472183C6A3000F85AD /* PacketTunnelSettingsGenerator.swift */; };
                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>"; };
                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; };
                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>"; };
                        isa = PBXGroup;
                        children = (
                                6FE254FA219C10800028284D /* ZipImporter.swift */,
+                               6FE254FE219C60290028284D /* ZipExporter.swift */,
                                6FDEF801218646B900D8FBF6 /* ZipArchive.swift */,
                                6FDEF7F421863B6100D8FBF6 /* 3rdparty */,
                        );
                                6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */,
                                6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */,
                                6BB8400421892C920003598F /* CopyableLabelTableViewCell.swift in Sources */,
+                               6FE254FF219C60290028284D /* ZipExporter.swift in Sources */,
                                6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
                                6F0068572191AFD200419BE9 /* ScrollableLabel.swift in Sources */,
                                6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,
index abc0083bfe867d9c85073a0bc27e0e66cd00b6dd..8aa0c1a3d8289a8fe5726cf7aad46374b7c31859 100644 (file)
@@ -32,6 +32,12 @@ class ErrorPresenter {
         case ZipImporterError.noTunnelsInZipArchive:
             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:
             os_log("ErrorPresenter: Error not presented: %{public}@", log: OSLog.default, type: .error, "\(error)")
             return nil
index 4024213e0ee9578d4011fee26fd56c0c6f40241b..dc2e27ef2164f537a52395dd169be7e50bafe60e 100644 (file)
@@ -63,20 +63,7 @@ class SettingsTableViewController: UITableViewController {
     }
 
     func exportConfigurationsAsZipFile(sourceView: UIView) {
-        guard let tunnelsManager = tunnelsManager, tunnelsManager.numberOfTunnels() > 0 else {
-            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 tunnelsManager = tunnelsManager else { return }
         guard let destinationDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
             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)
         }
 
+        let count = tunnelsManager.numberOfTunnels()
+        let tunnelConfigurations = (0 ..< count).compactMap { tunnelsManager.tunnel(at: $0).tunnelConfiguration() }
         do {
-            try ZipArchive.archive(inputs: inputsToArchiver, to: destinationURL)
-            let activityVC = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
-            // popoverPresentationController shall be non-nil on the iPad
-            activityVC.popoverPresentationController?.sourceView = sourceView
-            activityVC.popoverPresentationController?.sourceRect = sourceView.bounds
-            present(activityVC, animated: true)
+            try ZipExporter.exportConfigFiles(tunnelConfigurations: tunnelConfigurations, to: destinationURL)
         } catch (let error) {
-            showErrorAlert(title: "Unable to export", message: "There was an error exporting the tunnel configuration archive: \(String(describing: error))")
+            ErrorPresenter.showErrorAlert(error: error, from: self)
         }
+
+        let activityVC = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
+        // popoverPresentationController shall be non-nil on the iPad
+        activityVC.popoverPresentationController?.sourceView = sourceView
+        activityVC.popoverPresentationController?.sourceRect = sourceView.bounds
+        present(activityVC, animated: true)
     }
 
     func showErrorAlert(title: String, message: String) {
diff --git a/WireGuard/WireGuard/ZipArchive/ZipExporter.swift b/WireGuard/WireGuard/ZipArchive/ZipExporter.swift
new file mode 100644 (file)
index 0000000..d0cf9a7
--- /dev/null
@@ -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)
+    }
+}