The problem: every new iOS adds a lot of new useful classes. For example, UIRefreshControl. I want to add support for this class in iOS5 build.
Not cool solution: In all classes that must use UIRefreshControl, I can check for current iOS version and use inline replacement for that classes, for example:
pseudocode
...
- (void)viewDidLoad
{
...
if([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
self.refreshControl = [[MyCustonRefreshControl_for_iOS5 alloc] init];
}
else
{
self.refreshControl = [[UIRefreshControl alloc] init];
}
...
}
This solution is't cool, because I must add same code in all classes where I want to use latest iOS features.
Possible cool solution: 1) get or create your own 100% compatible class, for example for UIRefreshControl you can use CKRefreshControl (https://github.com/instructure/CKRefreshControl); 2) use Objective-C runtime to define replacement class as main class when App starts.
pseudocode
...
// ios 5 compatibility
#include <objc/runtime.h>
#import "CKRefreshControl.h"
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
// pre-ios 6 compatibility
if([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// register refresh control
Class clazz = objc_allocateClassPair([CKRefreshControl class], "UIRefreshControl", 0);
objc_registerClassPair(clazz);
}
...
}
I think that this way is really cool, but this code won't work.
@abuharsky, [CKRefreshControl]https://github.com/instructure/CKRefreshControl has been updated and now does exactly what you are asking for. All you need to do is:
Let us know if that doesn't work for you.
The second soultion should work fine
There's can be some issues when ARC is enabled, so, you should move allocate_pair code to some class, that is compiled with
-fno-objc-arc
flagFor more information, look here (in comments):
http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html
If all method calls are identical (and no class/"static" methods to speak of), simply use a "factory" method to create the objects and then use them "normally".
Otherwise, I'd probably use a "wrapper" class that reroutes calls to either the builtin support or your "replacement", based on one of the tests Filip's post.
You may want to make one consistent interface with different ways of doing the job. You need a strategy design pattern to solve your problem. Then you need to check for version only once - at initialisation of object which is doing iOS version specific job.