views:

1109

answers:

4

I'd like build a game for both the iPhone and iPad. As such, it would make sense to start this project from scratch as a universal app. However, iPhone and iPad currently run two different versions of the iOS since iOS 4 isn't available for the iPad yet. There are two iOS 4 features (GameCenter and iAd) that I would like to support in my game.

  1. In this case, is it a bad idea to create this project as a universal app?
  2. If not, what are some thoughts I should take into consideration as I'm building a universal app that supports two different versions of the iOS?
  3. Is it somewhat safe to bet on Apple releasing the iOS 4 for the iPad in the fall as speculated?
  4. If so, is there anyway I can begin building these iOS 4 features (GameCenter and iAd) into my iPad version of my game?

Thanks so much in advance for all your wisdom!

EDIT: I understand this issue involves managing risks. I'm aware of the risks, but I'm more interested in any tech design considerations related to building a universal app when the iOS is fragmented among the various iOS devices.

+1  A: 

This is a question that is all about managing risk. Risks include:

  1. Apple doesn't release the expected "unified 4.1" OS within the timeframe you need
  2. The OS is released on time for your needs, but one or both of GameCenter or iAds aren't included
  3. GameCenter and/or iAds are included, but they don't match the exact API you were expecting
  4. The APIs are what you expected, but they are buggy since it is the first version on the iPad
  5. etc...

Only you can determine what level of each risk you're comfortable with, how likely you think each risk is, if you can mitigate each risk, and what the costs would be for any of these problems along the way.

Shaggy Frog
thanks, shaggy, i'm actually more interested in any tech design considerations i need to think about when building a universal app since the iOS is fragmented between the various devices. your thoughts?
BeachRunnerJoe
You mentioned "Is it somewhat safe to bet on Apple releasing the iOS 4 for the iPad in the fall as speculated?" and the answer to that is "no", because of the risk involved. It's not so easy to want to talk about risk management and tech design considerations as two separate things in this case. You're trying to build an app in such a way that you can't test it, never mind be sure all your work won't go to waste.
Shaggy Frog
very good insight! thanks, shaggy!
BeachRunnerJoe
+2  A: 

A good post on this subject: http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html

iWasRobbed
thanks, iwasrobbed, great article indeed!
BeachRunnerJoe
+7  A: 

You mainly need to do two things:

  1. Weak-link any frameworks that aren’t present in the 3.2 SDK.
  2. Write runtime tests for any APIs that are new to iOS 4.

To do the first, right-click on your target and select “Get Info.” The frameworks are listed in the inspector (under the “General” tab) with a drop-down box next to them that’ll allow you to select “Weak” linking. This ensures that the app will still run if the framework is not present.

To do the second, you could do something like the following to test for the new block-based animation in iOS 4:

if ([UIView respondsToSelector:@selector(animateWithDuration:animations:)]) {
    // Your awesome animation code here
} else {
    // Your almost-as-awesome, non-block-based animation code here.
}

By using introspective methods such as -respondsToSelector:, you can avoid calling something that the currently-running OS doesn’t support.

Note also that if you wanted to support iPhone OS 3.0, these same rules would apply.

Finally, it's also possible—though not advisable—to do this like so:

#ifdef __IPHONE_4_0
    // Your iOS 4.0-compatible code here
#elif defined(__IPHONE_3_2)
    // Your iPhone OS 3.2-compatible code here
#elif defined(__IPHONE_3_0)
    // Your iPhone OS 3.0-compatible code here
#endif

Why is this not advisable? Simple: only the code for the highest-numbered iOS version will be compiled. iPhone apps aren’t compiled separately for separate iOS versions, so to get this to actually work, you would have to release multiple versions of the app.

Jeff Kelley
thanks, Jeff, hugely helpful!
BeachRunnerJoe
This was very insightful, thanks!
bentford
+5  A: 

If you're about to build a Universal App, just remember the following two source code snippets:

  • Using classes only if they are available on the current device

Consider this piece of code:

UILocalNotification* n = [[UILocalNotification alloc] init];

When building a Universal App, this code will lead to a runtime error on any device running an iOS version that does not know about the UILocalNotification class.

You can still support UILocalNotification in your code while maintaining backwards compatibility by using the following code snippet:

Class notificationClass = NSClassFromString(@"UILocalNotification");
if (notificationClass) {
  UILocalNotification* n = [[notificationClass alloc] init];
}

This technique allows you to use classes which are unavailable in certain OS versions on devices that do support the classes.

  • Using methods only if they are available on the current device

Suppose you'd like to do the following:

[[UIApplication sharedApplication] scheduleLocalNotification:n];

Use the following piece of code to conditionally call the method in case it's available on the current device:

if ([UIApplication instancesRespondToSelector:@selector(scheduleLocalNotification:)]) {
  [[UIApplication sharedApplication] scheduleLocalNotification:n];
}

These two techniques are probably the only things you need to know to create your Universal App. Conditionally execute your code depending on device capabilities and you should be fine.

Having said that, you still need to consider that the iPad will probably be using a different UI than your iPhone counterpart. And, unfortunately, you won't be able to test your iPad UI with the iOS 4 features until they become available on the iPad. But this shouldn't be too much of a problem: if you use [[UIDevice currentDevice] userInterfaceIdiom] to check whether you're running on an iPad, you can prevent your Universal App from executing code that has no iPad UI yet. Once Apple releases iOS 4 for iPads, you can implement the UI, remove that check and release an update to the store.

Benjamin
thanks, benjamin, extremely helpful!
BeachRunnerJoe
Quick note for future readers: you MUST weak link UIKit if you're implementing the application:didReceiveLocalNotification: UIApplicationDelegate method, as it takes UILocalNotification as a parameter.
leolobato