Skip to content

Commit 13d98b7

Browse files
Update Project Settings - Generate Asset Symbols (#2009)
Updates the project settings to include generated asset symbols for cleaner asset use project-wide. This allows us to use type-safe, auto-generated symbols for referencing assets rather than string based APIs. This also allows for some cleaning around the use of these symbols, removing nil-coalescing operators and other optional unwrapping boilerplate that was previously required for safe use. For more info on generated asset symbols, see [Xcode 15 release notes here](https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#New-Features). ### Related Issues * N/A ### Checklist <!--- Add things that are not yet implemented above --> - [x] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md) - [x] The issues this PR addresses are related to each other - [x] My changes generate no new warnings - [x] My code builds and runs on my machine - [x] My changes are all related to the related issue above - [x] I documented my code ### Screenshots N/A
1 parent 9cabecd commit 13d98b7

13 files changed

+81
-82
lines changed

Diff for: CodeEdit.xcodeproj/project.pbxproj

+6-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@
380380
attributes = {
381381
BuildIndependentTargetsInParallel = 1;
382382
LastSwiftUpdateCheck = 1330;
383-
LastUpgradeCheck = 1540;
383+
LastUpgradeCheck = 1620;
384384
TargetAttributes = {
385385
2BE487EB28245162003F3F64 = {
386386
CreatedOnToolsVersion = 13.3.1;
@@ -577,6 +577,7 @@
577577
baseConfigurationReferenceRelativePath = Alpha.xcconfig;
578578
buildSettings = {
579579
ALWAYS_SEARCH_USER_PATHS = NO;
580+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
580581
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
581582
CLANG_ANALYZER_NONNULL = YES;
582583
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -771,6 +772,7 @@
771772
baseConfigurationReferenceRelativePath = Beta.xcconfig;
772773
buildSettings = {
773774
ALWAYS_SEARCH_USER_PATHS = NO;
775+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
774776
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
775777
CLANG_ANALYZER_NONNULL = YES;
776778
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -1033,6 +1035,7 @@
10331035
baseConfigurationReferenceRelativePath = Alpha.xcconfig;
10341036
buildSettings = {
10351037
ALWAYS_SEARCH_USER_PATHS = NO;
1038+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
10361039
CE_APPICON_NAME = AppIconPre;
10371040
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
10381041
CLANG_ANALYZER_NONNULL = YES;
@@ -1229,6 +1232,7 @@
12291232
baseConfigurationReferenceRelativePath = Debug.xcconfig;
12301233
buildSettings = {
12311234
ALWAYS_SEARCH_USER_PATHS = NO;
1235+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
12321236
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
12331237
CLANG_ANALYZER_NONNULL = YES;
12341238
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
@@ -1300,6 +1304,7 @@
13001304
baseConfigurationReferenceRelativePath = Release.xcconfig;
13011305
buildSettings = {
13021306
ALWAYS_SEARCH_USER_PATHS = NO;
1307+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
13031308
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
13041309
CLANG_ANALYZER_NONNULL = YES;
13051310
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;

Diff for: CodeEdit/Features/CEWorkspace/Models/CEWorkspaceFileIcon.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,13 @@ enum FileIcon {
180180
case .css:
181181
return .teal
182182
case .js, .mjs, .py, .entitlements, .LICENSE:
183-
return Color("Amber")
183+
return Color.amber
184184
case .json, .resolved, .rb, .strings, .yml:
185-
return Color("Scarlet")
185+
return Color.scarlet
186186
case .jsx, .tsx:
187187
return .cyan
188188
case .plist, .xcconfig, .sh:
189-
return Color("Steel")
189+
return Color.steel
190190
case .c, .cetheme:
191191
return .purple
192192
case .vue:
@@ -204,7 +204,7 @@ enum FileIcon {
204204
case .rs:
205205
return .orange
206206
default:
207-
return Color("Steel")
207+
return Color.steel
208208
}
209209
}
210210
}

Diff for: CodeEdit/Features/Editor/JumpBar/Views/EditorJumpBarMenu.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ final class JumpBarMenuItem: NSMenuItem {
7676
if fileItem.isFolder {
7777
let subMenu = NSMenu()
7878
submenu = subMenu
79-
color = NSColor(named: "FolderBlue") ?? NSColor(.secondary)
79+
color = NSColor.folderBlue
8080
}
8181
if generalSettings.fileIconStyle == .monochrome {
82-
color = NSColor(named: "CoolGray") ?? NSColor(.gray)
82+
color = NSColor.coolGray
8383
}
8484
let image = fileItem.nsIcon.withSymbolConfiguration(.init(paletteColors: [color]))
8585
self.image = image

Diff for: CodeEdit/Features/NavigatorArea/OutlineView/FileSystemTableViewCell.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ class FileSystemTableViewCell: StandardTableViewCell {
138138
if !item.isFolder {
139139
return NSColor(item.iconColor)
140140
} else {
141-
return NSColor(named: "FolderBlue") ?? NSColor(.cyan)
141+
return NSColor.folderBlue
142142
}
143143
} else {
144-
return NSColor(named: "CoolGray") ?? NSColor(.gray)
144+
return NSColor.coolGray
145145
}
146146
}
147147

Diff for: CodeEdit/Features/NavigatorArea/ProjectNavigator/ProjectNavigatorToolbarBottom.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ struct FilterDropDownIconButton<MenuView: View>: View {
168168
Menu { menu() } label: {}
169169
.background {
170170
if isOn == true {
171-
Image("line.3.horizontal.decrease.chevron.filled")
171+
Image(ImageResource.line3HorizontalDecreaseChevronFilled)
172172
.foregroundStyle(.tint)
173173
} else {
174-
Image("line.3.horizontal.decrease.chevron")
174+
Image(ImageResource.line3HorizontalDecreaseChevron)
175175
}
176176
}
177177
.menuStyle(.borderlessButton)

Diff for: CodeEdit/Features/NavigatorArea/SourceControlNavigator/Repository/Models/RepoOutlineGroupItem.swift

+7-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@
88
import SwiftUI
99

1010
struct RepoOutlineGroupItem: Hashable, Identifiable {
11+
enum ImageType: Hashable {
12+
case system(name: String)
13+
case symbol(name: String)
14+
}
15+
1116
var id: String
1217
var label: String
1318
var description: String?
14-
var systemImage: String?
15-
var symbolImage: String?
16-
var imageColor: Color?
19+
var image: ImageType
20+
var imageColor: Color
1721
var children: [RepoOutlineGroupItem]?
1822
var branch: GitBranch?
1923
var stashEntry: GitStashEntry?

Diff for: CodeEdit/Features/NavigatorArea/SourceControlNavigator/Repository/Views/SourceControlNavigatorRepositoryItem.swift

+39-43
Original file line numberDiff line numberDiff line change
@@ -17,53 +17,49 @@ struct SourceControlNavigatorRepositoryItem: View {
1717
var controlActiveState
1818

1919
var body: some View {
20-
if item.systemImage != nil || item.symbolImage != nil {
21-
Label(title: {
22-
Text(item.label)
20+
Label(title: {
21+
Text(item.label)
22+
.lineLimit(1)
23+
.truncationMode(.middle)
24+
if let description = item.description {
25+
Text(description)
2326
.lineLimit(1)
24-
.truncationMode(.middle)
25-
if let description = item.description {
26-
Text(description)
27-
.lineLimit(1)
28-
.foregroundStyle(.secondary)
29-
.font(.system(size: 11))
30-
.layoutPriority(-1)
31-
}
32-
Spacer()
33-
HStack(spacing: 5) {
34-
if let behind = item.branch?.behind, behind > 0 {
35-
HStack(spacing: 0) {
36-
Image(systemName: "arrow.down")
37-
.imageScale(.small)
38-
Text("\(behind)")
39-
.font(.system(size: 11))
40-
}
27+
.foregroundStyle(.secondary)
28+
.font(.system(size: 11))
29+
.layoutPriority(-1)
30+
}
31+
Spacer()
32+
HStack(spacing: 5) {
33+
if let behind = item.branch?.behind, behind > 0 {
34+
HStack(spacing: 0) {
35+
Image(systemName: "arrow.down")
36+
.imageScale(.small)
37+
Text("\(behind)")
38+
.font(.system(size: 11))
4139
}
42-
if let ahead = item.branch?.ahead, ahead > 0 {
43-
HStack(spacing: 0) {
44-
Image(systemName: "arrow.up")
45-
.imageScale(.small)
46-
Text("\(ahead)")
47-
.font(.system(size: 11))
48-
}
40+
}
41+
if let ahead = item.branch?.ahead, ahead > 0 {
42+
HStack(spacing: 0) {
43+
Image(systemName: "arrow.up")
44+
.imageScale(.small)
45+
Text("\(ahead)")
46+
.font(.system(size: 11))
4947
}
5048
}
51-
}, icon: {
52-
if item.symbolImage != nil {
53-
Image(symbol: item.symbolImage ?? "")
54-
.opacity(controlActiveState == .inactive ? 0.5 : 1)
55-
.foregroundStyle(fileIconStyle == .color ? item.imageColor ?? .accentColor : Color("CoolGray"))
56-
} else {
57-
Image(systemName: item.systemImage ?? "")
58-
.opacity(controlActiveState == .inactive ? 0.5 : 1)
59-
.foregroundStyle(fileIconStyle == .color ? item.imageColor ?? .accentColor : Color("CoolGray"))
49+
}
50+
}, icon: {
51+
Group {
52+
switch item.image {
53+
case .system(let name):
54+
Image(systemName: name)
55+
case .symbol(let name):
56+
Image(symbol: name)
6057
}
61-
})
62-
.padding(.leading, 1)
63-
.padding(.vertical, -1)
64-
} else {
65-
Text(item.label)
66-
.padding(.leading, 2)
67-
}
58+
}
59+
.opacity(controlActiveState == .inactive ? 0.5 : 1)
60+
.foregroundStyle(fileIconStyle == .color ? item.imageColor : Color.coolGray)
61+
})
62+
.padding(.leading, 1)
63+
.padding(.vertical, -1)
6864
}
6965
}

Diff for: CodeEdit/Features/NavigatorArea/SourceControlNavigator/Repository/Views/SourceControlNavigatorRepositoryView+outlineGroupData.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ extension SourceControlNavigatorRepositoryView {
1313
.init(
1414
id: "BranchesGroup",
1515
label: "Branches",
16-
systemImage: "externaldrive.fill",
16+
image: .system(name: "externaldrive.fill"),
1717
imageColor: Color(nsColor: .secondaryLabelColor),
1818
children: sourceControlManager.orderedLocalBranches.map { branch in
1919
.init(
2020
id: "Branch\(branch.name)",
2121
label: branch.name,
2222
description: branch == sourceControlManager.currentBranch ? "(current)" : nil,
23-
symbolImage: "branch",
23+
image: .symbol(name: "branch"),
2424
imageColor: .blue,
2525
branch: branch
2626
)
@@ -29,7 +29,7 @@ extension SourceControlNavigatorRepositoryView {
2929
.init(
3030
id: "StashedChangesGroup",
3131
label: "Stashed Changes",
32-
systemImage: "tray.2.fill",
32+
image: .system(name: "tray.2.fill"),
3333
imageColor: Color(nsColor: .secondaryLabelColor),
3434
children: sourceControlManager.stashEntries.map { stashEntry in
3535
.init(
@@ -43,7 +43,7 @@ extension SourceControlNavigatorRepositoryView {
4343
.hour(.defaultDigits(amPM: .abbreviated))
4444
.minute(.twoDigits)
4545
),
46-
systemImage: "tray",
46+
image: .system(name: "tray"),
4747
imageColor: .orange,
4848
stashEntry: stashEntry
4949
)
@@ -52,19 +52,19 @@ extension SourceControlNavigatorRepositoryView {
5252
.init(
5353
id: "RemotesGroup",
5454
label: "Remotes",
55-
systemImage: "network",
55+
image: .system(name: "network"),
5656
imageColor: Color(nsColor: .secondaryLabelColor),
5757
children: sourceControlManager.remotes.map { remote in
5858
.init(
5959
id: "Remote\(remote.hashValue)",
6060
label: remote.name,
61-
symbolImage: "vault",
61+
image: .symbol(name: "vault"),
6262
imageColor: .teal,
6363
children: remote.branches.map { branch in
6464
.init(
6565
id: "Remote\(remote.name)-Branch\(branch.name)",
6666
label: branch.name,
67-
symbolImage: "branch",
67+
image: .symbol(name: "branch"),
6868
imageColor: .blue,
6969
branch: branch
7070
)

Diff for: CodeEdit/Features/Settings/Pages/AccountsSettings/AccountSelectionView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct AccountSelectionView: View {
2323
ForEach(gitProviders, id: \.self) { provider in
2424
AccountsSettingsProviderRow(
2525
name: provider.name,
26-
iconName: provider.iconName,
26+
iconResource: provider.iconResource,
2727
action: {
2828
selectedProvider = provider
2929
dismiss()

Diff for: CodeEdit/Features/Settings/Pages/AccountsSettings/AccountsSettingsAccountLink.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct AccountsSettingsAccountLink: View {
2222
.font(.footnote)
2323
.foregroundColor(.secondary)
2424
} icon: {
25-
FeatureIcon(image: Image(account.provider.iconName), size: 26)
25+
FeatureIcon(image: Image(account.provider.iconResource), size: 26)
2626
.padding(.vertical, 2)
2727
.padding(.leading, 2)
2828
}

Diff for: CodeEdit/Features/Settings/Pages/AccountsSettings/AccountsSettingsProviderRow.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ import SwiftUI
99

1010
struct AccountsSettingsProviderRow: View {
1111
var name: String
12-
var iconName: String
12+
var iconResource: ImageResource
1313
var action: () -> Void
1414

1515
@State private var hovering = false
1616
@State private var pressing = false
1717

1818
var body: some View {
1919
HStack {
20-
FeatureIcon(image: Image(iconName), size: 28)
20+
FeatureIcon(image: Image(iconResource), size: 28)
2121
Text(name)
2222
Spacer()
2323
if hovering {

Diff for: CodeEdit/Features/Settings/Pages/AccountsSettings/AccountsSettingsSigninView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct AccountsSettingsSigninView: View {
6464
},
6565
header: {
6666
VStack(alignment: .center, spacing: 10) {
67-
FeatureIcon(image: Image(provider.iconName), size: 52)
67+
FeatureIcon(image: Image(provider.iconResource), size: 52)
6868
.padding(.top, 5)
6969
Text("Sign in to \(provider.name)")
7070
.multilineTextAlignment(.center)

Diff for: CodeEdit/Features/Settings/Pages/AccountsSettings/Models/SourceControlAccount.swift

+7-13
Original file line numberDiff line numberDiff line change
@@ -101,20 +101,14 @@ struct SourceControlAccount: Codable, Identifiable, Hashable {
101101
}
102102
}
103103

104-
var iconName: String {
104+
var iconResource: ImageResource {
105105
switch self {
106-
case .bitbucketCloud:
107-
return "BitBucketIcon"
108-
case .bitbucketServer:
109-
return "BitBucketIcon"
110-
case .github:
111-
return "GitHubIcon"
112-
case .githubEnterprise:
113-
return "GitHubIcon"
114-
case .gitlab:
115-
return "GitLabIcon"
116-
case .gitlabSelfHosted:
117-
return "GitLabIcon"
106+
case .bitbucketCloud, .bitbucketServer:
107+
return .bitBucketIcon
108+
case .github, .githubEnterprise:
109+
return .gitHubIcon
110+
case .gitlab, .gitlabSelfHosted:
111+
return .gitLabIcon
118112
}
119113
}
120114

0 commit comments

Comments
 (0)