Skip to content

Commit 5e7176a

Browse files
committed
refactor: better option control
1 parent e97de88 commit 5e7176a

7 files changed

Lines changed: 51 additions & 46 deletions

File tree

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
//
2-
// ControlWidgetsBundle.swift
3-
// ControlWidgets
4-
//
5-
// Created by YinMo19 on 2026/1/13.
6-
//
7-
81
import WidgetKit
92
import SwiftUI
103

@@ -13,4 +6,4 @@ struct ControlWidgetsBundle: WidgetBundle {
136
var body: some Widget {
147
ControlWidgetsControl()
158
}
16-
}
9+
}

ControlWidgets/ControlWidgetsControl.swift

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
//
2-
// ControlWidgetsControl.swift
3-
// ControlWidgets
4-
//
5-
// Created by YinMo19 on 2026/1/13.
6-
//
7-
81
import AppIntents
92
import SwiftUI
103
import WidgetKit
@@ -23,12 +16,12 @@ struct ControlWidgetsControl: ControlWidget {
2316
isOn: isConnected,
2417
action: ToggleVPNIntent()
2518
) { isOn in
26-
Label(isOn ? LocalizedStringResource("vpn_connected") : LocalizedStringResource("vpn_disconnected"), systemImage: "network")
27-
.controlWidgetActionHint(isOn ? LocalizedStringResource("vpn_disconnect") : LocalizedStringResource("vpn_connect"))
19+
Label(isOn ? "vpn_connected" : "vpn_disconnected", systemImage: "network")
20+
.controlWidgetActionHint(isOn ? "vpn_disconnect" : "vpn_connect")
2821
}
2922
}
3023
.displayName("EasyTier")
31-
.description(LocalizedStringResource("toggle_vpn_connection"))
24+
.description("toggle_vpn_connection")
3225
}
3326
}
3427

@@ -43,15 +36,15 @@ extension ControlWidgetsControl {
4336
guard let manager = managers.first else {
4437
return false
4538
}
46-
return manager.connection.status == .connected
39+
return [.connecting, .connected, .reasserting].contains(manager.connection.status)
4740
}
4841
}
4942
}
5043

5144
struct ToggleVPNIntent: SetValueIntent {
5245
static let title: LocalizedStringResource = "toggle_vpn"
5346

54-
@Parameter(title: LocalizedStringResource("vpn_connected"))
47+
@Parameter(title: "vpn_connected")
5548
var value: Bool
5649

5750
func perform() async throws -> some IntentResult {

EasyTier.xcodeproj/project.pbxproj

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
0526D7992F1762C300968CE2 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 0526D7822F1762C300968CE2 /* Localizable.xcstrings */; };
11+
0526D7B32F17656B00968CE2 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 0526D7822F1762C300968CE2 /* Localizable.xcstrings */; };
1012
055836312F04D26700139811 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 055836302F04D26700139811 /* NetworkExtension.framework */; };
1113
055836392F04D26700139811 /* EasyTierNetworkExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0558362E2F04D26600139811 /* EasyTierNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
1214
05B61F5C2F05056D00646DDC /* libeasytier_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 05B61F5B2F05056D00646DDC /* libeasytier_ios.a */; };
@@ -50,6 +52,7 @@
5052

5153
/* Begin PBXFileReference section */
5254
051C6A0B2F03AB0000AF29B1 /* EasyTier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EasyTier.app; sourceTree = BUILT_PRODUCTS_DIR; };
55+
0526D7822F1762C300968CE2 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
5356
0558362E2F04D26600139811 /* EasyTierNetworkExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = EasyTierNetworkExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
5457
055836302F04D26700139811 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
5558
05B61F5B2F05056D00646DDC /* libeasytier_ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libeasytier_ios.a; sourceTree = "<group>"; };
@@ -145,6 +148,7 @@
145148
051C6A0D2F03AB0000AF29B1 /* EasyTier */,
146149
055836322F04D26700139811 /* EasyTierNetworkExtension */,
147150
7A59B81E2F1641100069728D /* ControlWidgets */,
151+
0526D7822F1762C300968CE2 /* Localizable.xcstrings */,
148152
0558362F2F04D26700139811 /* Frameworks */,
149153
051C6A0C2F03AB0000AF29B1 /* Products */,
150154
);
@@ -295,6 +299,7 @@
295299
isa = PBXResourcesBuildPhase;
296300
buildActionMask = 2147483647;
297301
files = (
302+
0526D7992F1762C300968CE2 /* Localizable.xcstrings in Resources */,
298303
);
299304
runOnlyForDeploymentPostprocessing = 0;
300305
};
@@ -309,6 +314,7 @@
309314
isa = PBXResourcesBuildPhase;
310315
buildActionMask = 2147483647;
311316
files = (
317+
0526D7B32F17656B00968CE2 /* Localizable.xcstrings in Resources */,
312318
);
313319
runOnlyForDeploymentPostprocessing = 0;
314320
};
@@ -711,11 +717,11 @@
711717
CODE_SIGN_ENTITLEMENTS = ControlWidgets/ControlWidgetsExtension.entitlements;
712718
CODE_SIGN_IDENTITY = "Apple Development";
713719
CODE_SIGN_STYLE = Automatic;
714-
CURRENT_PROJECT_VERSION = 1;
720+
CURRENT_PROJECT_VERSION = 14;
715721
DEVELOPMENT_TEAM = Y8RH943F65;
716722
GENERATE_INFOPLIST_FILE = YES;
717723
INFOPLIST_FILE = ControlWidgets/Info.plist;
718-
INFOPLIST_KEY_CFBundleDisplayName = ControlWidgets;
724+
INFOPLIST_KEY_CFBundleDisplayName = EasyTierControlWidgets;
719725
INFOPLIST_KEY_NSHumanReadableCopyright = "";
720726
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
721727
LD_RUNPATH_SEARCH_PATHS = (
@@ -745,11 +751,11 @@
745751
CODE_SIGN_ENTITLEMENTS = ControlWidgets/ControlWidgetsExtension.entitlements;
746752
CODE_SIGN_IDENTITY = "Apple Development";
747753
CODE_SIGN_STYLE = Automatic;
748-
CURRENT_PROJECT_VERSION = 1;
754+
CURRENT_PROJECT_VERSION = 14;
749755
DEVELOPMENT_TEAM = Y8RH943F65;
750756
GENERATE_INFOPLIST_FILE = YES;
751757
INFOPLIST_FILE = ControlWidgets/Info.plist;
752-
INFOPLIST_KEY_CFBundleDisplayName = ControlWidgets;
758+
INFOPLIST_KEY_CFBundleDisplayName = EasyTierControlWidgets;
753759
INFOPLIST_KEY_NSHumanReadableCopyright = "";
754760
IPHONEOS_DEPLOYMENT_TARGET = 26.0;
755761
LD_RUNPATH_SEARCH_PATHS = (

EasyTier/Utils/NEManager.swift

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -154,26 +154,7 @@ class NEManager: NEManagerProtocol {
154154
}
155155
}
156156

157-
func connect(profile: ProfileSummary) async throws {
158-
guard ![.connecting, .connected, .disconnecting, .reasserting].contains(status) else {
159-
Self.logger.warning("connect() failed: in \(String(describing: self.status)) status")
160-
return
161-
}
162-
guard !isLoading else {
163-
Self.logger.warning("connect() failed: not loaded")
164-
return
165-
}
166-
if status == .invalid {
167-
_ = try await NEManager.install()
168-
try await load()
169-
}
170-
guard let manager else {
171-
Self.logger.error("connect() failed: manager is nil")
172-
return
173-
}
174-
manager.isEnabled = true
175-
try await manager.saveToPreferences()
176-
157+
static func generateOptions(_ profile: ProfileSummary) throws -> [String : NSObject] {
177158
var options: [String : NSObject] = [:]
178159
let config = NetworkConfig(from: profile.profile, name: profile.name)
179160

@@ -210,6 +191,10 @@ class NEManager: NEManagerProtocol {
210191
options["dns"] = dnsArray as NSArray
211192
}
212193

194+
return options
195+
}
196+
197+
static func saveOptions(_ options: [String : NSObject]) {
213198
// Save config to App Group for Widget use
214199
let defaults = UserDefaults(suiteName: "group.site.yinmo.easytier")
215200
var configDict: [String: String] = [:]
@@ -222,9 +207,31 @@ class NEManager: NEManagerProtocol {
222207
defaults?.set(configData, forKey: "LastVPNConfig")
223208
defaults?.synchronize()
224209
}
225-
226-
210+
}
211+
212+
func connect(profile: ProfileSummary) async throws {
213+
guard ![.connecting, .connected, .disconnecting, .reasserting].contains(status) else {
214+
Self.logger.warning("connect() failed: in \(String(describing: self.status)) status")
215+
return
216+
}
217+
guard !isLoading else {
218+
Self.logger.warning("connect() failed: not loaded")
219+
return
220+
}
221+
if status == .invalid {
222+
_ = try await NEManager.install()
223+
try await load()
224+
}
225+
guard let manager else {
226+
Self.logger.error("connect() failed: manager is nil")
227+
return
228+
}
229+
manager.isEnabled = true
230+
try await manager.saveToPreferences()
231+
227232
do {
233+
let options = try Self.generateOptions(profile)
234+
Self.saveOptions(options)
228235
try manager.connection.startVPNTunnel(options: options)
229236
} catch {
230237
Self.logger.error("connect() start vpn tunnel failed: \(String(describing: error))")
File renamed without changes.

EasyTier/Views/DashboardView.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,17 @@ struct DashboardView<Manager: NEManagerProtocol>: View {
243243
guard let selectedProfile else { return }
244244
Task {
245245
await manager.updateName(name: selectedProfile.name, server: selectedProfile.id.uuidString)
246+
if let options = try? NEManager.generateOptions(selectedProfile) {
247+
NEManager.saveOptions(options)
248+
}
246249
}
247250
}
248251
.onDisappear {
249252
// Release observer to remove registration
250253
darwinObserver = nil
254+
if let selectedProfile, let options = try? NEManager.generateOptions(selectedProfile) {
255+
NEManager.saveOptions(options)
256+
}
251257
}
252258
.sheet(isPresented: $showManageSheet) {
253259
sheetView

0 commit comments

Comments
 (0)