Typography v1.0 has a clear issue... The list is included manually and it might not be up to date.
If only a could check directly with the OS and obtain a list of registered fonts. Oh wait... I can!
iOS exposes all the fonts used by UIKit
:
// In swift it would be something like this.
import UIKit
class FontLookup {
func getFonts() -> [String] {
return UIFont.familyNames
}
}
I got no idea how to get it for Android, but I imagine is going to be pretty easy too, right?
In any case, react-native
should allow me to expose it to my javacript/typescript code... Reading the documentation, I noticed three things right out of the bat:
- Whatever you do, it will need to be exported or registered with the react-native framework (expected)
- Any method receives the same treatment. If your method returns a value, it will have to be returned via a callback or a promise provided as an argument.
- There is a list of supported types:
- For iOS:
- ObjC:
NSString
or Swift's:string
maps tostring
- ObjC:
CGFloat
/NSNumber
or Swift's:float
,double
maps tonumber
- ObjC:
BOOL
maps toboolean
- ObjC:
NSArray
maps toArray
- ObjC:
NSDictioanary
(strings as keys) maps to a hashset. - You can also provide a function which is
RCTResponseSenderBlock
orRCTPromiseResolveBlock
/RCTPromiseRejectBlock
- ObjC:
- For Android:
Bool
maps toboolean
Integer
,Double
,Float
maps tonumber
String
maps tostring
Callback
tofunction
List<T>
,ArrayList<T>
, etc... maps to nothing! You have to export it manually viaArguments.fromList(...)
or similar methods. You will have it viaWritableArray
orWritableMap
if you are sending info to Javascript orReadableArray
,ReadableMap
if you are sending it to Android via Java or Kotlin.
- For iOS:
I've found these inconsistencies quite annoying... but, moving on.
Let's build the application and take a look how to work with it!
The objective is to build an application similar to typography v1.0 but making it completely dynamic.
Now, to create the api I am going to use the promises
approach. This means in objc I need to add a method with two arguments RCTPromiseResolveBlock
and RCTPromiseRejectBlock
. In Java, the method will take in a promise that will be marked as rejected or resolved.
I am going to try to build the interface as close as possible to minimise differences in my javascript code. Hopefully, I won't have to create a wrapper to address differences.
Well... Android reports a set of 29 font families (9 are sans-serif
variations and 2 are serif
, everything else is different) and iOS reported 78 font families (very different to the 294 reported on the list that does not crash the application).
Unfortunately, passing complex objects is not supported at all (discovered this while paying with early implementations of this app). I wish facebook decides to revise this api and make it better... for one, provide a mechanism to serialize objects into json and automatically reads it into an object on the other side. At the moment, this will work only if you manually serialise everything and pass it through as a string
.
# Cloning the repo to 'typography'
git clone git@github.com:rodrigoelp/reactnative-typescript-exercise-11.git typography-2.0
# Changing directory
cd typography-2.0
# Installing dependencies
yarn # if you have not installed yarn, then change it to: npm install
# Compiling the typescript code
./node_modules/.bin/tsc
# Launching the react-native development server
open -a Terminal "`react-native start`"
# Compiling the code for ios and deploying it to the simulator
react-native run-ios # optionally, type: react-native run-android
# Alternatively, you could comment the line above and run the two lines below.
# open -a Terminal "`react-native run-ios`"
# open -a Terminal "`react-native run-android`"