1

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
  • 1,151
  • 12
  • 21

4 Answers4

0

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.

pro_metedor
  • 1,176
  • 10
  • 17
  • It is not Objective-c or cocoa style, this way frequently used in java. – abuharsky Oct 26 '12 at 12:57
  • This is a design pattern which can have use in Objective-C. Object Oriented Application Design principles and patterns stick to Objective-C programming as well. – pro_metedor Oct 26 '12 at 13:12
0

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.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
0

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 flag

For more information, look here (in comments):
http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html

tt.Kilew
  • 5,954
  • 2
  • 33
  • 51
0

@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:

self.refreshControl = [[UIRefreshControl alloc] init];

Let us know if that doesn't work for you.