Finish independent macOS version

This commit is contained in:
世界
2023-07-25 14:04:13 +08:00
parent 12bf02070e
commit 486a685bb5
12 changed files with 147 additions and 98 deletions
@@ -78,6 +78,13 @@ public struct ActiveDashboardView: View {
} }
} }
} }
.alert(isPresented: $errorPresented) {
Alert(
title: Text("Error"),
message: Text(errorMessage),
dismissButton: .default(Text("Ok"))
)
}
#if os(iOS) #if os(iOS)
.onChange(of: scenePhase, perform: { newValue in .onChange(of: scenePhase, perform: { newValue in
if newValue == .active { if newValue == .active {
+1 -1
View File
@@ -67,7 +67,7 @@ public class ExtensionProfile: ObservableObject {
public static func install() async throws { public static func install() async throws {
let manager = NETunnelProviderManager() let manager = NETunnelProviderManager()
manager.localizedDescription = "utun interface" manager.localizedDescription = Variant.applicationName
let tunnelProtocol = NETunnelProviderProtocol() let tunnelProtocol = NETunnelProviderProtocol()
if Variant.useSystemExtension { if Variant.useSystemExtension {
tunnelProtocol.providerBundleIdentifier = "\(FilePath.packageName).system" tunnelProtocol.providerBundleIdentifier = "\(FilePath.packageName).system"
+1 -1
View File
@@ -3,7 +3,7 @@ import Libbox
public class HTTPClient { public class HTTPClient {
private static var userAgent: String { private static var userAgent: String {
var userAgent = FilePath.httpClientName var userAgent = Variant.applicationName
userAgent += "/" userAgent += "/"
userAgent += Bundle.main.version userAgent += Bundle.main.version
userAgent += " (Build " userAgent += " (Build "
+14 -4
View File
@@ -4,24 +4,32 @@
public class SystemExtension: NSObject, OSSystemExtensionRequestDelegate { public class SystemExtension: NSObject, OSSystemExtensionRequestDelegate {
private let forceUpdate: Bool private let forceUpdate: Bool
private let inBackground: Bool
private let semaphore = DispatchSemaphore(value: 0) private let semaphore = DispatchSemaphore(value: 0)
private var result: OSSystemExtensionRequest.Result? private var result: OSSystemExtensionRequest.Result?
private var properties: [OSSystemExtensionProperties]? private var properties: [OSSystemExtensionProperties]?
private var error: Error? private var error: Error?
private init(forceUpdate: Bool = false) { private init(forceUpdate: Bool = false, inBackground: Bool = false) {
self.forceUpdate = forceUpdate self.forceUpdate = forceUpdate
self.inBackground = inBackground
} }
public func request(_: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction { public func request(_: OSSystemExtensionRequest, actionForReplacingExtension existing: OSSystemExtensionProperties, withExtension ext: OSSystemExtensionProperties) -> OSSystemExtensionRequest.ReplacementAction {
if forceUpdate { if forceUpdate {
return .replace return .replace
} }
if existing.isAwaitingUserApproval, !inBackground {
return .replace
}
if existing.bundleIdentifier == ext.bundleIdentifier, if existing.bundleIdentifier == ext.bundleIdentifier,
existing.bundleVersion == ext.bundleVersion existing.bundleVersion == ext.bundleVersion,
existing.bundleShortVersion == ext.bundleShortVersion
{ {
NSLog("Skip update system extension")
return .cancel return .cancel
} else { } else {
NSLog("Update system extension")
return .replace return .replace
} }
} }
@@ -69,6 +77,7 @@
public static func isInstalled() async -> Bool { public static func isInstalled() async -> Bool {
await (try? Task.detached { await (try? Task.detached {
for _ in 0 ..< 3 {
do { do {
let propList = try SystemExtension().getProperties() let propList = try SystemExtension().getProperties()
if propList.isEmpty { if propList.isEmpty {
@@ -80,13 +89,14 @@
} }
} }
} catch { } catch {
NSLog(error.localizedDescription) try await Task.sleep(nanoseconds: NSEC_PER_SEC)
}
} }
return false return false
}.result.get()) == true }.result.get()) == true
} }
public static func install(forceUpdate: Bool = false) async throws -> OSSystemExtensionRequest.Result? { public static func install(forceUpdate: Bool = false, inBackground _: Bool = false) async throws -> OSSystemExtensionRequest.Result? {
try await Task.detached { try await Task.detached {
try SystemExtension(forceUpdate: forceUpdate).submitAndWait() try SystemExtension(forceUpdate: forceUpdate).submitAndWait()
}.result.get() }.result.get()
-5
View File
@@ -2,11 +2,6 @@ import Foundation
public enum FilePath { public enum FilePath {
public static let packageName = "io.nekohasekai.sfa" public static let packageName = "io.nekohasekai.sfa"
#if os(iOS)
public static let httpClientName = "SFI"
#elseif os(macOS)
public static let httpClientName = "SFM"
#endif
} }
public extension FilePath { public extension FilePath {
+6
View File
@@ -6,4 +6,10 @@ public enum Variant {
#else #else
public static let useSystemExtension = false public static let useSystemExtension = false
#endif #endif
#if os(iOS)
public static let applicationName = "SFI"
#elseif os(macOS)
public static let applicationName = "SFM"
#endif
} }
+4 -17
View File
@@ -20,23 +20,6 @@ open class ApplicationDelegate: NSObject, NSApplicationDelegate {
} }
Task.detached { Task.detached {
do { do {
if Variant.useSystemExtension {
if await SystemExtension.isInstalled() {
if let result = try await SystemExtension.install() {
if result == .willCompleteAfterReboot {
return
}
}
}
}
try await self.postStart(launchedAsLogInItem)
} catch {
NSLog("application setup error: \(error.localizedDescription)")
}
}
}
private func postStart(_ launchedAsLogInItem: Bool) async throws {
try ProfileUpdateTask.setup() try ProfileUpdateTask.setup()
if launchedAsLogInItem { if launchedAsLogInItem {
if SharedPreferences.startedByUser { if SharedPreferences.startedByUser {
@@ -45,6 +28,10 @@ open class ApplicationDelegate: NSObject, NSApplicationDelegate {
} }
} }
} }
} catch {
NSLog("application setup error: \(error.localizedDescription)")
}
}
} }
public func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { public func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool {
+35 -10
View File
@@ -10,9 +10,10 @@ public struct MainView: View {
@State private var profileLoading = true @State private var profileLoading = true
@State private var logClient: LogClient! @State private var logClient: LogClient!
@State private var serviceNotificationTitle = "" @State private var dialogTitle = ""
@State private var serviceNotificationContent = "" @State private var dialogContent = ""
@State private var serviceNotificationPresented = false @State private var dialogAction: (() -> Void)?
@State private var dialogPresented = false
public init() {} public init() {}
public var body: some View { public var body: some View {
@@ -20,6 +21,7 @@ public struct MainView: View {
VStack { VStack {
SidebarView() SidebarView()
} }
.frame(minWidth: 150) .frame(minWidth: 150)
} detail: { } detail: {
if profileLoading { if profileLoading {
@@ -33,18 +35,28 @@ public struct MainView: View {
selection.contentView selection.contentView
} }
} }
.alert(isPresented: $serviceNotificationPresented, content: { #if !DEBUG
.onAppear {
if Variant.useSystemExtension {
Task.detached {
checkApplicationPath()
}
}
}
#endif
.alert(isPresented: $dialogPresented, content: {
Alert( Alert(
title: Text(serviceNotificationTitle), title: Text(dialogTitle),
message: Text(serviceNotificationContent), message: Text(dialogContent),
dismissButton: .default(Text("Ok")) dismissButton: .default(Text("Ok"), action: dialogAction)
) )
}) })
.onAppear { .onAppear {
ServiceNotification.setServiceNotificationListener { notification in ServiceNotification.setServiceNotificationListener { notification in
serviceNotificationTitle = notification.title dialogTitle = notification.title
serviceNotificationContent = notification.body dialogContent = notification.body
serviceNotificationPresented = true dialogAction = nil
dialogPresented = true
} }
} }
.onDisappear { .onDisappear {
@@ -99,4 +111,17 @@ public struct MainView: View {
logClient.reconnect() logClient.reconnect()
} }
} }
private func checkApplicationPath() {
let directoryName = URL(filePath: Bundle.main.bundlePath).deletingLastPathComponent().pathComponents.last
if directoryName != "Applications" {
dialogTitle = "Wrong application location"
dialogContent = "This app needs to be placed under ~/Applications to work."
dialogAction = {
NSWorkspace.shared.selectFile(Bundle.main.bundlePath, inFileViewerRootedAtPath: "")
NSApp.terminate(nil)
}
dialogPresented = true
}
}
} }
+1 -5
View File
@@ -4,11 +4,7 @@ import SwiftUI
@main @main
struct Application: App { struct Application: App {
@NSApplicationDelegateAdaptor private var appDelegate: ApplicationDelegate @NSApplicationDelegateAdaptor private var appDelegate: IndependentApplicationDelegate
init() {
Variant.useSystemExtension = true
}
var body: some Scene { var body: some Scene {
MacApplication() MacApplication()
@@ -0,0 +1,19 @@
import AppKit
import Foundation
import Library
import MacLibrary
class IndependentApplicationDelegate: ApplicationDelegate {
public func applicationWillFinishLaunching(_: Notification) {
Variant.useSystemExtension = true
Task.detached {
if await SystemExtension.isInstalled() {
if let result = try await SystemExtension.install() {
if result == .willCompleteAfterReboot {
return
}
}
}
}
}
}
+16 -12
View File
@@ -19,6 +19,7 @@
3A2223582A6E1CC700C50B23 /* MacApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2223572A6E1CC700C50B23 /* MacApplication.swift */; }; 3A2223582A6E1CC700C50B23 /* MacApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2223572A6E1CC700C50B23 /* MacApplication.swift */; };
3A22235A2A6E212A00C50B23 /* SystemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2223592A6E212A00C50B23 /* SystemExtension.swift */; }; 3A22235A2A6E212A00C50B23 /* SystemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2223592A6E212A00C50B23 /* SystemExtension.swift */; };
3A251C122A52D09700651082 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3AAB5E7A2A4C1446009757F1 /* Assets.xcassets */; }; 3A251C122A52D09700651082 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3AAB5E7A2A4C1446009757F1 /* Assets.xcassets */; };
3A2EAEED2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2EAEEC2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift */; };
3A3AA7FC2A4EFDAE002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; }; 3A3AA7FC2A4EFDAE002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; };
3A3AA7FF2A4EFDB3002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; }; 3A3AA7FF2A4EFDB3002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; };
3A3DEBEB2A4FFE2D00373BF4 /* AppIntents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3DEBE62A4FFA6000373BF4 /* AppIntents.framework */; }; 3A3DEBEB2A4FFE2D00373BF4 /* AppIntents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A3DEBE62A4FFA6000373BF4 /* AppIntents.framework */; };
@@ -357,6 +358,7 @@
3A2223552A6E1BDE00C50B23 /* Variant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Variant.swift; sourceTree = "<group>"; }; 3A2223552A6E1BDE00C50B23 /* Variant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Variant.swift; sourceTree = "<group>"; };
3A2223572A6E1CC700C50B23 /* MacApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacApplication.swift; sourceTree = "<group>"; }; 3A2223572A6E1CC700C50B23 /* MacApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacApplication.swift; sourceTree = "<group>"; };
3A2223592A6E212A00C50B23 /* SystemExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtension.swift; sourceTree = "<group>"; }; 3A2223592A6E212A00C50B23 /* SystemExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemExtension.swift; sourceTree = "<group>"; };
3A2EAEEC2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndependentApplicationDelegate.swift; sourceTree = "<group>"; };
3A3DEBE12A4FFA1A00373BF4 /* ExtensionFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExtensionFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/ExtensionFoundation.framework; sourceTree = DEVELOPER_DIR; }; 3A3DEBE12A4FFA1A00373BF4 /* ExtensionFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExtensionFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/ExtensionFoundation.framework; sourceTree = DEVELOPER_DIR; };
3A3DEBE62A4FFA6000373BF4 /* AppIntents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppIntents.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/AppIntents.framework; sourceTree = DEVELOPER_DIR; }; 3A3DEBE62A4FFA6000373BF4 /* AppIntents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppIntents.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/AppIntents.framework; sourceTree = DEVELOPER_DIR; };
3A44BB662A4DBF7900E4C9F8 /* SFI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SFI.entitlements; sourceTree = "<group>"; }; 3A44BB662A4DBF7900E4C9F8 /* SFI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SFI.entitlements; sourceTree = "<group>"; };
@@ -768,6 +770,7 @@
3AEECC0A2A6DF9CA006A0E0C /* Assets.xcassets */, 3AEECC0A2A6DF9CA006A0E0C /* Assets.xcassets */,
3AEECC502A6E0074006A0E0C /* SFM.entitlements */, 3AEECC502A6E0074006A0E0C /* SFM.entitlements */,
3A2223532A6E1B6700C50B23 /* Info.plist */, 3A2223532A6E1B6700C50B23 /* Info.plist */,
3A2EAEEC2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift */,
); );
path = SFM.System; path = SFM.System;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1279,6 +1282,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
3AEECC072A6DF9CA006A0E0C /* Application.swift in Sources */, 3AEECC072A6DF9CA006A0E0C /* Application.swift in Sources */,
3A2EAEED2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -1782,7 +1786,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.3.3; MARKETING_VERSION = 1.3.4;
OTHER_CODE_SIGN_FLAGS = "--deep"; OTHER_CODE_SIGN_FLAGS = "--deep";
OTHER_LDFLAGS = ""; OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
@@ -1823,7 +1827,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.3.3; MARKETING_VERSION = 1.3.4;
OTHER_CODE_SIGN_FLAGS = "--deep"; OTHER_CODE_SIGN_FLAGS = "--deep";
OTHER_LDFLAGS = ""; OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
@@ -1847,7 +1851,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 11; CURRENT_PROJECT_VERSION = 12;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = Z56Z6NYZN2; DEVELOPMENT_TEAM = Z56Z6NYZN2;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -1863,7 +1867,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.3.3; MARKETING_VERSION = 1.3.4;
OTHER_CODE_SIGN_FLAGS = ""; OTHER_CODE_SIGN_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box"; PRODUCT_NAME = "sing-box";
@@ -1885,7 +1889,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 11; CURRENT_PROJECT_VERSION = 12;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = Z56Z6NYZN2; DEVELOPMENT_TEAM = Z56Z6NYZN2;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -1901,7 +1905,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.3.3; MARKETING_VERSION = 1.3.4;
OTHER_CODE_SIGN_FLAGS = ""; OTHER_CODE_SIGN_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box"; PRODUCT_NAME = "sing-box";
@@ -2023,7 +2027,6 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = Z56Z6NYZN2; "DEVELOPMENT_TEAM[sdk=macosx*]" = Z56Z6NYZN2;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -2039,7 +2042,7 @@
"@executable_path/../../../../Frameworks", "@executable_path/../../../../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.3.4;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system;
PRODUCT_NAME = "$(inherited)"; PRODUCT_NAME = "$(inherited)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2059,7 +2062,6 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = Z56Z6NYZN2; "DEVELOPMENT_TEAM[sdk=macosx*]" = Z56Z6NYZN2;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -2075,7 +2077,7 @@
"@executable_path/../../../../Frameworks", "@executable_path/../../../../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.3.4;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system;
PRODUCT_NAME = "$(inherited)"; PRODUCT_NAME = "$(inherited)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2108,13 +2110,14 @@
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SFM.System/Info.plist; INFOPLIST_FILE = SFM.System/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "sing-box"; INFOPLIST_KEY_CFBundleDisplayName = "sing-box";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.3.4;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent;
PRODUCT_NAME = SFM; PRODUCT_NAME = SFM;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2146,13 +2149,14 @@
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = SFM.System/Info.plist; INFOPLIST_FILE = SFM.System/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "sing-box"; INFOPLIST_KEY_CFBundleDisplayName = "sing-box";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0; MARKETING_VERSION = 1.3.4;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent;
PRODUCT_NAME = SFM; PRODUCT_NAME = SFM;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -7,7 +7,7 @@
<key>ApplicationLibrary.xcscheme_^#shared#^_</key> <key>ApplicationLibrary.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>1</integer> <integer>3</integer>
</dict> </dict>
<key>Associations (Playground) 1.xcscheme</key> <key>Associations (Playground) 1.xcscheme</key>
<dict> <dict>
@@ -69,7 +69,7 @@
<key>MacLibrary.xcscheme_^#shared#^_</key> <key>MacLibrary.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>5</integer> <integer>4</integer>
</dict> </dict>
<key>MessageExtension.xcscheme_^#shared#^_</key> <key>MessageExtension.xcscheme_^#shared#^_</key>
<dict> <dict>
@@ -131,17 +131,17 @@
<key>SFM.System.xcscheme_^#shared#^_</key> <key>SFM.System.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>2</integer> <integer>5</integer>
</dict> </dict>
<key>SFM.xcscheme_^#shared#^_</key> <key>SFM.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>4</integer> <integer>2</integer>
</dict> </dict>
<key>SystemExtension.xcscheme_^#shared#^_</key> <key>SystemExtension.xcscheme_^#shared#^_</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
<integer>3</integer> <integer>1</integer>
</dict> </dict>
<key>Test.xcscheme_^#shared#^_</key> <key>Test.xcscheme_^#shared#^_</key>
<dict> <dict>