lcandy2/symbolkit
Lightweight helpers for working with SF Symbols and custom asset icons across SwiftUI and UIKit.
Features
- Unified
Symbolenum for system and custom asset names - SwiftUI
ImageandLabelconvenience initializers - UIKit
UIImageconvenience initializer - Platform support: iOS 15+, macOS 12+, tvOS 15+, watchOS 8+, visionOS 1+
Use case: Before & After
Before: Mixing SF Symbols and custom assets requires branching code per framework.
// SwiftUI
Image(systemName: "heart")
Image("BrandLogo")
// UIKit
UIImage(systemName: "heart")
UIImage(named: "BrandLogo")After: Use Symbol once and keep the same API across SwiftUI and UIKit.
let favorite = Symbol.systemSymbol("heart")
let brand = Symbol.custom("BrandLogo")
// SwiftUI
Image(symbol: favorite)
Label("Favorites", symbol: favorite)
Image(symbol: brand)
// UIKit
let icon = UIImage(symbol: favorite)
let logo = UIImage(symbol: brand)Requirements
- Swift 6
- Platforms listed above (conditional imports protect unavailable frameworks)
Installation (Swift Package Manager)
Add the package to your Package.swift dependencies:
dependencies: [
.package(url: "https://github.com/lcandy2/SymbolKit.git", from: "1.0.0")
]Then add SymbolKit to your target dependencies:
.target(
name: "YourApp",
dependencies: ["SymbolKit"]
)Usage
Creating symbols
let system = Symbol.systemSymbol("square.and.arrow.up")
let custom = Symbol.custom("BrandLogo")SwiftUI
import SwiftUI
import SymbolKit
struct ContentView: View {
var body: some View {
VStack(spacing: 16) {
Image(symbol: .systemSymbol("heart"))
Label("Favorites", symbol: .systemSymbol("heart.fill"))
Button("Edit", symbol: .systemSymbol("pencil")) { /* action */ }
Image(symbol: .custom("BrandLogo")) // requires the asset in your bundle
}
}
}UIKit
import UIKit
import SymbolKit
let imageView = UIImageView(image: UIImage(symbol: .systemSymbol("person.crop.circle")))
imageView.tintColor = .labelAccessing the raw name
Symbol.systemSymbol("heart").toSystemName // "heart"
Symbol.custom("BrandLogo").toSystemName // "BrandLogo"Testing
Run the package tests:
swift testSwiftUI tests are conditionally compiled; UIKit coverage runs when UIKit is available (e.g., iOS/tvOS simulators). If you add a custom image test, include a fixture asset in the test bundle.
Release workflow
The repository includes a manual GitHub Actions workflow (release.yml) that:
- Lets you pick the version bump (
major,minor, orpatch) - Installs Swift 6.2 via
swift-actions/setup-swift@v2 - Runs
swift testand a release build - Creates and pushes a tag, then publishes a GitHub Release with generated notes
Trigger it from GitHub → Actions → Release → Run workflow.
Use case: Before & After
Before: Mixing SF Symbols and custom assets requires branching code per framework.
// SwiftUI
Image(systemName: "heart")
Image("BrandLogo")
// UIKit
UIImage(systemName: "heart")
UIImage(named: "BrandLogo")After: Use Symbol once and keep the same API across SwiftUI and UIKit.
let favorite = Symbol.systemSymbol("heart")
let brand = Symbol.custom("BrandLogo")
// SwiftUI
Image(symbol: favorite)
Label("Favorites", symbol: favorite)
Image(symbol: brand)
// UIKit
let icon = UIImage(symbol: favorite)
let logo = UIImage(symbol: brand)Package Metadata
Repository: lcandy2/symbolkit
Default branch: main
README: README.md