How to use different interface declarations at compile time without confusing Interface Builder

If I have multiple builds of my app, paid and free versions, for example, and I want to have different interfaces depending on which build, it seems to confuse Interface Builder.

For example:

  • How can I scan barcodes on iOS?
  • UIView with rounded corners and drop shadow?
  • voice over can only see a page of a uicollectionview
  • How to unwind to the first view controller on a navigation stack
  • Insert string at cursor position of UITextField
  • Expected declaration error for making high score
  • // MyViewController.h
    #ifdef FREE
    @interface MyViewController : NSObject <UIActionSheetDelegate, ADBannerViewDelegate>
    #else
    @interface MyViewController : NSObject <UIActionSheetDelegate>
    #endif
    {
        IBOutlet UILabel* myLabel;
    }
    - (IBAction) myAction:(id)sender;
    

    When I load up MyViewController.xib in IB, it shows warnings in the Info window like “The ‘myLabel’ outlet of ‘File’s Owner’ is connected to ‘My View’ but ‘myLabel’ is not longer defined on MyViewController.”

    Is there a way to do this so as not to confuse IB?

    I suppose the other option is to just not #ifdef it, and have one definition for all builds. What happens if I build with my controller conforming to ADBannerViewDelegate (which requires iOS 4), and I deploy on iOS 3.2? If that works, maybe there’s no issue…

    Solutions Collect From Internet About “How to use different interface declarations at compile time without confusing Interface Builder”

    I haven’t been able to figure out a way to get IB to understand the structure you’re using (I tried to do it with a paid/free app I made in the past). This is how I solving my problem:

    I didn’t use the conditional compilation in my @interface definition. I just defined the class as normal as if it was the paid, non-ad version. Let’s call it MyPaidViewController.

    @interface MyPaidViewController : UIViewController <UIActionSheetDelegate> {
    

    Then I created a subclass of MyPaidViewController which was the for the free version. Something like:

    @interface MyFreeViewController : MyPaidViewController <ADBannerViewDelegate> {
    

    Since I usually needed to use a different xib for my free version than I did for my paid version (because I had to move stuff around in order to make room for the ads) I would just have the paid xib use MyPaidViewController as File’s Owner and my free xib use MyFreeViewController as the File’s Owner.

    Interface Builder will see the IBOutlets from the super classes too, so you’ll be able to reference myLabel in your free xib.

    Make sure MyPaidViewController is part of the paid and the free build targets, but the MyFreeViewController should only be part of the free build target.