diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index c80a5796..c95499ea 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 1920B04F2924AC8300744F60 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1920B04E2924AC8300744F60 /* Settings.bundle */; }; 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; }; 1F07F5672955D16A00F7BE95 /* SFSafeSymbols in Frameworks */ = {isa = PBXBuildFile; productRef = 1F07F5662955D16A00F7BE95 /* SFSafeSymbols */; }; + 1F07F5692955D3EC00F7BE95 /* SFSafeSymbols in Frameworks */ = {isa = PBXBuildFile; productRef = 1F07F5682955D3EC00F7BE95 /* SFSafeSymbols */; }; 1F0DD81C2932D2FF007608A4 /* AppScreenshotsScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0DD81B2932D2FF007608A4 /* AppScreenshotsScrollView.swift */; }; 1F0DD81F2932D84C007608A4 /* ExpandableText in Frameworks */ = {isa = PBXBuildFile; productRef = 1F0DD81E2932D84C007608A4 /* ExpandableText */; }; 1F0DD8212933B749007608A4 /* AppPermissionsGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0DD8202933B749007608A4 /* AppPermissionsGrid.swift */; }; @@ -983,6 +984,7 @@ B3C395F1284F2DE700DA9E2F /* KeychainAccess in Frameworks */, 99C4EF4D2979132100CB538D /* SemanticVersion in Frameworks */, 4879A95F2861046500FC1BBD /* AltSign in Frameworks */, + 1F07F5692955D3EC00F7BE95 /* SFSafeSymbols in Frameworks */, B39575F5284F29E20080B4FF /* Roxas.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2194,6 +2196,7 @@ B3C395F0284F2DE700DA9E2F /* KeychainAccess */, 4879A95E2861046500FC1BBD /* AltSign */, 99C4EF4C2979132100CB538D /* SemanticVersion */, + 1F07F5682955D3EC00F7BE95 /* SFSafeSymbols */, ); productName = AltStoreCore; productReference = BF66EE7E2501AE50007EE018 /* AltStoreCore.framework */; @@ -3776,6 +3779,11 @@ package = 1F07F5652955D16A00F7BE95 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */; productName = SFSafeSymbols; }; + 1F07F5682955D3EC00F7BE95 /* SFSafeSymbols */ = { + isa = XCSwiftPackageProductDependency; + package = 1F07F5652955D16A00F7BE95 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */; + productName = SFSafeSymbols; + }; 1F0DD81E2932D84C007608A4 /* ExpandableText */ = { isa = XCSwiftPackageProductDependency; package = 1F0DD81D2932D84C007608A4 /* XCRemoteSwiftPackageReference "ExpandableText" */; diff --git a/AltStore/Protocols/NavigationTab.swift b/AltStore/Protocols/NavigationTab.swift index 0b889af4..ca4e83a9 100644 --- a/AltStore/Protocols/NavigationTab.swift +++ b/AltStore/Protocols/NavigationTab.swift @@ -7,10 +7,11 @@ // import Foundation +import SFSafeSymbols protocol NavigationTab: RawRepresentable, Identifiable, CaseIterable, Hashable where RawValue == Int { static var defaultTab: Self { get } - var displaySymbol: String { get } + var displaySymbol: SFSymbol { get } var displayName: String { get } } diff --git a/AltStore/View Components/RatingStars.swift b/AltStore/View Components/RatingStars.swift index d8a6ce83..df39d116 100644 --- a/AltStore/View Components/RatingStars.swift +++ b/AltStore/View Components/RatingStars.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols struct RatingStars: View { @@ -15,7 +16,7 @@ struct RatingStars: View { var body: some View { HStack(spacing: 0) { ForEach(0..<5) { i in - Image(systemName: i < rating ? "star.fill" : "star") + Image(systemSymbol: i < rating ? .starFill : .star) .resizable() .aspectRatio(contentMode: .fit) } diff --git a/AltStore/Views/App Detail/AppPermissionsGrid.swift b/AltStore/Views/App Detail/AppPermissionsGrid.swift index 072c8cab..d8d05581 100644 --- a/AltStore/Views/App Detail/AppPermissionsGrid.swift +++ b/AltStore/Views/App Detail/AppPermissionsGrid.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols import AltStoreCore struct AppPermissionsGrid: View { @@ -34,7 +35,7 @@ struct AppPermissionGridItemView: View { self.isPopoverPresented = true } label: { VStack { - Image(uiImage: (permission.type.icon?.withRenderingMode(.alwaysTemplate) ?? UIImage(systemName: "questionmark"))!) // TODO: Replace with system icon + Image(uiImage: permission.type.icon ?? UIImage(systemSymbol: .questionmark)) .padding() .background(Circle().foregroundColor(Color(.secondarySystemBackground))) Text(permission.type.localizedShortName ?? permission.type.localizedName ?? "") diff --git a/AltStore/Views/Browse/AddSourceView.swift b/AltStore/Views/Browse/AddSourceView.swift index 553a3201..7706510f 100644 --- a/AltStore/Views/Browse/AddSourceView.swift +++ b/AltStore/Views/Browse/AddSourceView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols struct AddSourceView: View { @@ -28,7 +29,7 @@ struct AddSourceView: View { Text("Please enter the source url here. Then, tap continue to validate and add the source in the next step.") HStack(alignment: .top) { - Image(systemName: "exclamationmark.triangle.fill") + Image(systemSymbol: .exclamationmarkTriangleFill) Text("Be careful with unvalidated third-party sources! Make sure to only add sources that you trust.") } diff --git a/AltStore/Views/Browse/BrowseView.swift b/AltStore/Views/Browse/BrowseView.swift index 684823c4..d34d49b2 100644 --- a/AltStore/Views/Browse/BrowseView.swift +++ b/AltStore/Views/Browse/BrowseView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols import AltStoreCore struct BrowseView: View { @@ -76,7 +77,7 @@ struct BrowseView: View { SwiftUI.Button { } label: { - Image(systemName: "line.3.horizontal.decrease.circle") + Image(systemSymbol: .lineHorizontal3DecreaseCircle) .imageScale(.large) } @@ -127,7 +128,7 @@ struct PromotedCategoryView: View { } HStack { - Image(systemName: "dpad.right.filled") + Image(systemSymbol: .dpadRightFill) Text("Games &\nEmulators") .multilineTextAlignment(.leading) } diff --git a/AltStore/Views/Browse/ConfirmAddSourceView.swift b/AltStore/Views/Browse/ConfirmAddSourceView.swift index 8c7be5e3..9ce687c1 100644 --- a/AltStore/Views/Browse/ConfirmAddSourceView.swift +++ b/AltStore/Views/Browse/ConfirmAddSourceView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols import AltStoreCore struct ConfirmAddSourceView: View { @@ -64,7 +65,7 @@ struct ConfirmAddSourceView: View { SwiftUI.Button { confirmationHandler(fetchedSource) } label: { - Label(title: { Text("Add Source") }, icon: { Image(systemName: "plus") }) + Label("Add Source", systemSymbol: .plus) } .buttonStyle(FilledButtonStyle()) .padding() @@ -75,7 +76,7 @@ struct ConfirmAddSourceView: View { SwiftUI.Button { } label: { - Image(systemName: "xmark.circle.fill") + Image(systemSymbol: .xmarkCircleFill) .foregroundColor(.secondary) } diff --git a/AltStore/Views/Browse/SourcesView.swift b/AltStore/Views/Browse/SourcesView.swift index a7f6b320..a224f4e4 100644 --- a/AltStore/Views/Browse/SourcesView.swift +++ b/AltStore/Views/Browse/SourcesView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols import AltStoreCore import CoreData @@ -57,7 +58,7 @@ struct SourcesView: View { SwiftUI.Button { self.removeSource(source) } label: { - Label("Remove", systemImage: "trash") + Label("Remove", systemSymbol: .trash) } })) } @@ -85,7 +86,7 @@ struct SourcesView: View { SwiftUI.Button { self.isShowingAddSourceAlert = true } label: { - Image(systemName: "plus") + Image(systemSymbol: .plus) } .sheet(isPresented: self.$isShowingAddSourceAlert) { NavigationView { diff --git a/AltStore/Views/My Apps/AppAction.swift b/AltStore/Views/My Apps/AppAction.swift index 4985cd99..5ccb6684 100644 --- a/AltStore/Views/My Apps/AppAction.swift +++ b/AltStore/Views/My Apps/AppAction.swift @@ -7,6 +7,7 @@ // import Foundation +import SFSafeSymbols enum AppAction: Int, CaseIterable { case install, open, refresh @@ -34,20 +35,20 @@ enum AppAction: Int, CaseIterable { } } - var imageName: String { + var symbol: SFSymbol { switch self { - case .install: return "Install" - case .open: return "arrow.up.forward.app" - case .refresh: return "arrow.clockwise" - case .activate: return "checkmark.circle" - case .deactivate: return "xmark.circle" - case .remove: return "trash" - case .enableJIT: return "bolt" - case .backup: return "doc.on.doc" - case .exportBackup: return "arrow.up.doc" - case .restoreBackup: return "arrow.down.doc" - case .chooseCustomIcon: return "photo" - case .resetCustomIcon: return "arrow.uturn.left" + case .install: return .squareAndArrowDown + case .open: return .arrowUpForwardApp + case .refresh: return .arrowClockwise + case .activate: return .checkmarkCircle + case .deactivate: return .xmarkCircle + case .remove: return .trash + case .enableJIT: return .bolt + case .backup: return .docOnDoc + case .exportBackup: return .arrowUpDoc + case .restoreBackup: return .arrowDownDoc + case .chooseCustomIcon: return .photo + case .resetCustomIcon: return .arrowUturnLeft } } } diff --git a/AltStore/Views/My Apps/MyAppsView.swift b/AltStore/Views/My Apps/MyAppsView.swift index dca7267b..8c883e6d 100644 --- a/AltStore/Views/My Apps/MyAppsView.swift +++ b/AltStore/Views/My Apps/MyAppsView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols import MobileCoreServices import AltStoreCore @@ -119,7 +120,7 @@ struct MyAppsView: View { SwiftUI.Button { self.isShowingFilePicker = true } label: { - Image(systemName: "plus") + Image(systemSymbol: .plus) .imageScale(.large) } .sheet(isPresented: self.$isShowingFilePicker) { @@ -157,7 +158,7 @@ struct MyAppsView: View { SwiftUI.Button { self.perform(action: action, for: app) } label: { - Label(action.title, systemImage: action.imageName) + Label(action.title, systemSymbol: action.symbol) } } })) diff --git a/AltStore/Views/RootView.swift b/AltStore/Views/RootView.swift index 3dc9192d..da5eb8e8 100644 --- a/AltStore/Views/RootView.swift +++ b/AltStore/Views/RootView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import SFSafeSymbols struct RootView: View { @@ -78,12 +79,12 @@ extension RootView { static var defaultTab: RootView.Tab = .news - var displaySymbol: String { + var displaySymbol: SFSymbol { switch self { - case .news: return "newspaper" - case .browse: return "app.dashed" - case .myApps: return "app.badge" - case .settings: return "gearshape" + case .news: return .newspaper + case .browse: return .booksVertical + case .myApps: return .appBadge + case .settings: return .gearshape } } @@ -97,7 +98,7 @@ extension RootView { } var label: some View { - Label(self.displayName, systemImage: self.displaySymbol) + Label(self.displayName, systemSymbol: self.displaySymbol) } } } diff --git a/AltStore/Views/Settings/SettingsView.swift b/AltStore/Views/Settings/SettingsView.swift index 178d9675..b201f904 100644 --- a/AltStore/Views/Settings/SettingsView.swift +++ b/AltStore/Views/Settings/SettingsView.swift @@ -8,6 +8,7 @@ import SwiftUI import AsyncImage +import SFSafeSymbols import AltStoreCore import Intents @@ -149,7 +150,7 @@ struct SettingsView: View { SwiftUI.Button { } label: { - Image(systemName: "person.crop.circle") + Image(systemSymbol: .personCropCircle) .imageScale(.large) } diff --git a/AltStoreCore/Model/AppPermission.swift b/AltStoreCore/Model/AppPermission.swift index 2763f95c..8169c804 100644 --- a/AltStoreCore/Model/AppPermission.swift +++ b/AltStoreCore/Model/AppPermission.swift @@ -7,6 +7,7 @@ // import CoreData +import SFSafeSymbols import UIKit public extension ALTAppPermissionType @@ -46,28 +47,51 @@ public extension ALTAppPermissionType } var icon: UIImage? { - switch self - { - case .photos: return UIImage(systemName: "photo.on.rectangle.angled") - case .camera: return UIImage(systemName: "camera.fill") - case .location: return UIImage(systemName: "location.fill") - case .contacts: return UIImage(systemName: "person.2.fill") - case .reminders: return UIImage(systemName: "checklist") - case .appleMusic: return UIImage(systemName: "music.note") - case .microphone: return UIImage(systemName: "mic.fill") - case .speechRecognition: return UIImage(systemName: "waveform.and.mic") - case .backgroundAudio: return UIImage(systemName: "speaker.fill") - case .backgroundFetch: return UIImage(systemName: "square.and.arrow.down") - case .bluetooth: return UIImage(systemName: "wave.3.right") - case .network: return UIImage(systemName: "network") - case .calendars: return UIImage(systemName: "calendar") - case .touchID: return UIImage(systemName: "touchid") - case .faceID: return UIImage(systemName: "faceid") - case .siri: return UIImage(systemName: "mic.and.signal.meter.fill") - case .motion: return UIImage(systemName: "figure.walk.motion") - default: + let symbol: SFSymbol? = { + switch self { + case .photos: return .photoOnRectangleAngled + case .camera: return .cameraFill + case .location: return .locationFill + case .contacts: return .person2Fill + case .reminders: + if #available(iOS 15.0, *) { + return .checklist + } + return .listBullet + case .appleMusic: return .musicNote + case .microphone: return .micFill + case .speechRecognition: + if #available(iOS 15.0, *) { + return .waveformAndMic + } + return .recordingtape + case .backgroundAudio: return .speakerFill + case .backgroundFetch: return .squareAndArrowDown + case .bluetooth: return .wave3Right + case .network: return .network + case .calendars: return .calendar + case .touchID: return .touchid + case .faceID: return .faceid + case .siri: + if #available(iOS 16.0, *) { + return .micAndSignalMeterFill + } + return .waveform + case .motion: + if #available(iOS 16.0, *) { + return .figureWalkMotion + } + return .figureWalk + default: + return nil + } + }() + + guard let symbol = symbol else { return nil } + + return UIImage(systemSymbol: symbol) } }