Skip to content

Commit

Permalink
[iOS] Move nala symbols & color assets into core build
Browse files Browse the repository at this point in the history
This shifts the actual symbol & color asset catalog generation and compilation into the brave-core ninja build system and bundles them in a dynamic framework which will allow asset sharing between targets saving some disk space.

This change will improve incremental build times of anything that would have imported the `DesignSystem` target by 30s+ per build as SPM plugins were executing incorrectly every build (with no way to seemingly fix it for asset catalogs) thus causing asset catalog recompilations each time.
  • Loading branch information
kylehickinson committed Nov 6, 2024
1 parent cd75575 commit 2e3482d
Show file tree
Hide file tree
Showing 226 changed files with 440 additions and 2,612 deletions.
6 changes: 6 additions & 0 deletions ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ group("brave_ios") {
":brave_core_xcframework",
":generated_xcconfig",
":material_components_xcframework",
":nala_assets_xcframework",
]
}

Expand Down Expand Up @@ -197,6 +198,11 @@ ios_create_xcframework("material_components_xcframework") {
deps = [ "//ios/third_party/material_components_ios" ]
}

ios_create_xcframework("nala_assets_xcframework") {
framework_dir = "$root_build_dir/NalaAssets.framework"
deps = [ "//brave/ios/nala:nala_assets_framework" ]
}

# Generates an xcconfig based on GN args that are needed in the Xcode app build
# process such as Info.plist or build setting subsititions.
generated_file("generated_xcconfig") {
Expand Down
9 changes: 7 additions & 2 deletions ios/brave-ios/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var package = Package(
.library(name: "BraveShared", targets: ["BraveShared"]),
.library(name: "BraveShields", targets: ["BraveShields"]),
.library(name: "BraveUI", targets: ["BraveUI"]),
.library(name: "DesignSystem", targets: ["DesignSystem"]),
.library(name: "DesignSystem", targets: ["DesignSystem", "NalaAssets"]),
.library(name: "BraveWallet", targets: ["BraveWallet"]),
.library(name: "Data", targets: ["Data"]),
.library(name: "Storage", targets: ["Storage"]),
Expand Down Expand Up @@ -140,7 +140,12 @@ var package = Package(
dependencies: ["Strings", "Preferences", "BraveCore"],
plugins: ["LoggerPlugin"]
),
.target(name: "DesignSystem", dependencies: ["Then"], plugins: ["LeoAssetsPlugin"]),
.target(
name: "DesignSystem",
dependencies: ["Then", "NalaAssets"],
plugins: ["LeoAssetsPlugin"]
),
.binaryTarget(name: "NalaAssets", path: "../../../out/ios_current_link/NalaAssets.xcframework"),
.binaryTarget(name: "BraveCore", path: "../../../out/ios_current_link/BraveCore.xcframework"),
.binaryTarget(
name: "MaterialComponents",
Expand Down
91 changes: 3 additions & 88 deletions ios/brave-ios/Plugins/LeoAssetsPlugin/LeoAssetsPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,9 @@ struct LeoAssetsPlugin: BuildToolPlugin {
let fileManager = FileManager.default
let braveCoreRootDirectory = context.package.directory.removingLastComponent()
.removingLastComponent()
let leoSymbolsDirectory = braveCoreRootDirectory.appending("node_modules/@brave/leo-sf-symbols")
let leoColorsDirectory = braveCoreRootDirectory.appending("node_modules/@brave/leo")

if !fileManager.fileExists(atPath: leoSymbolsDirectory.string)
|| !fileManager.fileExists(atPath: leoColorsDirectory.string)
{
if !fileManager.fileExists(atPath: leoColorsDirectory.string) {
Diagnostics.error(
"Required Leo assets not found: \(FileManager.default.currentDirectoryPath)"
)
Expand All @@ -33,108 +30,26 @@ struct LeoAssetsPlugin: BuildToolPlugin {
return []
}

let assetCatalogs = Array(target.sourceFiles(withSuffix: "xcassets").map(\.path))
if assetCatalogs.isEmpty {
Diagnostics.error("No asset catalogs found in the target")
return []
}

// The command that will create an asset catalog full of leo sf symbols
let copySFSymbolsCommand: Command = try {
let scriptPath = context.package.directory.appending(
"Plugins/LeoAssetsPlugin/make_asset_catalog.sh"
)
let outputDirectory = context.pluginWorkDirectory.appending("LeoAssets.xcassets")

// Running a macOS tool while archiving a iOS build is unfortunately broken in Xcode 14. It attempts to
// run the macOS tool from the wrong directory and fails to find it. One way around this is to use a
// precompiled version of this tool instead, but it will mean building and uploading them somewhere
// so for now the tool will be replaced by a bash script. We can uncomment this and add back the dep on
// `LeoAssetCatalogGenerator` once this is fixed in Xcode.
// return [
// .buildCommand(
// displayName: "Create Asset Catalog",
// executable: try context.tool(named: "LeoAssetCatalogGenerator").path,
// arguments: assetCatalogs + [leoSymbolsDirectory, outputDirectory.string],
// inputFiles: assetCatalogs + [leoSymbolsDirectory.appending("package.json")],
// outputFiles: [outputDirectory]
// ),
// ]
let icons = try assetCatalogs.flatMap {
try symbolSets(in: URL(fileURLWithPath: $0.string))
}.joined(separator: ",")
return .buildCommand(
displayName: "Create Asset Catalog",
executable: Path("/bin/zsh"),
arguments: [
scriptPath.string,
"-l", leoSymbolsDirectory.string,
"-i", icons,
"-o", context.pluginWorkDirectory.string,
],
inputFiles: assetCatalogs + [
leoSymbolsDirectory.appending("package.json"),
scriptPath,
],
outputFiles: [outputDirectory]
)
}()

let copyColorsCommand: Command = {
let tokensPath = leoColorsDirectory.appending("tokens/ios-swift")
let outputDirectory = context.pluginWorkDirectory.appending("LeoColors")
return .buildCommand(
displayName: "Copy Leo Colors",
executable: Path("/bin/zsh"),
arguments: [
"-c", "cp -R \"\(tokensPath.string)/.\" \"\(outputDirectory)\"",
"-c", "find \"\(tokensPath)\" -name \\*.swift -exec cp {} \"\(outputDirectory)\" \\;",
],
inputFiles: [
tokensPath.appending("Colors.xcassets"),
tokensPath.appending("Gradients.swift"),
tokensPath.appending("ColorSetAccessors.swift"),
],
outputFiles: [
outputDirectory.appending("Colors.xcassets"),
outputDirectory.appending("Gradients.swift"),
outputDirectory.appending("ColorSetAccessors.swift"),
]
)
}()

return [
copySFSymbolsCommand,
copyColorsCommand,
]
}
}

extension LeoAssetsPlugin {
fileprivate func symbolSets(in catalog: URL) throws -> [String] {
let fileManager = FileManager.default
var symbols: [String] = []
guard
let enumerator = fileManager.enumerator(
at: catalog,
includingPropertiesForKeys: [.isDirectoryKey, .nameKey],
options: [.skipsHiddenFiles, .skipsSubdirectoryDescendants]
)
else { return [] }
while let fileURL = enumerator.nextObject() as? URL {
guard
let values = try? fileURL.resourceValues(forKeys: [.isDirectoryKey, .nameKey]),
let isDirectory = values.isDirectory,
let name = values.name,
isDirectory,
name.hasPrefix("leo"),
name.hasSuffix(".symbolset"),
!(try fileManager.contentsOfDirectory(atPath: fileURL.path)
.contains(where: { $0.hasSuffix("svg") }))
else {
continue
}
symbols.append(fileURL.deletingPathExtension().lastPathComponent)
}
return symbols
return [copyColorsCommand]
}
}
75 changes: 0 additions & 75 deletions ios/brave-ios/Plugins/LeoAssetsPlugin/make_asset_catalog.sh

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public class BraveNewsAddSourceResultsViewController: UITableViewController {
let cell = tableView.dequeueReusableCell(for: indexPath) as FeedLocationCell
cell.imageView?.image =
indexPath.section == 0
? UIImage(braveSystemNamed: "brave.lock.alt", compatibleWith: nil)?
? UIImage(braveSystemNamed: "leo.lock.plain", compatibleWith: nil)?
.applyingSymbolConfiguration(
.init(font: .preferredFont(for: .body, weight: .semibold), scale: .small)
) : UIImage(named: "insecure-site-icon", in: .module, compatibleWith: nil)!
Expand Down
5 changes: 3 additions & 2 deletions ios/brave-ios/Sources/DesignSystem/Colors/BraveColors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

import Foundation
import NalaAssets
import SwiftUI
import UIKit

extension Color {
/// Initialize a `Color` with a color resource.
public init(braveSystemName resource: FigmaColorResource) {
self.init(resource.name, bundle: resource.bundle)
self.init(resource.name, bundle: .nalaAssets)
}
}

extension UIColor {
/// Initialize a `UIColor` with a color resource.
public convenience init(braveSystemName resource: FigmaColorResource) {
self.init(named: resource.name, in: resource.bundle, compatibleWith: nil)!
self.init(named: resource.name, in: .nalaAssets, compatibleWith: nil)!
}
}
5 changes: 3 additions & 2 deletions ios/brave-ios/Sources/DesignSystem/Icons/BraveSymbols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

import Foundation
import NalaAssets
import SwiftUI
import UIKit

Expand All @@ -14,14 +15,14 @@ extension UIImage {
braveSystemNamed name: String,
compatibleWith traitCollection: UITraitCollection? = nil
) {
self.init(named: name, in: .module, compatibleWith: traitCollection)
self.init(named: name, in: .nalaAssets, compatibleWith: traitCollection)
}
}

extension Image {
/// Creates a labeled image from the Design System bundle that you can use as content for controls.
public init(braveSystemName name: String) {
self.init(name, bundle: .module)
self.init(name, bundle: .nalaAssets)
}
}

Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 2e3482d

Please sign in to comment.