How to list every SF Symbol in code (without hardcoding names)
A question that comes up constantly: “How do I get a list of all SF Symbols in code?” — to build a symbol picker, a debug grid, a design-system gallery, whatever.
The uncomfortable answer with Apple’s APIs: you can’t. There is no SFSymbol.allCases, no UIImage.allSystemSymbols, no public enumeration. SF Symbols are referenced by string, and you cannot iterate a set of strings that was never written down anywhere in your code. This is the same root problem as a misspelled symbol — just viewed from the other side.
Why there’s no built-in list
Image(systemName:) and UIImage(systemName:) take a String. The system resolves that string against a private catalog at runtime. Your code never holds the catalog — it holds individual string literals you typed. So “give me all symbols” has no answer at the language level, because the symbols aren’t data in your program. They’re an opaque lookup keyed by strings.
People work around this in bad ways:
// The "I'll just hardcode the ones I need" array let symbols = ["house", "gear", "bell", "star", "trash"] // ...now maintained by hand, forever, and 0.07% of the catalog
That array is the maintenance liability in its purest form: a hand-typed subset of a 7,000-symbol catalog, guaranteed to be incomplete and to drift.
The fix: a generated CaseIterable enum
SFSymbolsKit ships an SFSymbol enum that is CaseIterable — because the symbol catalog is data in the package (generated from SFSymbols.txt), it can be enumerated:
import SwiftUI import SFSymbolsKit struct SymbolGallery: View { let columns = [GridItem(.adaptive(minimum: 64))] var body: some View { ScrollView { LazyVGrid(columns: columns) { ForEach(SFSymbol.allCases, id: \.self) { symbol in Image(systemName: symbol.rawValue) .font(.title) } } } } }
Every symbol Apple ships, enumerable, in a few lines. Build a searchable picker:
struct SymbolPicker: View { @State private var query = "" @Binding var selection: SFSymbol var filtered: [SFSymbol] { query.isEmpty ? SFSymbol.allCases : SFSymbol.allCases.filter { $0.rawValue.contains(query) } } var body: some View { List(filtered, id: \.self, selection: $selection) { symbol in Label(symbol.rawValue, systemImage: symbol.rawValue) } .searchable(text: $query) } }
No hand-maintained array. No “I only added the 40 we use.” The picker covers the entire catalog and stays current when the package regenerates against a new SF Symbols release.
The deeper point
“There’s no way to list SF Symbols” and “my symbol name was misspelled” are the same bug. Both exist because the catalog lives outside your program as opaque strings. Make the catalog typed data in your program and both problems disappear at once: you can enumerate it, and you can’t misspell it.
FAQ
Can I get all symbols as plain strings? Yes — SFSymbol.allCases.map(\.rawValue) gives you every name as a String array, fully populated, no manual list.
Is iterating 7,000 symbols slow? allCases is an array of enum cases; rendering is lazy via LazyVGrid/List. Filtering 7,000 short strings is trivial on-device.
Will the list include symbols added in the latest iOS? It includes whatever the package’s generated catalog contains — bump the dependency after a new SF Symbols release and the new symbols are in allCases automatically. See keeping up with new SF Symbols.
This is the enumeration angle on the same thesis the rest of the blog covers: strings can’t be iterated, validated, or refactored. The SwiftUI and tutorial pieces cover the day-to-day usage.