views:

832

answers:

2

I have a video that I play. To use full screen in iOS 3.2 I use the MPMoviePlayerViewController (seems to only work with that Class). But if I want to build for iOS 3.0 I obviously get several errors, because this class is not known in iOS 3.0. I also know how to get what I want with MPMoviePlayerController in iOS 3.0, but I can only have one, either the code for iOS 3.0 or the code for iOS 3.2.

How to cope with that ? - Solution found (see bottom of bundled edit)

I guess I have to use multiple targets, do you have suggestions on how to do that (always when I tried multiple targets I got errors and gave up :) ) ?


Edit bundled (multiple edits combined)

First I thought this would work.

#ifdef __IPHONE_3_0
// OS 3.0 specific
#endif

But it doesn't because in the iOS's Availability.h files you have all OS's defined from 2.0 up to your current one. So if you compile for iOS 3.2 the #ifdef __IPHONE_3_0 will return true as well.

Then I thought this would work

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2
  // Code for older iOS
#else
  // Code for iOS 3.2 up
#end

But it doesn't also. Because in iOS 3 for example __IPHONE_3_2 is undefined.

So I thought I would have to create some more intelligent if/elseif/else block but then I (finally :D) read the comment above the __IPHONE_X_X in apples AvailabilityInternal.h file definitions:

It says that you can use __IPHONE_OS_VERSION_MIN_REQUIRED for exactly that kind of problem, but that you shouldn't use the __IPHONE_X_X constants because of what just happened to me... they simply might not be defined thus evaluating to 0. So they recommend to use the values instead. So I have a working selector now like this...

Solution that I found

(Now this really works 100 %)

#if __IPHONE_OS_VERSION_MIN_REQUIRED < 30200
  // code for iOS below 3.2
#else
  // code for iOS 3.2 ++
#endif
A: 

Try this...

#ifdef IPHONE_OS_3.2

/* iOS 3.2 code */

#endif

#ifdef IPHONE_OS_3.0

/* iOS 3.0 code */

#endif

...the offending code will get removed before the compiler sees it.

Mike Howard
And if I want to include iOS 4 too ?Is there something like#ifdef GREATER_THAN_IPHONE_OS_3_2_AND_SMALLER_THAN_IPHONE_OS_4_0
Allisone
#ifdef IPHONE_OS_3.0 doesn't work,#ifdef __IPHONE_3_0 does
Allisone
And even if your code would have been correct (__IPHONE_3_0 instead of IPHONE_OS_3.0) the logic would be wrong, because in OS 3.2 both constants are defined (__IPHONE_3_0 and __IPHONE_3_2 and everything in between and before that OS) so both peaces of your code would be executed.
Allisone
+4  A: 

I'm not sure if this is what you are trying to do, but as per Apple's recommendation for universal apps in the iPad Programming Guide, if you want to build for multiple OS versions with inconsistent APIs, you should use NSClassFromString, and go from there. This way, you only have to have one target (the lowest OS you support) and through out your code have things like

Class mplayerControllerClass = NSClassFromString(@"MPMoviePlayerViewController");
if(mplayerControllerClass != nil) {
   //Code for 3.2, e.g. [mplayerControllerClass alloc]
} else {
   //Code for pre-3.2 OSes
}
Jared P
Looks nice.Yet I will go with the if blocks now, because it's quite easy, and I already have implemented it that way. But I will keep this technique in mind for the next case. Thank you
Allisone
The problem with the `#ifdef` blocks is that they fail when a new OS is released. @Jared's method will continue to work as long as either `MPMoviePlayerViewController` or the alternative exist.
kubi
Not to be greedy or anything, but are you going to accept one of the answers?
Jared P