3

My company develops an advertising SDK that mediates other ad networks. At runtime, it loads constants from those SDKs using CFBundleGetDataPointerForName, as outlined in this StackOverflow post.

However, I'm not able to get that approach to work to load the GADAdSize constants that AdMob's banner SDK uses. Here's what my code looks like:

HZGADAdSize *hzlookupAdMobAdSizeConstant(NSString *const constantName) {
    return CFBundleGetDataPointerForName(CFBundleGetMainBundle(), (__bridge CFStringRef)constantName);
}

HZGADAdSize *hzAdMobAdSizeFlexibleWidthPortrait(void) {
    return hzlookupAdMobAdSizeConstant(@"kGADAdSizeBanner");
}

The above code works fine for loading similar constants, like Facebook's FBAdSize struct, but the returned pointer is NULL when trying to load any GADAdSize constant.

Here's how the constant is defined in the AdMob SDK:

/// Do not create a GADAdSize manually. Use one of the kGADAdSize constants. Treat GADAdSize as an
/// opaque type. Do not access any fields directly. To obtain a concrete CGSize, use the function
/// CGSizeFromGADAdSize().
typedef struct GADAdSize {
  CGSize size;
  NSUInteger flags;
} GADAdSize;

#pragma mark Standard Sizes

/// iPhone and iPod Touch ad size. Typically 320x50.
extern GADAdSize const kGADAdSizeBanner;

Things I've tried so far

  1. Trying with all bundles in the app:

    CFArrayRef array = CFBundleGetAllBundles();
    for (int i = 0; i < CFArrayGetCount(array); i++) {
        CFBundleRef bundle = (CFBundleRef)CFArrayGetValueAtIndex(array, i);
        void *ptr = CFBundleGetDataPointerForName(bundle, (__bridge CFStringRef)@"kGADAdSizeBanner");
        if (ptr == NULL) {
            NSLog(@"pointer was NULL");
        } else {
            NSLog(@"pointer was present!!");
        }
    }
    

None of the bundles in the app have the constant, so I don't think its an issue of the pointers being in a different bundle.

  1. Marking the constants as extern in my code

    extern HZGADAdSize const kGADAdSizeSmartBannerPortrait;
    

The extern approach lets me reference the constants, but if AdMob isn't present when the app is compiled, I get compiler errors about the missing constants, so I don't think this option is feasible since many of our developers won't use AdMob.

  1. Loading function pointers from the same class. Edit: I was mistaken; I can't load function pointers either. I also can't load string constants.

    void *ptr = CFBundleGetFunctionPointerForName(CFBundleGetMainBundle(), (__bridge CFStringRef)@"CGSizeFromGADAdSize"); // returns NULL
    

To avoid XY problems: Our SDK loads constants at runtime so that if e.g. the AdMob SDK is present, we can pass the constants it defines to it. If the SDK isn't present (e.g. when the developer isn't using AdMob but is using other ad networks), we still need our SDK to compile without AdMob being there. If there's a way we can accomplish this without loading values at runtime, that's just as good a solution for me.

Version Information:

  • AdMob SDK 7.0.0
  • iPhone 6 Simulator
  • iOS 8.2
  • Xcode 6.2
Community
  • 1
  • 1
MaxGabriel
  • 7,617
  • 4
  • 35
  • 82
  • Is `kGADAdSizeBanner` set anywhere in the code ? Also why are you accessing it using the constants ? – Mostafa Berg May 06 '15 at 19:44
  • `kGADAdSizeBanner` is a constant in AdMob's SDK—it's set by them in a compile-time statement in their SDK. There isn't any other way to access it other than the constant, so I don't understand your second question. – MaxGabriel May 06 '15 at 21:57
  • I haven't worked long enough with AdMob to know if there are other ways than the constants, but i'm pretty sure there has to be another way, What does this output though ? `GADBannerView *bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];` `NSLog(@"%f,%f", bannerView.frame.size.height,bannerView.frame.size.width);` – Mostafa Berg May 07 '15 at 11:09
  • That prints: `50.000000,375.000000` – MaxGabriel May 08 '15 at 02:55
  • seems like it works , check your code that reads constants ! I'm on vacation with no internet or computer. Will check back on Monday . Till then try to trace your code and see where things to bad. – Mostafa Berg May 11 '15 at 19:07
  • @MostafaTorbjørnBerg: the goal is to be able to load the constants without introducing a compile-time dependency on them, per the paragraph at the bottom of the question – MaxGabriel May 12 '15 at 22:53

0 Answers0