I wonder if there is a way to load fonts from a Swift Package at the moment? The font files are there in the package but the compiled program can't locate them.
I wonder if there is a way to load fonts from a Swift Package at the moment? The font files are there in the package but the compiled program can't locate them.
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 gFontRef = getFont(named: fileName) else {
print("*** ERROR: ***")
return
}
var errorRef: Unmanaged<CFError>? = nil
if !CTFontManagerRegisterGraphicsFont(gFontRef, &errorRef) {
print("*** ERROR: \(errorRef.debugDescription) ***")
}
}
static func getFont(named fileName: String) -> CGFont? {
let url = Bundle.module.url(forResource: fileName, withExtension: nil)
guard let gUrl = url,
let gFontData = NSData(contentsOf: gUrl),
let gDataProvider = CGDataProvider(data: gFontData),
let gFontRef = CGFont(gDataProvider) else {
print("*** ERROR: ***")
return nil
}
return gFontRef
}
}
Just remember to add the font filename in the array.
EDIT: I've updated my answer.
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 the Resources folder under sources/packageName to make it recognizable.
You need to register fonts to make it work. So you can use frameworks like FontBlaster.
NOTE: You can always write your own code, but I prefer to use an existing framework and contribute my extra needs to them
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!
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) }