CFBundleGetDataPointerForName (& co) doesn't work for values from iOS 8-style frameworks
| Originator: | feedback.tagher | ||
| Number: | rdar://20233759 | Date Originated: | 19-Mar-2015 |
| Status: | Open | Resolved: | |
| Product: | iOS | Product Version: | 8.2 |
| Classification: | Serious Bug | Reproducible: | Always |
Summary:
Functions that load values at runtime by their name (CFBundleGetDataPointerForName and CFBundleGetFunctionPointerForName) don't work when the constants are from an iOS 8-style framework (the kind discussed in WWDC 2014 Session 416: Building Modern Frameworks). Instead, the functions always return NULL for the looked up value.
Steps to Reproduce:
Instructions using a project pre-built by me:
1. git clone https://github.com/MaxGabriel/iOS8FrameworkGetDataPointer
2. Open the .xcodeproject file
3. Observe this code is in the AppDelegate:
void * versionPointer = CFBundleGetDataPointerForName(CFBundleGetMainBundle(), CFSTR("TestFramework2VersionNumber"));
NSLog(@"Version pointer is %@",versionPointer ? @"PRESENT" : @"NULL");
NSAssert(versionPointer != NULL, @"Version pointer should not be NULL");
4. Build the project and observe it crashes on the assertion.
Manual instructions, not using a pre-built git repo:
1. Create an iOS 8-style framework project template in Xcode
2. Build the framework for the simulator, open the derived data folder for that project, and find the built framework
3. Create a new iOS project, using a template like "Single View Application". Drag in the framework built in the previous step.
4. Add the built framework to "Linked Frameworks and Libraries" and "Embedded Binaries".
5. Attempt to load the version constant from the framework, making sure to use the correct constant name, like so:
void * versionPointer = CFBundleGetDataPointerForName(CFBundleGetMainBundle(), CFSTR("TestFramework2VersionNumber"));
NSLog(@"Version pointer is %@",versionPointer ? @"PRESENT" : @"NULL");
NSAssert(versionPointer != NULL, @"Version pointer should not be NULL");
-----------
You can also reproduce this with a 3rd party framework, like the one AdMob uses https://developers.google.com/mobile-ads-sdk/download
Expected Results:
CFBundleGetDataPointerForName looks up a non-NULL pointer.
Actual Results:
CFBundleGetDataPointerForName looks up a NULL pointer.
Version:
iOS 8.2 (12D508) and Xcode 6.2 (6C131e)
Notes:
Github repo of the xcodeproject I used to make the iOS 8 framework: https://github.com/MaxGabriel/iOS8Framework
Github repo of the xcodeproject that tries to load a constant from that framework: https://github.com/MaxGabriel/iOS8FrameworkGetDataPointer
Configuration:
iPhone 6 Device and Simulator
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!