Question

I realize there are a lot of questions here about making universal apps, but not so much on how to make a universal app that has completely different views and functions. I would want the user to be able to download one app, but each version is completely different. Is the only way to do this to use if statements, sensing what device the user has, and then loading the correct view controllers from there (i.e. in the delegate, load the correct first view controller)? Thanks

Was it helpful?

Solution

Basically you want to “deploy two different apps in a single binary”. In case you already have two apps that don't share class names (or other top level object names), that should be pretty simple.

You should run device specific code as soon as possible and that is in main.m. Pass different app delegate class for iPhone and for iPad. The rest should work as normal and no classes from the other “device” should be used.

int main(int argc, char * argv[]) {
    @autoreleasepool {
        UIUserInterfaceIdiom idiom = [[UIDevice currentDevice] userInterfaceIdiom];
        Class appDelegateClass = Nil;
        if (idiom == UIUserInterfaceIdiomPhone) {
            appDelegateClass = [iPhoneAppDelegate class];
        }
        else if (idiom == UIUserInterfaceIdiomPad) {
            appDelegateClass = [iPadAppDelegate class];
        }
        NSCAssert(appDelegateClass, @"Unexpected idiom! Maybe iWatch?");
        return UIApplicationMain(argc, argv, nil, appDelegateClass));
    }
}

You could also choose different split point, for example allocating different root view controller.

In case you want to share some code after all, you can just create universal superclasses, for example iPhoneAppDelegate and iPadAppDelegate can have superclass AppDelegate that handles notifications or URL handling.

OTHER TIPS

that is just the basic universal project's finish-launch method from the Apple:

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
    }
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

...but, you can load different view controllers for different interface idioms:

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.window.rootViewController = [[UIPhoneVersionViewController alloc] initWithNibName:@"UIPhoneVersionViewController" bundle:nil];
    } else {
        self.window.rootViewController = [[UIPadVersionViewController alloc] initWithNibName:@"UIPadVersionViewController" bundle:nil];
    }

    [self.window makeKeyAndVisible];
    return YES;
}

...and violá, job's done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top