diff --git a/.github/workflows/build-apple.yml b/.github/workflows/build-apple.yml index 0ed6c83..1aadcc2 100644 --- a/.github/workflows/build-apple.yml +++ b/.github/workflows/build-apple.yml @@ -9,7 +9,7 @@ on: jobs: build: name: Build App (${{ matrix.platform }}) - runs-on: macos-14 + runs-on: macos-12 strategy: fail-fast: false matrix: @@ -21,7 +21,7 @@ jobs: rust-targets: - aarch64-apple-ios - scheme: App - destination: platform=iOS Simulator,OS=17.2,name=iPhone 15 Pro + destination: platform=iOS Simulator,OS=16.2,name=iPhone 14 Pro platform: iOS Simulator sdk-name: iphonesimulator rust-targets: @@ -35,7 +35,7 @@ jobs: - x86_64-apple-darwin - aarch64-apple-darwin env: - DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@v3 diff --git a/.github/workflows/release-apple.yml b/.github/workflows/release-apple.yml index 24fbeb5..8b8a76c 100644 --- a/.github/workflows/release-apple.yml +++ b/.github/workflows/release-apple.yml @@ -6,7 +6,7 @@ on: jobs: build: name: Build ${{ matrix.configuration['platform'] }} Release - runs-on: macos-14 + runs-on: macos-12 strategy: fail-fast: false matrix: @@ -22,7 +22,7 @@ jobs: method: mac-application artifact-file: Burrow.app.txz env: - DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer + DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer steps: - name: Checkout uses: actions/checkout@v3 diff --git a/Apple/App/BurrowApp.swift b/Apple/App/BurrowApp.swift index e8aed86..6d798fb 100644 --- a/Apple/App/BurrowApp.swift +++ b/Apple/App/BurrowApp.swift @@ -15,7 +15,7 @@ struct BurrowApp: App { var body: some Scene { WindowGroup { - TunnelView(tunnel: Self.tunnel) + TunnelView() } } } diff --git a/Apple/App/Menu/MenuView.swift b/Apple/App/Menu/MenuView.swift index 56a7494..9d8fb31 100644 --- a/Apple/App/Menu/MenuView.swift +++ b/Apple/App/Menu/MenuView.swift @@ -8,7 +8,7 @@ import SwiftUI struct MenuItemToggleView: View { - var tunnel: Tunnel + @ObservedObject var tunnel: Tunnel var body: some View { HStack { @@ -23,6 +23,7 @@ struct MenuItemToggleView: View { .padding(.horizontal, 4) .padding(10) .frame(minWidth: 300, minHeight: 32, maxHeight: 32) + .task { await tunnel.update() } } } diff --git a/Apple/App/NetworkExtension+Async.swift b/Apple/App/NetworkExtension+Async.swift index 4833efb..ba478f3 100644 --- a/Apple/App/NetworkExtension+Async.swift +++ b/Apple/App/NetworkExtension+Async.swift @@ -2,13 +2,13 @@ import NetworkExtension extension NEVPNManager { func remove() async throws { - _ = try await withUnsafeThrowingContinuation { continuation in + let _: Void = try await withUnsafeThrowingContinuation { continuation in removeFromPreferences(completionHandler: completion(continuation)) } } func save() async throws { - _ = try await withUnsafeThrowingContinuation { continuation in + let _: Void = try await withUnsafeThrowingContinuation { continuation in saveToPreferences(completionHandler: completion(continuation)) } } @@ -18,7 +18,13 @@ extension NETunnelProviderManager { class var managers: [NETunnelProviderManager] { get async throws { try await withUnsafeThrowingContinuation { continuation in - loadAllFromPreferences(completionHandler: completion(continuation)) + loadAllFromPreferences { managers, error in + if let error = error { + continuation.resume(throwing: error) + } else { + continuation.resume(returning: managers ?? []) + } + } } } } @@ -26,20 +32,10 @@ extension NETunnelProviderManager { private func completion(_ continuation: UnsafeContinuation) -> (Error?) -> Void { return { error in - if let error { + if let error = error { continuation.resume(throwing: error) } else { continuation.resume(returning: ()) } } } - -private func completion(_ continuation: UnsafeContinuation) -> (T?, Error?) -> Void { - return { value, error in - if let error { - continuation.resume(throwing: error) - } else if let value { - continuation.resume(returning: value) - } - } -} diff --git a/Apple/App/Tunnel.swift b/Apple/App/Tunnel.swift index 0421a0c..e8bff22 100644 --- a/Apple/App/Tunnel.swift +++ b/Apple/App/Tunnel.swift @@ -2,16 +2,15 @@ import Combine import NetworkExtension import SwiftUI -@Observable class Tunnel { - private(set) var status: Status = .unknown - private var error: NEVPNError? +@MainActor +class Tunnel: ObservableObject { + @Published private(set) var status: Status = .unknown + @Published private var error: NEVPNError? private let bundleIdentifier: String private let configure: (NETunnelProviderManager, NETunnelProviderProtocol) -> Void private var tasks: [Task] = [] - // Each manager corresponds to one entry in the Settings app. - // Our goal is to maintain a single manager, so we create one if none exist and delete extra if there are any. private var managers: [NEVPNManager]? { didSet { status = currentStatus } } @@ -49,31 +48,24 @@ import SwiftUI self.bundleIdentifier = bundleIdentifier self.configure = configure - listenForUpdates() - Task { await update() } - } - - private func listenForUpdates() { - let center = NotificationCenter.default let statusTask = Task { - for try await _ in center.notifications(named: .NEVPNStatusDidChange).map({ _ in () }) { + for try await _ in NotificationCenter.default.notifications(named: .NEVPNStatusDidChange) { status = currentStatus } } let configurationTask = Task { - for try await _ in center.notifications(named: .NEVPNConfigurationChange).map({ _ in () }) { + for try await _ in NotificationCenter.default.notifications(named: .NEVPNConfigurationChange) { await update() } } tasks = [statusTask, configurationTask] } - private func update() async { + func update() async { do { - let updated = try await NETunnelProviderManager.managers - await MainActor.run { managers = updated } - } catch let vpnError as NEVPNError { - error = vpnError + managers = try await NETunnelProviderManager.managers + } catch let error as NEVPNError { + self.error = error } catch { print(error) } @@ -117,9 +109,7 @@ import SwiftUI } deinit { - for task in tasks { - task.cancel() - } + tasks.forEach { $0.cancel() } } } diff --git a/Apple/App/TunnelView.swift b/Apple/App/TunnelView.swift index dd91603..e3b9e28 100644 --- a/Apple/App/TunnelView.swift +++ b/Apple/App/TunnelView.swift @@ -1,34 +1,36 @@ import SwiftUI struct TunnelView: View { - var tunnel: Tunnel +// @ObservedObject var tunnel: Tunnel var body: some View { - VStack { - Text(verbatim: tunnel.status.description) - switch tunnel.status { - case .connected: - Button("Disconnect", action: stop) - case .permissionRequired: - Button("Allow", action: configure) - case .disconnected: - Button("Start", action: start) - default: - EmptyView() - } - } - .padding() + EmptyView() +// VStack { +// Text(verbatim: tunnel.status.description) +// switch tunnel.status { +// case .connected: +// Button("Disconnect", action: stop) +// case .permissionRequired: +// Button("Allow", action: configure) +// case .disconnected: +// Button("Start", action: start) +// default: +// EmptyView() +// } +// } +// .task { await tunnel.update() } +// .padding() } - private func start() { - try? tunnel.start() - } - - private func stop() { - tunnel.stop() - } - - private func configure() { - Task { try await tunnel.configure() } - } +// private func start() { +// try? tunnel.start() +// } +// +// private func stop() { +// tunnel.stop() +// } +// +// private func configure() { +// Task { try await tunnel.configure() } +// } } diff --git a/Apple/Burrow.xcodeproj/project.pbxproj b/Apple/Burrow.xcodeproj/project.pbxproj index c0e4f09..a8ff620 100644 --- a/Apple/Burrow.xcodeproj/project.pbxproj +++ b/Apple/Burrow.xcodeproj/project.pbxproj @@ -196,7 +196,7 @@ buildRules = ( ); dependencies = ( - D08252712B5C3E2E005DA378 /* PBXTargetDependency */, + D0BCC6122A0B328800AD070D /* PBXTargetDependency */, ); name = NetworkExtension; productName = BurrowNetworkExtension; @@ -215,7 +215,7 @@ buildRules = ( ); dependencies = ( - D08252732B5C3E33005DA378 /* PBXTargetDependency */, + D0BCC6142A0B329200AD070D /* PBXTargetDependency */, D020F65C29E4A697002790F6 /* PBXTargetDependency */, ); name = App; @@ -231,7 +231,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1430; - LastUpgradeCheck = 1510; + LastUpgradeCheck = 1430; TargetAttributes = { D020F65229E4A697002790F6 = { CreatedOnToolsVersion = 14.3; @@ -251,7 +251,6 @@ ); mainGroup = D05B9F6929E39EEC008CB1F9; packageReferences = ( - D082526F2B5C3E23005DA378 /* XCRemoteSwiftPackageReference "SwiftLint" */, ); productRefGroup = D05B9F7329E39EEC008CB1F9 /* Products */; projectDirPath = ""; @@ -338,13 +337,13 @@ target = D020F65229E4A697002790F6 /* NetworkExtension */; targetProxy = D020F65B29E4A697002790F6 /* PBXContainerItemProxy */; }; - D08252712B5C3E2E005DA378 /* PBXTargetDependency */ = { + D0BCC6122A0B328800AD070D /* PBXTargetDependency */ = { isa = PBXTargetDependency; - productRef = D08252702B5C3E2E005DA378 /* SwiftLintPlugin */; + productRef = D0BCC6112A0B328800AD070D /* SwiftLintPlugin */; }; - D08252732B5C3E33005DA378 /* PBXTargetDependency */ = { + D0BCC6142A0B329200AD070D /* PBXTargetDependency */ = { isa = PBXTargetDependency; - productRef = D08252722B5C3E33005DA378 /* SwiftLintPlugin */; + productRef = D0BCC6132A0B329200AD070D /* SwiftLintPlugin */; }; /* End PBXTargetDependency section */ @@ -424,25 +423,25 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - D082526F2B5C3E23005DA378 /* XCRemoteSwiftPackageReference "SwiftLint" */ = { + D0BCC6102A0B327700AD070D /* XCRemoteSwiftPackageReference "SwiftLint" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/realm/SwiftLint.git"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.54.0; + minimumVersion = 0.51.0; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - D08252702B5C3E2E005DA378 /* SwiftLintPlugin */ = { + D0BCC6112A0B328800AD070D /* SwiftLintPlugin */ = { isa = XCSwiftPackageProductDependency; - package = D082526F2B5C3E23005DA378 /* XCRemoteSwiftPackageReference "SwiftLint" */; + package = D0BCC6102A0B327700AD070D /* XCRemoteSwiftPackageReference "SwiftLint" */; productName = "plugin:SwiftLintPlugin"; }; - D08252722B5C3E33005DA378 /* SwiftLintPlugin */ = { + D0BCC6132A0B329200AD070D /* SwiftLintPlugin */ = { isa = XCSwiftPackageProductDependency; - package = D082526F2B5C3E23005DA378 /* XCRemoteSwiftPackageReference "SwiftLint" */; + package = D0BCC6102A0B327700AD070D /* XCRemoteSwiftPackageReference "SwiftLint" */; productName = "plugin:SwiftLintPlugin"; }; /* End XCSwiftPackageProductDependency section */ diff --git a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 7522840..0000000 --- a/Apple/Burrow.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,86 +0,0 @@ -{ - "pins" : [ - { - "identity" : "collectionconcurrencykit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git", - "state" : { - "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95", - "version" : "0.2.0" - } - }, - { - "identity" : "cryptoswift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", - "state" : { - "revision" : "7892a123f7e8d0fe62f9f03728b17bbd4f94df5c", - "version" : "1.8.1" - } - }, - { - "identity" : "sourcekitten", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/SourceKitten.git", - "state" : { - "revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56", - "version" : "0.34.1" - } - }, - { - "identity" : "swift-argument-parser", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-argument-parser.git", - "state" : { - "revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a", - "version" : "1.2.2" - } - }, - { - "identity" : "swift-syntax", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", - "state" : { - "revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036", - "version" : "509.0.2" - } - }, - { - "identity" : "swiftlint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/realm/SwiftLint.git", - "state" : { - "revision" : "f17a4f9dfb6a6afb0408426354e4180daaf49cee", - "version" : "0.54.0" - } - }, - { - "identity" : "swiftytexttable", - "kind" : "remoteSourceControl", - "location" : "https://github.com/scottrhoyt/SwiftyTextTable.git", - "state" : { - "revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3", - "version" : "0.9.0" - } - }, - { - "identity" : "swxmlhash", - "kind" : "remoteSourceControl", - "location" : "https://github.com/drmohundro/SWXMLHash.git", - "state" : { - "revision" : "4d0f62f561458cbe1f732171e625f03195151b60", - "version" : "7.0.1" - } - }, - { - "identity" : "yams", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/Yams.git", - "state" : { - "revision" : "0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3", - "version" : "5.0.6" - } - } - ], - "version" : 2 -} diff --git a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme b/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme index c63f8e6..7bb7808 100644 --- a/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme +++ b/Apple/Burrow.xcodeproj/xcshareddata/xcschemes/App.xcscheme @@ -1,6 +1,6 @@