0

How can I have an application that has iAds be able to run on an iPhone 2G. I understand that this device doesn't support iAds therefore I would want the code not to be executed.

Here is some of my code. The .h file:

#import <UIKit/UIKit.h>
#ifdef __IPHONE_4_0 
#import <iAd/iAd.h>
#endif

@interface ViewController : UIViewController
#ifdef __IPHONE_4_0 
<ADBannerViewDelegate> 
#endif
{
#ifdef __IPHONE_4_0 
    ADBannerView    *adView;
#endif
...

In the .m file I have all iAd coded surrounded like so:

#ifdef __IPHONE_4_0     //iAd Code
    adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
    adView.frame = CGRectOffset(adView.frame, 0, 500);
    adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    [self.view addSubview:adView];
    adView.delegate = self;
    self.bannerIsVisible = NO;
#endif

However I still get an error. The app always crashes and will only show the startup image. I get a popup saying, "Error Starting Executable 'app' Error launching remote program: failed to get the task for process 411." Here is the console:

GNU gdb 6.3.50-20050815 (Apple version gdb-1518) (Thu Jan 27 08:40:30 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=x86_64-apple-darwin --target=arm-apple-darwin".tty /dev/ttys000
warning: Unable to read symbols from "iAd" (not yet mapped into memory).
target remote-mobile /tmp/.XcodeGDBRemote-6877-41
Switching to remote-macosx protocol
mem 0x1000 0x3fffffff cache
mem 0x40000000 0xffffffff none
mem 0x00000000 0x0fff none
michaellindahl
  • 2,012
  • 5
  • 36
  • 64
  • possible duplicate of [Are Apps using iAd compatible with older iOS](http://stackoverflow.com/questions/3128457/are-apps-using-iad-compatible-with-older-ios) – Brad Larson Mar 19 '11 at 22:18

2 Answers2

1

As Daniel White says, first you have to weak link to the iAd library (that way, the library won't link into your app at runtime if the OS doesn't have it). To do that, expand the tree under your app's name in Targets in Xcode, and click the Link Binary With Libraries item. Then you should be able to find the iAd.framework and change its role from "Required" to "Weak".

Then, in your code you'll want to do run-time (not compile-time, as you are doing now) checks for the iAd framework. For instance,

// Add in iAd banner, if we are running on 4.0+
Class adBannerClass = NSClassFromString(@"ADBannerView");
if (adBannerClass != nil)
{
        adView = ....

That way the same code will execute on iOS 4.0+ devices and iOS 3.2 and earlier devices just fine.

Jeff Hay
  • 2,655
  • 28
  • 32
  • Do I need to surround any code in the .h file? (import line, ``, `ADBannerView *adView;`) Or anything else in the .m file? (`bannerViewDidLoadAd` method, and failed method and the `adView.delegate=nil;` `[adView release];` code in the dealloc method) Thanks – michaellindahl Mar 21 '11 at 02:24
  • @michaellindahl: You'll need to surround anything that references the `ADBannerView` class, or an instance of it, in your .m (as well as any of the iAD-related constants, etc.). However, if you declare the `adView` to be a just a `UIView` (instead of an `ADBannerView`) in the .h file, you can avoid having to surround code there and in the dealloc (but can still assign the IBOutlet in IB). Since the `` is really just a compile-time thing, you don't need to worry about surrounding that at all. – Jeff Hay Mar 21 '11 at 04:36
0

You will have to remove your conditional compiling and weak-link to iAd's library. You should use standard if blocks to check for the version.

Here is a tutorial i found: http://www.vellios.com/2010/07/04/using-ios-4-frameworks-on-os-3/

What you are doing with the ifdefs, is conditionally compiling.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445