diff --git a/ios/Approach.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Approach.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index a1de46b61..3a6a992e3 100644 --- a/ios/Approach.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Approach.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -18,6 +18,15 @@ "version" : "6.16.0" } }, + { + "identity" : "sfsafesymbols", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SFSafeSymbols/SFSafeSymbols.git", + "state" : { + "revision" : "7cca2d60925876b5953a2cf7341cd80fbeac983c", + "version" : "4.1.1" + } + }, { "identity" : "swift-algorithms", "kind" : "remoteSourceControl", diff --git a/ios/Approach/Package.swift b/ios/Approach/Package.swift index 98233d4b7..d30e0e4c3 100644 --- a/ios/Approach/Package.swift +++ b/ios/Approach/Package.swift @@ -134,6 +134,7 @@ let package = Package( .package(url: "https://github.com/pointfreeco/swift-identified-collections.git", from: "1.0.0"), .package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", from: "1.11.1"), .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay.git", from: "1.0.0"), + .package(url: "https://github.com/SFSafeSymbols/SFSafeSymbols.git", from: "4.1.1"), .package(url: "https://github.com/TelemetryDeck/SwiftClient.git", from: "1.4.4"), ], targets: [ @@ -398,7 +399,6 @@ let package = Package( "PreferenceServiceInterface", "RecentlyUsedServiceInterface", "SeriesListFeature", - "SortOrderLibrary", "StatisticsWidgetsLayoutFeature", ] ), @@ -500,6 +500,7 @@ let package = Package( dependencies: [ "GamesListFeature", "SeriesEditorFeature", + "SortOrderLibrary", ] ), .testTarget( @@ -1166,7 +1167,9 @@ let package = Package( // MARK: - Libraries .target( name: "AssetsLibrary", - dependencies: [], + dependencies: [ + .product(name: "SFSafeSymbols", package: "SFSafeSymbols"), + ], resources: [ .process("Resources"), ] diff --git a/ios/Approach/Package.swift.toml b/ios/Approach/Package.swift.toml index 409489b24..86f1ff51f 100644 --- a/ios/Approach/Package.swift.toml +++ b/ios/Approach/Package.swift.toml @@ -78,7 +78,6 @@ libraries = [ "Equatable", "Form", "ModelsViews", "ResourcePicker", "SwiftUIExte [features.LeaguesList] features = [ "LeagueEditor", "SeriesList", "StatisticsWidgetsLayout" ] services = [ "Preference", "RecentlyUsed" ] -libraries = [ "SortOrder" ] [features.OpponentDetails] features = [ "BowlerEditor" ] @@ -105,6 +104,7 @@ libraries = [ "DateTime", "Equatable", "Form", "ModelsViews", "ResourcePicker", [features.SeriesList] features = [ "GamesList", "SeriesEditor" ] +libraries = [ "SortOrder" ] [features.Settings] features = [ "FeatureFlagsList", "OpponentsList" ] @@ -236,6 +236,7 @@ libraries = [ "Tips" ] [libraries.Assets] skip_tests = true +dependencies = [ "SFSafeSymbols" ] [libraries.Assets.resources] processed = [ "Resources" ] @@ -368,6 +369,10 @@ from = "1.0.0" url = "https://github.com/pointfreeco/swift-identified-collections.git" from = "1.0.0" +[dependencies.SFSafeSymbols] +url = "https://github.com/SFSafeSymbols/SFSafeSymbols.git" +from = "4.1.1" + [dependencies.SnapshotTesting] suitable_for_dependents_matching = "\\w+Tests$" url = "https://github.com/pointfreeco/swift-snapshot-testing.git" diff --git a/ios/Approach/Sources/AccessoriesOverviewFeature/AccessoriesOverviewView.swift b/ios/Approach/Sources/AccessoriesOverviewFeature/AccessoriesOverviewView.swift index 0a7ce9beb..0d5396a27 100644 --- a/ios/Approach/Sources/AccessoriesOverviewFeature/AccessoriesOverviewView.swift +++ b/ios/Approach/Sources/AccessoriesOverviewFeature/AccessoriesOverviewView.swift @@ -68,8 +68,7 @@ public struct AccessoriesOverviewView: View { ForEach(row.group) { kind in Button { viewStore.send(.didTapGearKind(kind)) } label: { HStack { - Image(systemName: kind.systemImage) - .resizable() + Image(systemSymbol: kind.systemSymbol) .scaledToFit() .frame(width: .smallIcon, height: .smallIcon) Text(kind.pluralDescription) @@ -116,7 +115,7 @@ public struct AccessoriesOverviewView: View { Button(Strings.Alley.List.add) { viewStore.send(.didTapAddAlley) } Button(Strings.Gear.List.add) { viewStore.send(.didTapAddGear) } } label: { - Image(systemName: "plus") + Image(systemSymbol: .plus) } } } diff --git a/ios/Approach/Sources/AlleyEditorFeature/AlleyEditorView.swift b/ios/Approach/Sources/AlleyEditorFeature/AlleyEditorView.swift index 1e2a40f9c..f608ec982 100644 --- a/ios/Approach/Sources/AlleyEditorFeature/AlleyEditorView.swift +++ b/ios/Approach/Sources/AlleyEditorFeature/AlleyEditorView.swift @@ -75,7 +75,7 @@ public struct AlleyEditorView: View { Spacer() if viewStore.location != nil { Button { viewStore.send(.didTapRemoveAddressButton) } label: { - Image(systemName: "x.circle.fill") + Image(systemSymbol: .xCircleFill) } } } diff --git a/ios/Approach/Sources/AlleyEditorFeature/AlleyLanesEditor/AlleyLanesEditorView.swift b/ios/Approach/Sources/AlleyEditorFeature/AlleyLanesEditor/AlleyLanesEditorView.swift index 5acf19aed..3b9ad0b51 100644 --- a/ios/Approach/Sources/AlleyEditorFeature/AlleyLanesEditor/AlleyLanesEditorView.swift +++ b/ios/Approach/Sources/AlleyEditorFeature/AlleyLanesEditor/AlleyLanesEditorView.swift @@ -1,3 +1,4 @@ +import AssetsLibrary import ComposableArchitecture import FeatureActionLibrary import LaneEditorFeature @@ -47,11 +48,11 @@ public struct AlleyLanesEditorView: View { Section { Button { viewStore.send(.didTapAddLaneButton) } label: { - Label(Strings.Lane.List.add, systemImage: "plus.square") + Label(Strings.Lane.List.add, systemSymbol: .plusSquare) } Button { viewStore.send(.didTapAddMultipleLanesButton) } label: { - Label(Strings.Lane.List.addMultiple, systemImage: "plus.square.on.square") + Label(Strings.Lane.List.addMultiple, systemSymbol: .plusSquareOnSquare) } } } diff --git a/ios/Approach/Sources/AppFeature/TabbedContentView.swift b/ios/Approach/Sources/AppFeature/TabbedContentView.swift index 7fae0c59c..ec8ed25de 100644 --- a/ios/Approach/Sources/AppFeature/TabbedContentView.swift +++ b/ios/Approach/Sources/AppFeature/TabbedContentView.swift @@ -49,7 +49,7 @@ public struct TabbedContentView: View { } .tag(tab) .tabItem { - Label(tab.name, systemImage: tab.image) + Label(tab.name, systemSymbol: tab.symbol) } } } @@ -84,16 +84,16 @@ extension TabbedContent.Tab { } } - var image: String { + var symbol: SFSymbol { switch self { case .accessories: - return "bag" + return .bag case .settings: - return "gear" + return .gear case .overview: - return "figure.bowling" + return .figureBowling case .statistics: - return "chart.bar" + return .chartBar } } } diff --git a/ios/Approach/Sources/AssetsLibrary/SFSafeSymbols+Exports.swift b/ios/Approach/Sources/AssetsLibrary/SFSafeSymbols+Exports.swift new file mode 100644 index 000000000..07e0eb8b3 --- /dev/null +++ b/ios/Approach/Sources/AssetsLibrary/SFSafeSymbols+Exports.swift @@ -0,0 +1 @@ +@_exported import SFSafeSymbols diff --git a/ios/Approach/Sources/AvatarEditorFeature/AvatarEditorView.swift b/ios/Approach/Sources/AvatarEditorFeature/AvatarEditorView.swift index b6f4e2ba5..526624ef8 100644 --- a/ios/Approach/Sources/AvatarEditorFeature/AvatarEditorView.swift +++ b/ios/Approach/Sources/AvatarEditorFeature/AvatarEditorView.swift @@ -1,3 +1,4 @@ +import AssetsLibrary import AvatarServiceInterface import ComposableArchitecture import ModelsLibrary @@ -26,7 +27,7 @@ public struct AvatarEditorView: View { VStack { AvatarView(viewStore.avatar, size: .extraLargeIcon) LazyVGrid(columns: [.init(), .init(), .init()]) { - Image(systemName: "camera") + Image(systemSymbol: .camera) .resizable() .aspectRatio(contentMode: .fit) .frame(width: .smallIcon, height: .smallIcon) @@ -36,7 +37,7 @@ public struct AvatarEditorView: View { .frame(width: .largeIcon, height: .largeIcon) } - Image(systemName: "photo.on.rectangle") + Image(systemSymbol: .photoOnRectangle) .resizable() .frame(width: .standardIcon, height: .standardIcon) } diff --git a/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsHeader.swift b/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsHeader.swift index 5d77f76af..2ff3b1687 100644 --- a/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsHeader.swift +++ b/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsHeader.swift @@ -102,7 +102,7 @@ public struct GameDetailsHeaderView: View { HStack { Text(String(describing: next)) .font(.caption) - Image(systemName: "chevron.forward") + Image(systemSymbol: .chevronForward) .resizable() .scaledToFit() .frame(width: .tinyIcon, height: .tinyIcon) diff --git a/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsView.swift b/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsView.swift index a53bb9ae8..3a0c87a3d 100644 --- a/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsView.swift +++ b/ios/Approach/Sources/GamesEditorFeature/Game/GameDetailsView.swift @@ -51,7 +51,7 @@ public struct GameDetailsView: View { Strings.Opponent.title, value: viewStore.game.matchPlay?.opponent?.name ?? Strings.none ) - Image(systemName: "chevron.forward") + Image(systemSymbol: .chevronForward) .resizable() .scaledToFit() .frame(width: .tinyIcon, height: .tinyIcon) diff --git a/ios/Approach/Sources/GamesEditorFeature/Manage/GamesHeader.swift b/ios/Approach/Sources/GamesEditorFeature/Manage/GamesHeader.swift index 4af2c1d9f..3c212f211 100644 --- a/ios/Approach/Sources/GamesEditorFeature/Manage/GamesHeader.swift +++ b/ios/Approach/Sources/GamesEditorFeature/Manage/GamesHeader.swift @@ -64,20 +64,20 @@ public struct GamesHeaderView: View { public var body: some View { WithViewStore(store, observe: { $0 }, send: { .view($0) }, content: { viewStore in HStack { - headerButton(systemName: "chevron.backward") { viewStore.send(.didTapCloseButton) } + headerButton(systemSymbol: .chevronBackward) { viewStore.send(.didTapCloseButton) } Spacer() Text(Strings.Game.titleWithOrdinal(viewStore.currentGameIndex + 1)) .font(.caption) .foregroundColor(.white) Spacer() - headerButton(systemName: "gear") { viewStore.send(.didTapSettingsButton) } + headerButton(systemSymbol: .gear) { viewStore.send(.didTapSettingsButton) } } }) } - private func headerButton(systemName: String, action: @escaping () -> Void) -> some View { + private func headerButton(systemSymbol: SFSymbol, action: @escaping () -> Void) -> some View { Button(action: action) { - Image(systemName: systemName) + Image(systemSymbol: systemSymbol) .resizable() .scaledToFit() .frame(width: .smallIcon, height: .smallIcon) diff --git a/ios/Approach/Sources/GamesEditorFeature/Roll/RollEditor.swift b/ios/Approach/Sources/GamesEditorFeature/Roll/RollEditor.swift index 480258005..e74984dbc 100644 --- a/ios/Approach/Sources/GamesEditorFeature/Roll/RollEditor.swift +++ b/ios/Approach/Sources/GamesEditorFeature/Roll/RollEditor.swift @@ -96,7 +96,7 @@ public struct RollEditorView: View { HStack(spacing: .smallSpacing) { Text(Strings.Roll.Properties.Foul.title) .foregroundColor(viewStore.didFoul ? Asset.Colors.Error.default.swiftUIColor : .white) - Image(systemName: viewStore.didFoul ? "f.cursive.circle.fill" : "f.cursive.circle") + Image(systemSymbol: viewStore.didFoul ? .fCursiveCircleFill : .fCursiveCircle) .resizable() .frame(width: .smallIcon, height: .smallIcon) .foregroundColor(viewStore.didFoul ? Asset.Colors.Error.default.swiftUIColor : .white) diff --git a/ios/Approach/Sources/ModelsViewsLibrary/Gear+View.swift b/ios/Approach/Sources/ModelsViewsLibrary/Gear+View.swift index e70034dc6..a76d23017 100644 --- a/ios/Approach/Sources/ModelsViewsLibrary/Gear+View.swift +++ b/ios/Approach/Sources/ModelsViewsLibrary/Gear+View.swift @@ -1,3 +1,4 @@ +import AssetsLibrary import ModelsLibrary import SwiftUI @@ -10,18 +11,18 @@ extension Gear { } public var body: some SwiftUI.View { - Label(gear.name, systemImage: gear.kind.systemImage) + Label(gear.name, systemSymbol: gear.kind.systemSymbol) } } } extension Gear.Kind { - public var systemImage: String { + public var systemSymbol: SFSymbol { switch self { - case .bowlingBall: return "poweroutlet.type.h" - case .shoes: return "shoeprints.fill" - case .towel: return "square.split.bottomrightquarter" - case .other: return "questionmark.app" + case .bowlingBall: return .poweroutletTypeH + case .shoes: return .shoeprintsFill + case .towel: return .squareSplitBottomrightquarter + case .other: return .questionmarkApp } } } diff --git a/ios/Approach/Sources/ModelsViewsLibrary/Lane+View.swift b/ios/Approach/Sources/ModelsViewsLibrary/Lane+View.swift index aba3ad6e4..1e3785958 100644 --- a/ios/Approach/Sources/ModelsViewsLibrary/Lane+View.swift +++ b/ios/Approach/Sources/ModelsViewsLibrary/Lane+View.swift @@ -23,7 +23,7 @@ extension Lane { .frame(maxWidth: .infinity, alignment: .leading) // TODO: choose a better icon for the wall indicator if position != .noWall { - Image(systemName: "decrease.quotelevel") + Image(systemSymbol: .decreaseQuotelevel) .opacity(0.7) } } diff --git a/ios/Approach/Sources/ResourcePickerLibrary/ResourcePickerView.swift b/ios/Approach/Sources/ResourcePickerLibrary/ResourcePickerView.swift index 0a6e93c25..1157ee3c8 100644 --- a/ios/Approach/Sources/ResourcePickerLibrary/ResourcePickerView.swift +++ b/ios/Approach/Sources/ResourcePickerLibrary/ResourcePickerView.swift @@ -41,7 +41,7 @@ public struct ResourcePickerView: View { viewStore.send(.didTapOption(ordering)) } label: { HStack(alignment: .center, spacing: .standardSpacing) { - Image(systemName: viewStore.selected == ordering ? "checkmark.circle.fill" : "circle") + Image(systemSymbol: viewStore.selected == ordering ? .checkmarkCircleFill : .circle) .resizable() .frame(width: .smallIcon, height: .smallIcon) .foregroundColor(Asset.Colors.Action.default) diff --git a/ios/Approach/Sources/StatisticsWidgetsLayoutFeature/Widgets/MoveableWidget.swift b/ios/Approach/Sources/StatisticsWidgetsLayoutFeature/Widgets/MoveableWidget.swift index 4b6926051..29f1b3a19 100644 --- a/ios/Approach/Sources/StatisticsWidgetsLayoutFeature/Widgets/MoveableWidget.swift +++ b/ios/Approach/Sources/StatisticsWidgetsLayoutFeature/Widgets/MoveableWidget.swift @@ -40,7 +40,7 @@ public struct MoveableWidget: View { .fill(Asset.Colors.Destructive.default.swiftUIColor) .frame(width: .smallerIcon, height: .smallerIcon) - Image(systemName: "xmark") + Image(systemSymbol: .xmark) .resizable() .scaledToFit() .frame(width: .tinyIcon, height: .tinyIcon) diff --git a/ios/Approach/Sources/TipsLibrary/Views/BasicTipView.swift b/ios/Approach/Sources/TipsLibrary/Views/BasicTipView.swift index e1b458921..739a97463 100644 --- a/ios/Approach/Sources/TipsLibrary/Views/BasicTipView.swift +++ b/ios/Approach/Sources/TipsLibrary/Views/BasicTipView.swift @@ -1,3 +1,4 @@ +import AssetsLibrary import SwiftUI import ViewsLibrary @@ -17,7 +18,7 @@ public struct BasicTipView: View { .font(.headline) .frame(maxWidth: .infinity, alignment: .leading) Button(action: onDismiss) { - Image(systemName: "xmark") + Image(systemSymbol: .xmark) .resizable() .scaledToFit() .frame(width: .smallIcon, height: .smallSpacing) diff --git a/ios/Approach/Sources/ViewsLibrary/Buttons/AddButton.swift b/ios/Approach/Sources/ViewsLibrary/Buttons/AddButton.swift index 4b248d86c..ebaa0486d 100644 --- a/ios/Approach/Sources/ViewsLibrary/Buttons/AddButton.swift +++ b/ios/Approach/Sources/ViewsLibrary/Buttons/AddButton.swift @@ -1,3 +1,4 @@ +import AssetsLibrary import SwiftUI public struct AddButton: View { @@ -9,7 +10,7 @@ public struct AddButton: View { public var body: some View { Button(action: perform) { - Image(systemName: "plus") + Image(systemSymbol: .plus) } } } diff --git a/ios/Approach/Sources/ViewsLibrary/Buttons/DeleteButton.swift b/ios/Approach/Sources/ViewsLibrary/Buttons/DeleteButton.swift index c66a8e114..f6a9b7220 100644 --- a/ios/Approach/Sources/ViewsLibrary/Buttons/DeleteButton.swift +++ b/ios/Approach/Sources/ViewsLibrary/Buttons/DeleteButton.swift @@ -11,7 +11,7 @@ public struct DeleteButton: View { public var body: some View { Button(role: .destructive, action: perform) { - Label(Strings.Action.delete, systemImage: "trash") + Label(Strings.Action.delete, systemSymbol: .trash) .foregroundColor(Asset.Colors.Destructive.default) } .tint(Asset.Colors.Destructive.default) diff --git a/ios/Approach/Sources/ViewsLibrary/Buttons/EditButton.swift b/ios/Approach/Sources/ViewsLibrary/Buttons/EditButton.swift index c1b685712..48c3fa65c 100644 --- a/ios/Approach/Sources/ViewsLibrary/Buttons/EditButton.swift +++ b/ios/Approach/Sources/ViewsLibrary/Buttons/EditButton.swift @@ -11,7 +11,7 @@ public struct EditButton: View { public var body: some View { Button(action: perform) { - Label(Strings.Action.edit, systemImage: "pencil") + Label(Strings.Action.edit, systemSymbol: .pencil) } .tint(Asset.Colors.Action.default) } diff --git a/ios/Approach/Sources/ViewsLibrary/Buttons/FilterButton.swift b/ios/Approach/Sources/ViewsLibrary/Buttons/FilterButton.swift index 140ab271a..2a5229aa3 100644 --- a/ios/Approach/Sources/ViewsLibrary/Buttons/FilterButton.swift +++ b/ios/Approach/Sources/ViewsLibrary/Buttons/FilterButton.swift @@ -1,3 +1,4 @@ +import AssetsLibrary import SwiftUI public struct FilterButton: View { @@ -11,7 +12,7 @@ public struct FilterButton: View { public var body: some View { Button(action: perform) { - Image(systemName: isActive ? "line.3.horizontal.decrease.circle.fill" : "line.3.horizontal.decrease.circle") + Image(systemSymbol: isActive ? .line3HorizontalDecreaseCircleFill : .line3HorizontalDecreaseCircle) } } } diff --git a/ios/Approach/Sources/ViewsLibrary/Buttons/SortButton.swift b/ios/Approach/Sources/ViewsLibrary/Buttons/SortButton.swift index 62c6c1259..775ad813c 100644 --- a/ios/Approach/Sources/ViewsLibrary/Buttons/SortButton.swift +++ b/ios/Approach/Sources/ViewsLibrary/Buttons/SortButton.swift @@ -1,3 +1,4 @@ +import AssetsLibrary import SwiftUI public struct SortButton: View { @@ -11,7 +12,7 @@ public struct SortButton: View { public var body: some View { Button(action: perform) { - Image(systemName: isActive ? "arrow.up.arrow.down.square.fill" : "arrow.up.arrow.down.square") + Image(systemSymbol: isActive ? .arrowUpArrowDownSquareFill : .arrowUpArrowDownSquare) } } }