Sharing fonts between Flutter and Native

Tony Owen
2 min readNov 26, 2018

Flutter is great, but every so often you need to dip back into native code and display things that just aren’t possible inside Flutter. For example Google Maps (here’s hoping that gets resolved at some point).

Lets say you’ve written your app and you’ve used a custom font. Now you’re in Android / iOS in a native Activity / ViewController and you want to continue using the font.

Option One:

Add the font file in the standard platform ways, add the font file, link it up, use it. But then we’re shipping the same font twice for each platform. This can add up quickly, and it’s overhead we don’t need.

Option Two (TL;DR use this one)

We can re-use the Flutter font, with a little config on both platforms.

First, check out the documentation for sharing assets. It’ll give you some background on whats going on.

Lets checkout the Android code first, as its more sane than the iOS code (you’ve been warned):

val assetManager = assets
val fontKey = flutterView.getLookupKeyForAsset("fonts/your_font.ttf")
val myTypeface = Typeface.createFromAsset(assetManager, fontKey)

This is called inside the MainActivity that is created by Flutter.

First, we grab the AssetManager, then we use the flutterView defined in a FlutterActivity to lookup the location of your font. Mine is stored in a folder called "fonts"

Now we can set the typeface to any TextView etc we want to. Pretty straightforward.

Now lets checkout the iOS code:

let controller : FlutterViewController = window?.rootViewController as! FlutterViewController;
let bundle = Bundle.main
let fontKey = controller.lookupKey(forAsset: "fonts/your_font.ttf")
let path = bundle.path(forResource: fontKey, ofType: nil)
let fontData = NSData(contentsOfFile: path ?? "")
let dataProvider = CGDataProvider(data: fontData!)
let fontRef = CGFont(dataProvider!)
var errorRef: Unmanaged<CFError>? = nil
if let fr = fontRef {
CTFontManagerRegisterGraphicsFont(fr, &errorRef)
}

This is placed inside the AppDelegate class that is created by Flutter.

We get the bundle, and use lookupKey to find its locate the font. Various conversions to data, references (I honestly don't understand all of this). In the end we call CTFontManagerRegisterGraphicsFont to add the font for future use.

Once this is complete, the font can be used anywhere by calling:

UIFont(name: "your-font", size: 18.0)

Now your Flutter app, and your native sections can look the same without having to duplicate the font files.

--

--