home-assistant / Iconic

:art: Auto-generated icon font library for iOS, watchOS and tvOS
Apache License 2.0
1.58k stars 86 forks source link

Error registering / unregistering font file. #35

Closed salisbbn closed 8 years ago

salisbbn commented 8 years ago

Hey. Cool project.

Everything was working great for about 2 weeks, then I started getting this error:

Error Domain=com.apple.CoreText.CTFontManagerErrorDomain Code=105 "Could not register the font file(s)"

So, I checked out error code 105 -> kCTFontManagerErrorAlreadyRegistered

I looked through Iconic's source and it doesn't look like the "already registered" case was handled, so I thought I'd just handle it myself in the app delegate by unregistering the font first:

let bundle = NSBundle(forClass: Iconic.self)
if let url = bundle.URLForResource("Linearicons", withExtension: "ttf"){
       var error: Unmanaged<CFErrorRef>? = nil
       CTFontManagerUnregisterFontsForURL(url, .None, &error)
       Iconic.registerIconFont()
}

However, the call to CTFontManagerUnregisterFontsForURL also returns an error:

Error Domain=com.apple.CoreText.CTFontManagerErrorDomain Code=201 "Could not unregister the font file(s)"

So, I checkout out error code 201 -> kCTFontManagerErrorNotRegistered

Not registered... o.O

Have you run into this before - not being able to register nor unregister a font? Tried cleaning, deleting my derived data, deleting the simulator's data, and double checked the font urls, but no luck.

Could Iconic try to continue its initialization in the case when the error is 105 - already registered?

Any suggestions appreciated.

Thanks!

dzenbot commented 8 years ago

So this error is triggered as soon as you call Iconic.registerIconFont() then? Would you mind sharing your icon font file? I have not seen this on the ones I use.

salisbbn commented 8 years ago

That's right, I think the error is triggered around line 192 causing configure(withURL: url, name: fontName, map: map) to never get called.

Here's the font file I use:

Linearicons-Free.ttf.zip

dzenbot commented 8 years ago

I just tried the font file in the sample project, and all works as expected: image

I pushed this into a branch, so you can test it out and compare it with your setup. https://github.com/dzenbot/Iconic/tree/linearicon-sample

(I love the icons btw, very cool! Specially the 💩)

salisbbn commented 8 years ago

Thanks - I tested the sample project - it's working as expected just like mine used to. I did a line-by-line comparison of the generated files and everything is the same. I checked the size of the binary and there is a difference there, but it seems a little crazy to think that a build setting somewhere is causing hiccup, especially when I swapped in a different icon file (Fontawesome) and everything worked. Changing back to Linearicons still produces the "already registered" error though.

Will keep digging.

dzenbot commented 8 years ago

Let me know if you find anything. I ran the pod installation a few times, plus added new dependencies, just for testing, and it still worked.

By any chance, are you also adding the Linearicons to your plist?

salisbbn commented 8 years ago

I'm not. Though I did try it that way too, just for kicks :)

salisbbn commented 8 years ago

Ok - I figured out what was going on. If the font file is part of the Copy Bundle Resources build phase then Iconic can't register the font because it gets automatically registered by the OS just by being part of that build phase - even if the font is not declared as an app provided font in the plist.

Removing the font file from the Copy Bundle Resources phase fixed the issue. Perhaps, as a future enhancement, Iconic could check if the font has already been registered, and, if so, ignore the error and continue with its initialization.

dzenbot commented 8 years ago

That is so strange! I will def. put something on the README about this, and will see if there's a way Iconic could skip registering but continue with its initialisation to mitigate this error. Thanks for the headsup!

dzenbot commented 8 years ago

@salisbbn: I've been trying to reproduce your error without success. Would you mind providing a sample project with it? So I can know if there is an error code Iconic could observe and handle it correctly.

salisbbn commented 8 years ago

@dzenbot Here's the sample project that exhibits the behavior.

A couple of notes - it looks like that in addition to the font file being part of the Copy Bundle Resources build phase, the font also needs to be used somewhere in the IB (I added a quick label to Main.storyboard -> ThirdViewController). If either of those two conditions aren't met, no failure will occur. The font needed to installed on my machine for it to pop up in the IB's font selector (screen shot below).

One other note - I had to move Iconic.registerIconFont() to func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?)... when it was part of init() it fell into a semaphore wait trap. Odd.

Iconic.zip

screen shot 2016-08-23 at 8 00 52 am
salisbbn commented 8 years ago

Yep, this seems to have done the trick. Thanks!