commit ff89c703ed37c0da85cbbfa4d36bb44cead6c8d7
parent aa10881dc18e29131a9aef0b79c0302d9f4b0c89
Author: Michael Camilleri <[email protected]>
Date: Tue, 16 Jun 2026 17:01:10 +0900
Support iOS/iPadOS 17.5
This commit lowers the app's deployment target from iOS/iPadOS 26 to
iOS/iPadOS 17.5 so older supported simulators and devices can run
Crossmate. The 26 toolbar and glass affordances remain unchanged on
current systems, while older systems get simpler fallbacks instead of
failing availability checks.
Co-Authored-By: Codex GPT 5.5 <[email protected]>
Diffstat:
6 files changed, 49 insertions(+), 12 deletions(-)
diff --git a/Crossmate.xcodeproj/project.pbxproj b/Crossmate.xcodeproj/project.pbxproj
@@ -151,6 +151,7 @@
C1930083671621AC79CF95DD /* MovesUpdaterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF6157D97271205626E207C /* MovesUpdaterTests.swift */; };
C1D97A4CD02BC9C22C4208BB /* NYTAuthServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED8154F949E1D94252F70765 /* NYTAuthServiceTests.swift */; };
C30C0C4E54E4209A22843872 /* CrossmateModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F93AC31640C40FCC039570A3 /* CrossmateModel.xcdatamodeld */; };
+ C472EF02D8C7B0AC1D2284B8 /* CustomButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9B757D86362CD6F0500E9CB /* CustomButtons.swift */; };
C511387D9FFBCC2E2F5EF699 /* NotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 51318FC5DAE02D35CB005729 /* NotificationService.appex */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
C58F15CBEADA72032B54009D /* ReplayControlsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847415468DBB1C566D18BC17 /* ReplayControlsTests.swift */; };
C843CADAA263CED503528A4E /* NYTBrowseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3413F8755236FC0578AF8109 /* NYTBrowseView.swift */; };
@@ -420,6 +421,7 @@
F5DF04E70017065DFA95B396 /* PuzzleModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PuzzleModifiers.swift; sourceTree = "<group>"; };
F64DAE64C9AA042B330C526F /* SessionMonitorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionMonitorTests.swift; sourceTree = "<group>"; };
F97B399E89BBB37730F2F1E9 /* TestHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = "<group>"; };
+ F9B757D86362CD6F0500E9CB /* CustomButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomButtons.swift; sourceTree = "<group>"; };
FAF6E3F3558E128E7A482A61 /* PushRequestAuthenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushRequestAuthenticator.swift; sourceTree = "<group>"; };
FDE193CAB325C991952D7CE5 /* PUZToXDConverterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PUZToXDConverterTests.swift; sourceTree = "<group>"; };
FEDD63AD5E33E2B0399780EF /* NotificationNavigationBrokerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationNavigationBrokerTests.swift; sourceTree = "<group>"; };
@@ -666,6 +668,7 @@
children = (
CD68E9CA9D3057FE07E985E1 /* AnnouncementBanner.swift */,
B024B2FFB11E51E9724BBE23 /* CompactSlider.swift */,
+ F9B757D86362CD6F0500E9CB /* CustomButtons.swift */,
065CD67A1D9F7B63AE6B42D6 /* FriendAvatarView.swift */,
6B1F07B5DDE2A8B49B28392A /* GridThumbnailView.swift */,
836B8D4B351C9225162A82C0 /* Layouts.swift */,
@@ -1002,6 +1005,7 @@
2571BA6482B3E896A80FF393 /* CompactSlider.swift in Sources */,
DE9E4FAB098731A650F2D306 /* CrossmateApp.swift in Sources */,
C30C0C4E54E4209A22843872 /* CrossmateModel.xcdatamodeld in Sources */,
+ C472EF02D8C7B0AC1D2284B8 /* CustomButtons.swift in Sources */,
CCF3867C32C3F36E4F69A59E /* DebuggingMonitors.swift in Sources */,
0F2992C16A3A658DEA0F707E /* DiagnosticsView.swift in Sources */,
978F91DBAE94BC5DA1D94705 /* DriveMonitor.swift in Sources */,
@@ -1170,7 +1174,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 26.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.5;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1359,7 +1363,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 26.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.5;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
diff --git a/Crossmate/Views/Components/CustomButtons.swift b/Crossmate/Views/Components/CustomButtons.swift
@@ -0,0 +1,27 @@
+import SwiftUI
+
+extension View {
+ @ViewBuilder
+ func pencilGlass(isActive: Bool, tint: Color) -> some View {
+ if #available(iOS 26.0, *) {
+ glassEffect(isActive ? .regular.tint(tint) : .identity, in: Circle())
+ } else {
+ background {
+ if isActive {
+ Circle().fill(tint)
+ }
+ }
+ }
+ }
+
+ @ViewBuilder
+ func replayGlass() -> some View {
+ if #available(iOS 26.0, *) {
+ glassEffect(.regular.interactive(), in: .capsule)
+ } else {
+ overlay {
+ Capsule().strokeBorder(.quaternary, lineWidth: 0.5)
+ }
+ }
+ }
+}
diff --git a/Crossmate/Views/GameList/GameListView.swift b/Crossmate/Views/GameList/GameListView.swift
@@ -86,7 +86,9 @@ struct GameListView: View {
Image(systemName: "person.2")
}
}
- ToolbarSpacer(.fixed, placement: .topBarTrailing)
+ if #available(iOS 26.0, *) {
+ ToolbarSpacer(.fixed, placement: .topBarTrailing)
+ }
ToolbarItem(placement: .topBarTrailing) {
Button {
showingNewGame = true
diff --git a/Crossmate/Views/Puzzle/PuzzleModifiers.swift b/Crossmate/Views/Puzzle/PuzzleModifiers.swift
@@ -42,11 +42,9 @@ struct PuzzleToolbarModifier: ViewModifier {
Image(systemName: "pencil")
.foregroundStyle(pencilButtonForeground)
.padding(6)
- .glassEffect(
- !isSolved && session.isPencilMode
- ? .regular.tint(preferences.color.tint)
- : .identity,
- in: Circle()
+ .pencilGlass(
+ isActive: !isSolved && session.isPencilMode,
+ tint: preferences.color.tint
)
}
.accessibilityLabel("Pencil")
@@ -57,7 +55,13 @@ struct PuzzleToolbarModifier: ViewModifier {
if isSolved {
return .secondary
}
- return session.isPencilMode ? .white : .primary
+ if session.isPencilMode {
+ return .white
+ }
+ if #available(iOS 26.0, *) {
+ return .primary
+ }
+ return .accentColor
}
private var entryMenu: some View {
diff --git a/Crossmate/Views/Puzzle/SuccessPanel.swift b/Crossmate/Views/Puzzle/SuccessPanel.swift
@@ -340,7 +340,7 @@ private struct ReplayScrubber: View {
.font(.caption2.monospacedDigit().weight(.semibold))
.contentTransition(.numericText())
.frame(width: 28, height: 18)
- .glassEffect(.regular.interactive(), in: .capsule)
+ .replayGlass()
.animation(.easeInOut(duration: 0.16), value: replay.selectedPlaybackSpeed)
}
.foregroundStyle(.secondary)
@@ -397,7 +397,7 @@ private struct PlaybackControl: View {
.frame(width: 26, height: 18)
.padding(.horizontal, 7)
.padding(.vertical, 4)
- .glassEffect(.regular.interactive(), in: .capsule)
+ .replayGlass()
.animation(.easeInOut(duration: 0.18), value: isPlaying)
}
.buttonStyle(.plain)
diff --git a/project.yml b/project.yml
@@ -3,7 +3,7 @@ name: Crossmate
options:
bundleIdPrefix: net.inqk.crossmate
deploymentTarget:
- iOS: "26.0"
+ iOS: "17.5"
configFiles:
Debug: Generated/Config.xcconfig