Xcode: Using custom fonts inside Dynamic framework Xcode: Using custom fonts inside Dynamic framework swift swift

Xcode: Using custom fonts inside Dynamic framework


I'm here a bit late, but I took PetahChristian's solution and created a Swift version in the form of an extension. This is working for me. I've found that when you try to get a font using a font name and a size using the regular way that it always looks in the main bundle for the font file, and there's no method that takes a bundle identifier as a parameter. It would be nice if Apple would make one.

Swift:

public extension UIFont {    public static func jbs_registerFont(withFilenameString filenameString: String, bundle: Bundle) {        guard let pathForResourceString = bundle.path(forResource: filenameString, ofType: nil) else {            print("UIFont+:  Failed to register font - path for resource not found.")            return        }        guard let fontData = NSData(contentsOfFile: pathForResourceString) else {            print("UIFont+:  Failed to register font - font data could not be loaded.")            return        }        guard let dataProvider = CGDataProvider(data: fontData) else {            print("UIFont+:  Failed to register font - data provider could not be loaded.")            return        }        guard let font = CGFont(dataProvider) else {            print("UIFont+:  Failed to register font - font could not be loaded.")            return        }        var errorRef: Unmanaged<CFError>? = nil        if (CTFontManagerRegisterGraphicsFont(font, &errorRef) == false) {            print("UIFont+:  Failed to register font - register graphics font failed - this font may have already been registered in the main bundle.")        }    }}

Usage Example:

UIFont.jbs_registerFont(    withFilenameString: "Boogaloo-Regular.ttf",    bundle: Bundle(identifier: "com.JBS.JBSFramework")!)


Here's my version of John's answer, showing how to call the function if you have lots of fonts

import Foundationextension UIFont {    @nonobjc static var loadAllFontsDO: dispatch_once_t = 0    class func initialsAvatarFont() -> UIFont {        loadAllFonts()        if let retval = UIFont(name: "MyFontName", size: kInitialsAvatarFontSize) {            return retval;        } else {            return UIFont.systemFontOfSize(kInitialsAvatarFontSize)        }    }    class func loadAllFonts() {        dispatch_once(&loadAllFontsDO) { () -> Void in            registerFontWithFilenameString("thefontfilename.ttf", bundleIdentifierString: "nameOfResourceBundleAlongsideTheFrameworkBundle")            // Add more font files here as required        }    }    static func registerFontWithFilenameString(filenameString: String, bundleIdentifierString: String) {        let frameworkBundle = NSBundle(forClass: AnyClassInYourFramework.self)        let resourceBundleURL = frameworkBundle.URLForResource(bundleIdentifierString, withExtension: "bundle")        if let bundle = NSBundle(URL: resourceBundleURL!) {            let pathForResourceString = bundle.pathForResource(filenameString, ofType: nil)            let fontData = NSData(contentsOfFile: pathForResourceString!)            let dataProvider = CGDataProviderCreateWithCFData(fontData)            let fontRef = CGFontCreateWithDataProvider(dataProvider)            var errorRef: Unmanaged<CFError>? = nil            if (CTFontManagerRegisterGraphicsFont(fontRef!, &errorRef) == false) {                NSLog("Failed to register font - register graphics font failed - this font may have already been registered in the main bundle.")            }        }        else {            NSLog("Failed to register font - bundle identifier invalid.")        }    }}


Swift 4:

This is maybe an old thread but has updated @xaphod for swift 4 as all static and global variables are lazily initialised using dispatch_once.

extension UIFont {// load framework font in applicationpublic static let loadAllFonts: () = {    registerFontWith(filenameString: "SanFranciscoText-Regular.otf", bundleIdentifierString: "Fonts")    registerFontWith(filenameString: "SanFranciscoText-Medium.otf", bundleIdentifierString: "Fonts")    registerFontWith(filenameString: "SanFranciscoText-Semibold.otf", bundleIdentifierString: "Fonts")    registerFontWith(filenameString: "SanFranciscoText-Bold.otf", bundleIdentifierString: "Fonts")    registerFontWith(filenameString: "SanFranciscoText-LightItalic.otf", bundleIdentifierString: "Fonts")}()//MARK: - Make custom font bundle register to frameworkstatic func registerFontWith(filenameString: String, bundleIdentifierString: String) {    let frameworkBundle = Bundle(for: MSAlertController.self)    let resourceBundleURL = frameworkBundle.url(forResource: bundleIdentifierString, withExtension: "bundle")    if let url = resourceBundleURL, let bundle = Bundle(url: url) {        let pathForResourceString = bundle.path(forResource: filenameString, ofType: nil)        if let fontData = NSData(contentsOfFile: pathForResourceString!), let dataProvider = CGDataProvider.init(data: fontData) {            let fontRef = CGFont.init(dataProvider)            var errorRef: Unmanaged<CFError>? = nil            if (CTFontManagerRegisterGraphicsFont(fontRef!, &errorRef) == false) {                print("Failed to register font - register graphics font failed - this font may have already been registered in the main bundle.")            }        }    }    else {        print("Failed to register font - bundle identifier invalid.")    }}}

Then you can call UIFont.loadAllfont inside the appDelegate