Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CGFontCreateWithDataProvider hangs in airplane mode

When I make a call to CGFontCreateWithDataProvider while in airplane mode, my apps freeze. Not in airplane mode, it works fine. The font is stored on the device, no network access should be happening.

While calling this method to load a local font file:

[self registerIconFontWithURL:[[NSBundle mainBundle] URLForResource:@"FontAwesome" withExtension:@"otf"]];

The value of url in the following method is: file:///var/mobile/Applications/48D3DA14-235B-4450-A081-7A6BA6116667/Blah.app/FontAwesome.otf

+ (void)registerIconFontWithURL:(NSURL *)url
{
    NSAssert([[NSFileManager defaultManager] fileExistsAtPath:[url path]], @"Font file doesn't exist");
    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)url);

//******Freezes after the next line******
    CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
//******FROZEN******

    CGDataProviderRelease(fontDataProvider);
    CFErrorRef error;
    CTFontManagerRegisterGraphicsFont(newFont, &error);
    CGFontRelease(newFont);
}

iOS 7.1.x, iPhone 5.

I have no idea why this might happen and haven't been able to find any help out there. Does anyone have a clue why this might happen?

Thanks in advance!

like image 942
DiscDev Avatar asked Jul 23 '14 02:07

DiscDev


1 Answers

I found the answer after a bit more searching.

According to the following bug report: https://alpha.app.net/jaredsinclair/post/18555292

If there’s no network connection, CGFontCreateWithDataProvider() hangs in a semaphore trap if it’s called during appDidFinishLaunchingWithOptions. Calling it in the next run loop works without hanging.

As noted in the same post, calling

[UIFont familyNames]

before CGFontCreateWithDataProvider()

resolves the issue. My code now looks like this and works as expected:

+ (void)registerIconFontWithURL:(NSURL *)url
{
    NSAssert([[NSFileManager defaultManager] fileExistsAtPath:[url path]], @"Font file doesn't exist");
    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)url);

    //THE NEXT LINE IS RELEVANT PART
    [UIFont familyNames];

    CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
    CGDataProviderRelease(fontDataProvider);
    CFErrorRef error;
    CTFontManagerRegisterGraphicsFont(newFont, &error);
    CGFontRelease(newFont);
}
like image 123
DiscDev Avatar answered Oct 13 '22 18:10

DiscDev