Load fonts from a Swift Package
Mojtaba Hosseini's answer is correct but in order to use the fonts of your package you need to register them also. You could do it with a little supporting function in a struct... I use this in my projects:
public struct Appearance {
/// Configures all the UI of the package
public static func configurePackageUI() {
loadPackageFonts()
}
static func loadPackageFonts() {
// All the filenames of your custom fonts here
let fontNames = ["Latinotype - Texta-Black.otf",
"Latinotype - Texta-BlackIt.otf",
"Latinotype - Texta-Bold.otf",
"Latinotype - Texta-BoldIt.otf",
"Latinotype - Texta-Book.otf",
"Latinotype - Texta-BookIt.otf",
"Latinotype - Texta-Heavy.otf",
"Latinotype - Texta-HeavyIt.otf",
"Latinotype - Texta-It.otf",
"Latinotype - Texta-Light.otf",
"Latinotype - Texta-LightIt.otf",
"Latinotype - Texta-Medium.otf",
"Latinotype - Texta-MediumIt.otf",
"Latinotype - Texta-Regular.otf",
"Latinotype - Texta-Thin.otf",
"Latinotype - Texta-ThintIt.otf",
]
fontNames.forEach{registerFont(fileName: $0)}
}
static func registerFont(fileName: String) {
guard let pathForResourceString = Bundle.module.path(forResource: fileName, ofType: nil),
let fontData = NSData(contentsOfFile: pathForResourceString),
let dataProvider = CGDataProvider(data: fontData),
let fontRef = CGFont(dataProvider) else {
print("*** ERROR: ***")
return
}
var errorRef: Unmanaged<CFError>? = nil
if !CTFontManagerRegisterGraphicsFont(fontRef, &errorRef) {
print("*** ERROR: \(errorRef.debugDescription) ***")
}
}
}
Just remember to add the font filename in the array.
✅ It is supported now
From Swift 5.3, you can add any resources
to the target, including images, assets, fonts, zip, etc. Using the directory name will include all subfiles of the directory:
.target(
name: "ABUIKit",
dependencies: [],
resources: [.process("Resources") // <- this will add Resource directory to the target
]
),
Note that you should put Resources
folder under sources/packageName
to make it recognizable.
⚠️ Also, Don't forget to register them!
You need to register fonts to make it work. So you can use frameworks like FontBlaster.
So you call this somewhere early in the module's code (like some init method):
FontBlaster.blast(bundle: .module)
Then you can use the font inside or even outside of the module!
🛑 There is no need to manually name the font!
It will register all included fonts automatically. You can double-check the loaded fonts right after calling the blast method:
FontBlaster.loadedFonts.forEach { print("🔠", $0) }