diff --git a/FrameworkTests/TerminalCommandDraftControllerTests.swift b/FrameworkTests/TerminalCommandDraftControllerTests.swift index f0f9a12f..d51002f7 100644 --- a/FrameworkTests/TerminalCommandDraftControllerTests.swift +++ b/FrameworkTests/TerminalCommandDraftControllerTests.swift @@ -13,7 +13,7 @@ struct TerminalCommandDraftControllerTests { writes.append(data) } } - await Task.yield() + while !controller.hasPendingRequest { await Task.yield() } await #expect(throws: TerminalDraftError.self) { try await controller.read(isAvailable: true) { _ in } @@ -39,7 +39,7 @@ struct TerminalCommandDraftControllerTests { let read = Task { try await controller.read(isAvailable: true) { _ in } } - await Task.yield() + while !controller.hasPendingRequest { await Task.yield() } controller.cancel(CancellationError()) diff --git a/Frameworks/Resources/Localizable.xcstrings b/Frameworks/Resources/Localizable.xcstrings index 8f0ec840..de274853 100644 --- a/Frameworks/Resources/Localizable.xcstrings +++ b/Frameworks/Resources/Localizable.xcstrings @@ -7696,7 +7696,6 @@ } }, "Discard Changes" : { - "extractionState" : "manual", "localizations" : { "zh-Hans" : { "stringUnit" : { @@ -7713,7 +7712,6 @@ } }, "Discard Changes?" : { - "extractionState" : "manual", "localizations" : { "zh-Hans" : { "stringUnit" : { @@ -26998,4 +26996,4 @@ } }, "version" : "1.2" -} \ No newline at end of file +} diff --git a/Frameworks/TermindApplication/Connections/RemoteSessionHostStore.swift b/Frameworks/TermindApplication/Connections/RemoteSessionHostStore.swift index 7a6514f1..d7755eac 100644 --- a/Frameworks/TermindApplication/Connections/RemoteSessionHostStore.swift +++ b/Frameworks/TermindApplication/Connections/RemoteSessionHostStore.swift @@ -44,8 +44,6 @@ public protocol RemoteSessionHostStore: AnyObject, Sendable { func upsert(_ host: Host) } -extension HostLibraryModel: RemoteSessionHostStore {} - extension RemoteSessionHostStore { public func expectedHostKeys( for host: Host, temporaryHostKeys: [Host.ID: SSHHostKeyIdentity] diff --git a/Frameworks/TermindApplication/FeatureModels/HostLibraryModel.swift b/Frameworks/TermindApplication/FeatureModels/HostLibraryModel.swift index 924b6aea..17416607 100644 --- a/Frameworks/TermindApplication/FeatureModels/HostLibraryModel.swift +++ b/Frameworks/TermindApplication/FeatureModels/HostLibraryModel.swift @@ -9,7 +9,7 @@ import struct TermindDomain.Host /// Core host metadata is backed by SwiftData in the app and projected into value /// types for the views. Previews can still construct an in-memory store directly. @Observable -public final class HostLibraryModel { +public final class HostLibraryModel: RemoteSessionHostStore { public private(set) var hosts: [Host] = [] public private(set) var groups: [HostGroup] = [] public private(set) var keys: [SSHKeyRef] = [] diff --git a/Frameworks/TermindRemoteInfrastructure/SSH/SSHSessionActor.swift b/Frameworks/TermindRemoteInfrastructure/SSH/SSHSessionActor.swift index f3a47cc3..23c66dfd 100644 --- a/Frameworks/TermindRemoteInfrastructure/SSH/SSHSessionActor.swift +++ b/Frameworks/TermindRemoteInfrastructure/SSH/SSHSessionActor.swift @@ -53,19 +53,18 @@ public nonisolated struct RemoteShellIntegrationBootstrap: Sendable { // The POSIX helper reads os-release as inert assignment text instead of // sourcing it. Its output precedes the shell marker, so a missing `sh` // still leaves the original shell-only bootstrap path usable. - startCommand = Data( - (" command sh -c 'f=; did=; dlike=; dver=; " - + "[ -r /etc/os-release ] && f=/etc/os-release; " - + "[ -z \"$f\" ] && [ -r /usr/lib/os-release ] && f=/usr/lib/os-release; " - + "if [ -n \"$f\" ]; then while IFS= read -r line; do case \"$line\" in " - + "ID=*) did=${line#ID=} ;; ID_LIKE=*) dlike=${line#ID_LIKE=} ;; " - + "VERSION_ID=*) dver=${line#VERSION_ID=} ;; esac; " - + "done < \"$f\"; fi; kn=$(uname -s 2>/dev/null); " - + "kr=$(uname -r 2>/dev/null); ka=$(uname -m 2>/dev/null); " - + "printf \"\\n__TRMD_%s_SYSTEM__%s|%s|%s|%s|%s|%s__\\n\" " - + "\"$1\" \"$did\" \"$dlike\" \"$dver\" \"$kn\" \"$kr\" \"$ka\"' sh '\(token)'; " - + "printf '\\n__TRMD_%s_SHELL__%s__\\n' '\(token)' \"$SHELL\"\n").utf8 - ) + var probeCommand = " command sh -c 'f=; did=; dlike=; dver=; " + probeCommand += "[ -r /etc/os-release ] && f=/etc/os-release; " + probeCommand += "[ -z \"$f\" ] && [ -r /usr/lib/os-release ] && f=/usr/lib/os-release; " + probeCommand += "if [ -n \"$f\" ]; then while IFS= read -r line; do case \"$line\" in " + probeCommand += "ID=*) did=${line#ID=} ;; ID_LIKE=*) dlike=${line#ID_LIKE=} ;; " + probeCommand += "VERSION_ID=*) dver=${line#VERSION_ID=} ;; esac; " + probeCommand += "done < \"$f\"; fi; kn=$(uname -s 2>/dev/null); " + probeCommand += "kr=$(uname -r 2>/dev/null); ka=$(uname -m 2>/dev/null); " + probeCommand += "printf \"\\n__TRMD_%s_SYSTEM__%s|%s|%s|%s|%s|%s__\\n\" " + probeCommand += "\"$1\" \"$did\" \"$dlike\" \"$dver\" \"$kn\" \"$kr\" \"$ka\"' sh '\(token)'; " + probeCommand += "printf '\\n__TRMD_%s_SHELL__%s__\\n' '\(token)' \"$SHELL\"\n" + startCommand = Data(probeCommand.utf8) deadline = now + Self.responseTimeout } diff --git a/TFI/Features/Workspaces/MobileWorkspace.swift b/TFI/Features/Workspaces/MobileWorkspace.swift index b978d5c4..2b6076b2 100644 --- a/TFI/Features/Workspaces/MobileWorkspace.swift +++ b/TFI/Features/Workspaces/MobileWorkspace.swift @@ -552,8 +552,8 @@ final class MobileWorkspace: Identifiable { self?.generation == $0 } connection.clearHostKeyPrompt() - attempt = Task { [weak self] in - guard let self else { return } + attempt = Task { [weak self, weak hosts] in + guard let self, let hosts else { return } defer { if generation == token { busy = false } } guard generation == token, !Task.isCancelled else { return } do { diff --git a/TFI/Info.plist b/TFI/Info.plist index 36ea3147..ea6b0134 100644 --- a/TFI/Info.plist +++ b/TFI/Info.plist @@ -13,10 +13,6 @@ - NSFaceIDUsageDescription - Authenticate to use your SSH keys. - NSSupportsLiveActivities - TermindCloudKitEnvironment $(ICLOUD_CONTAINER_ENVIRONMENT) TermindKeychainAccessGroup @@ -36,12 +32,6 @@ remote-notification - NSMicrophoneUsageDescription - Termind uses the microphone to transcribe speech into your chat draft. - NSSpeechRecognitionUsageDescription - Termind uses Apple Speech Recognition to turn your recording into text. Depending on system settings and language support, Apple may process the audio online. - NSCameraUsageDescription - Termind uses the camera to attach photos to your chat. UTExportedTypeDeclarations diff --git a/TFI/UI/Components/MobileNativeList.swift b/TFI/UI/Components/MobileNativeList.swift index 4e2345be..37bb5090 100644 --- a/TFI/UI/Components/MobileNativeList.swift +++ b/TFI/UI/Components/MobileNativeList.swift @@ -214,8 +214,6 @@ where Item: Identifiable & Hashable & SendableMetatype, RowContent: View { } } - @_optimize(none) deinit {} - func update( listView: ListView, items newItems: [Item], renderer: @escaping Renderer, onSelect: ((Item) -> Void)?, diff --git a/TFM/App/RootView.swift b/TFM/App/RootView.swift index f50e1f1a..a170bf40 100644 --- a/TFM/App/RootView.swift +++ b/TFM/App/RootView.swift @@ -160,7 +160,8 @@ struct RootView: View { window.refreshSessionContext() window.reconcileSidebarMode() } - .onAppear { + .onAppear { [weak app] in + guard let app else { return } window.proAccess = app.proAccess window.connectionCoordinator = app.connections window.hostStore = app.hostLibrary diff --git a/TFM/Features/SFTP/SFTPSessionModel.swift b/TFM/Features/SFTP/SFTPSessionModel.swift index 31712794..1387a377 100644 --- a/TFM/Features/SFTP/SFTPSessionModel.swift +++ b/TFM/Features/SFTP/SFTPSessionModel.swift @@ -347,8 +347,8 @@ final class SFTPSessionModel: Identifiable { hint = reconnecting ? String(localized: "Reconnecting") : String(localized: "Connecting") - connectionTask = Task { [weak self] in - guard let self else { return } + connectionTask = Task { [weak self, weak store] in + guard let self, let store else { return } do { let configuration: SSHConnectionConfiguration if let suppliedAuthentication { diff --git a/TFM/Features/Terminal/SSHSessionModel.swift b/TFM/Features/Terminal/SSHSessionModel.swift index 7c9ec9da..c2da9fa2 100644 --- a/TFM/Features/Terminal/SSHSessionModel.swift +++ b/TFM/Features/Terminal/SSHSessionModel.swift @@ -573,8 +573,8 @@ final class SSHSessionModel: Identifiable { connection.clearHostKeyPrompt() connectionTask?.cancel() status = reconnecting ? .reconnecting : .connecting - connectionTask = Task { [weak self] in - guard let self else { return } + connectionTask = Task { [weak self, weak store] in + guard let self, let store else { return } do { try await openSSH( host: host, username: username, credentials: credentials, diff --git a/TFM/UI/Components/HostingListRow.swift b/TFM/UI/Components/HostingListRow.swift index debab220..78dfc5bb 100644 --- a/TFM/UI/Components/HostingListRow.swift +++ b/TFM/UI/Components/HostingListRow.swift @@ -42,9 +42,6 @@ where private var colorScheme = ColorScheme.light private var items: [Item] = [] - // Swift 6.3.3's optimizer can crash while synthesizing generic deinit. - @_optimize(none) deinit {} - @discardableResult func update( _ listView: ListView, items newItems: [Item], renderer: @escaping Renderer, diff --git a/TFM/UI/Components/ManagedChooser.swift b/TFM/UI/Components/ManagedChooser.swift index dd955f0e..9f65c14b 100644 --- a/TFM/UI/Components/ManagedChooser.swift +++ b/TFM/UI/Components/ManagedChooser.swift @@ -17,11 +17,6 @@ final class ManagedChooserState { self.selected = selected } - // Swift 6.3.3's EarlyPerfInliner crashes while synthesizing this generic - // class's optimized destructor. Keeping just the destructor unoptimized - // preserves normal release optimization for the chooser and the app. - @_optimize(none) deinit {} - func activate(_ id: ID) { cursor = id switch mode { diff --git a/TFMTests/StoreKitTrialTests.swift b/TFMTests/StoreKitTrialTests.swift index b797236f..9568b3a3 100644 --- a/TFMTests/StoreKitTrialTests.swift +++ b/TFMTests/StoreKitTrialTests.swift @@ -50,8 +50,8 @@ struct StoreKitTrialTests { @Test func lifetimePurchaseTakesPrecedenceOverAnnualSubscription() async throws { let fixture = try Fixture() - try await fixture.session.buyProduct(identifier: ProAccessController.annualProductID) - try await fixture.session.buyProduct(identifier: ProAccessController.lifetimeProductID) + try await fixture.purchase(ProAccessController.annualProductID) + try await fixture.purchase(ProAccessController.lifetimeProductID) let access = fixture.controller() await access.refresh() @@ -63,7 +63,7 @@ struct StoreKitTrialTests { @Test func cancellationAndNetworkFailuresDoNotRemoveAnnualAccess() async throws { let fixture = try Fixture() - try await fixture.session.buyProduct(identifier: ProAccessController.annualProductID) + try await fixture.purchase(ProAccessController.annualProductID) let access = fixture.controller() await access.refresh() let active = access.status @@ -110,12 +110,14 @@ struct StoreKitTrialTests { @Test func unverifiedAnnualTransactionNeverGrantsAccess() async throws { let fixture = try Fixture() - try await fixture.session.buyProduct(identifier: ProAccessController.annualProductID) try await fixture.session.setSimulatedError(.verification(.invalidSignature), forAPI: .verification) let access = fixture.controller() await access.refresh() + await access.reloadProducts() + await access.purchaseAnnual() - #expect(access.status == .verificationFailed) + #expect(access.error == .purchaseVerificationFailed) + await access.refresh() #expect(!access.hasProAccess) } @@ -192,6 +194,30 @@ struct StoreKitTrialTests { ProAccessController(now: now, observeStore: false) } + func purchase(_ identifier: Product.ID) async throws { + let updates = Task { + for await _ in Transaction.updates { + guard !Task.isCancelled else { return } + } + } + defer { updates.cancel() } + await Task.yield() + let products = try await Product.products(for: [identifier]) + let product = try #require(products.first { $0.id == identifier }) + let result = try await product.purchase() + guard case .success(let verification) = result else { + Issue.record("StoreKit did not complete the \(identifier) purchase: \(result)") + return + } + let transaction = try verification.payloadValue + await transaction.finish() + for _ in 0..<100 { + if await Transaction.latest(for: identifier) != nil { return } + try await Task.sleep(for: .milliseconds(50)) + } + Issue.record("StoreKit did not publish the \(identifier) transaction") + } + static func modifiedConfiguration(_ name: String) throws -> URL { var root = try #require( JSONSerialization.jsonObject(with: Data(contentsOf: configurationURL)) as? [String: Any]) diff --git a/Termind.xcodeproj/project.pbxproj b/Termind.xcodeproj/project.pbxproj index 3e39880d..f348636d 100644 --- a/Termind.xcodeproj/project.pbxproj +++ b/Termind.xcodeproj/project.pbxproj @@ -8,7 +8,7 @@ /* Begin PBXBuildFile section */ 0202B16D630CC57432748F0C /* TermindDomain.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A62058825D6607920F1E2A1 /* TermindDomain.framework */; }; - 03892FFD3F1E351BD2C296E4 /* TermindWidgets.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 32414DBD2157FBAD4D00056D /* TermindWidgets.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 03892FFD3F1E351BD2C296E4 /* TermindWidgets.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 32414DBD2157FBAD4D00056D /* TermindWidgets.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 082994E88792AF7D1F99B147 /* TermindPersistence.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 244632CCDB1CA43F45C0EB54 /* TermindPersistence.framework */; }; 0861B3AA103F736DEE93983B /* TermindInfrastructure.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 67B48098792E58C2955768F2 /* TermindInfrastructure.framework */; }; 08620C447AFE3884EA26ADCC /* TermindPresentation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F2CD72AE76428E896F81B64 /* TermindPresentation.framework */; }; @@ -382,15 +382,15 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - B7FBAAD7AF587EA9ADB523C5 /* Embed App Extensions */ = { + B7FBAAD7AF587EA9ADB523C5 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 13; files = ( - 03892FFD3F1E351BD2C296E4 /* TermindWidgets.appex in Embed App Extensions */, + 03892FFD3F1E351BD2C296E4 /* TermindWidgets.appex in Embed Foundation Extensions */, ); - name = "Embed App Extensions"; + name = "Embed Foundation Extensions"; runOnlyForDeploymentPostprocessing = 0; }; TRMD00000000000000000085 /* Embed MCP Bridge */ = { @@ -760,7 +760,7 @@ isa = PBXNativeTarget; buildConfigurationList = 20CE6E8A93D697985F372EA6 /* Build configuration list for PBXNativeTarget "TFI" */; buildPhases = ( - B7FBAAD7AF587EA9ADB523C5 /* Embed App Extensions */, + B7FBAAD7AF587EA9ADB523C5 /* Embed Foundation Extensions */, AC89B83FA8E4154383D9AC81 /* Sources */, 7B09CFC5B32584951BD4C8F9 /* Frameworks */, 8F0C5245592A0E2AFB85E50F /* Resources */, @@ -1135,7 +1135,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 2660; - LastUpgradeCheck = 2660; + LastUpgradeCheck = 2700; TargetAttributes = { 1EAB6B47E04D61C8CFC54762 = { SystemCapabilities = { @@ -1615,13 +1615,15 @@ 00A459BF9EBF49731B530B7A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindremoteinfrastructure; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1638,7 +1640,6 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = F6SUNDBBN9; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -1661,13 +1662,15 @@ 26CFA808AF64A9ACDD4DF923 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindpersistence; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1682,13 +1685,15 @@ 2E96D702E8EE688FB9B4DC71 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindinfrastructure; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1703,13 +1708,15 @@ 30D03D452305AD59ECD3C460 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindapplication; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1729,13 +1736,17 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = TFI/TFI.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; - DEVELOPMENT_TEAM = F6SUNDBBN9; + CURRENT_PROJECT_VERSION = 9; GENERATE_INFOPLIST_FILE = YES; ICLOUD_CONTAINER_ENVIRONMENT = Development; INFOPLIST_FILE = TFI/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Termind; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; + INFOPLIST_KEY_NSCameraUsageDescription = "Termind uses the camera to attach photos to your chat."; + INFOPLIST_KEY_NSFaceIDUsageDescription = "Authenticate to use your SSH keys."; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Termind uses the microphone to transcribe speech into your chat draft."; + INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "Termind uses Apple Speech Recognition to turn your recording into text. Depending on system settings and language support, Apple may process the audio online."; + INFOPLIST_KEY_NSSupportsLiveActivities = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; @@ -1746,7 +1757,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 1.7.7; + MARKETING_VERSION = 1.8.0; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind; PRODUCT_MODULE_NAME = TermindIOS; PRODUCT_NAME = Termind; @@ -1761,7 +1772,6 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = F6SUNDBBN9; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -1783,13 +1793,15 @@ 51206A2D54AE88E0247CD9C6 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindpresentation; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1805,7 +1817,6 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = F6SUNDBBN9; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -1827,13 +1838,15 @@ 61A9E8DD25722DF762DBC92A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindremoteinfrastructure; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1851,7 +1864,6 @@ APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 6; - DEVELOPMENT_TEAM = F6SUNDBBN9; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = TFIWidgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Termind Workspaces"; @@ -1876,13 +1888,15 @@ 925DF91139ED491057366958 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindpersistence; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1897,13 +1911,15 @@ 9A9993A9405331488B140C6A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.terminddomain; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1918,13 +1934,15 @@ A1DAF8C420A41777983ECE89 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindpresentation; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1939,13 +1957,15 @@ BD9E47297AE0FA3235A4633E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.terminddomain; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1960,13 +1980,15 @@ C4ED38FD24B69F063AC1FCC7 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindapplication; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -1986,13 +2008,17 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = TFI/TFI.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; - DEVELOPMENT_TEAM = F6SUNDBBN9; + CURRENT_PROJECT_VERSION = 9; GENERATE_INFOPLIST_FILE = YES; ICLOUD_CONTAINER_ENVIRONMENT = Production; INFOPLIST_FILE = TFI/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Termind; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; + INFOPLIST_KEY_NSCameraUsageDescription = "Termind uses the camera to attach photos to your chat."; + INFOPLIST_KEY_NSFaceIDUsageDescription = "Authenticate to use your SSH keys."; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Termind uses the microphone to transcribe speech into your chat draft."; + INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "Termind uses Apple Speech Recognition to turn your recording into text. Depending on system settings and language support, Apple may process the audio online."; + INFOPLIST_KEY_NSSupportsLiveActivities = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; @@ -2003,7 +2029,7 @@ "@executable_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 1.7.7; + MARKETING_VERSION = 1.8.0; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind; PRODUCT_MODULE_NAME = TermindIOS; PRODUCT_NAME = Termind; @@ -2020,7 +2046,6 @@ APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 6; - DEVELOPMENT_TEAM = F6SUNDBBN9; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = TFIWidgets/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Termind Workspaces"; @@ -2045,13 +2070,15 @@ E072A089DE54B923933916DA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + ENABLE_MODULE_VERIFIER = YES; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; MACH_O_TYPE = staticlib; MACOSX_DEPLOYMENT_TARGET = 15.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++14"; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind.termindinfrastructure; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -2068,7 +2095,6 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = F6SUNDBBN9; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 18.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -2093,12 +2119,33 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 6; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = F6SUNDBBN9; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -2108,11 +2155,18 @@ "DEBUG=1", "$(inherited)", ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.6.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_APPROACHABLE_CONCURRENCY = YES; SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; @@ -2129,20 +2183,48 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 6; + DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = F6SUNDBBN9; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.6.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_APPROACHABLE_CONCURRENCY = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; @@ -2164,9 +2246,9 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 13; + CURRENT_PROJECT_VERSION = 14; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = ""; - DEVELOPMENT_TEAM = F6SUNDBBN9; ENABLE_APP_SANDBOX = YES; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; @@ -2181,7 +2263,7 @@ ); LM_SKIP_METADATA_EXTRACTION = YES; MACOSX_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 1.7.6; + MARKETING_VERSION = 1.8.0; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind; PRODUCT_MODULE_NAME = Termind; PRODUCT_NAME = Termind; @@ -2201,9 +2283,9 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 13; + CURRENT_PROJECT_VERSION = 14; + DEAD_CODE_STRIPPING = YES; DEVELOPMENT_ASSET_PATHS = ""; - DEVELOPMENT_TEAM = F6SUNDBBN9; ENABLE_APP_SANDBOX = YES; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; @@ -2222,7 +2304,7 @@ ); LM_SKIP_METADATA_EXTRACTION = YES; MACOSX_DEPLOYMENT_TARGET = 15.0; - MARKETING_VERSION = 1.7.6; + MARKETING_VERSION = 1.8.0; PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind; PRODUCT_MODULE_NAME = Termind; PRODUCT_NAME = Termind; @@ -2238,7 +2320,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = F6SUNDBBN9; + DEAD_CODE_STRIPPING = YES; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 15.0; @@ -2258,7 +2340,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = F6SUNDBBN9; + DEAD_CODE_STRIPPING = YES; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 15.0; @@ -2280,7 +2362,7 @@ CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; CODE_SIGN_STYLE = Automatic; CREATE_INFOPLIST_SECTION_IN_BINARY = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + DEAD_CODE_STRIPPING = YES; ENABLE_APP_SANDBOX = YES; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; @@ -2304,7 +2386,7 @@ CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; CODE_SIGN_STYLE = Automatic; CREATE_INFOPLIST_SECTION_IN_BINARY = YES; - DEVELOPMENT_TEAM = F6SUNDBBN9; + DEAD_CODE_STRIPPING = YES; ENABLE_APP_SANDBOX = YES; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; diff --git a/Termind.xcodeproj/xcshareddata/xcschemes/TFI.xcscheme b/Termind.xcodeproj/xcshareddata/xcschemes/TFI.xcscheme index f963120f..6d4a546b 100644 --- a/Termind.xcodeproj/xcshareddata/xcschemes/TFI.xcscheme +++ b/Termind.xcodeproj/xcshareddata/xcschemes/TFI.xcscheme @@ -1,39 +1,98 @@ - - - + + + - - + + - + - - + + - - + + - - - + + + - - - + + + - + - + - \ No newline at end of file + diff --git a/Termind.xcodeproj/xcshareddata/xcschemes/TFM.xcscheme b/Termind.xcodeproj/xcshareddata/xcschemes/TFM.xcscheme index 1cd91681..1fe2ce85 100644 --- a/Termind.xcodeproj/xcshareddata/xcschemes/TFM.xcscheme +++ b/Termind.xcodeproj/xcshareddata/xcschemes/TFM.xcscheme @@ -1,6 +1,6 @@