Checking for availability of iOS classes (rather than methods) in MonoTouch

522 Views Asked by At

MonoTouch exposes the RespondsToSelector method for checking the availability of methods across iOS versions.

However I can't seem to find out how to perform the similar checks for class availability.
Apple documents it here that in iOS 4.2+ you should attempt to access a static class selector of the required class. e.g:

if ([EKReminder class]) 
{
    ....
}

However that doesn't seem to be exposed. I think it is similar to my previous question here, in that to implement this in MT it would need explicit mapping of a Class static property on every MT type.

So I guess my question is, should I just use the old pre iOS 4.2 technique? i.e:

Class cls = NSClassFromString (@"EKReminder");
if (cls) 
{
    ...
}

Which I think maps to:

var iosClass = Class.GetHandle("EKReminder");
if ( iosClass != null )
    ...

Or call the selector manually using the interop methods available in Messaging?

Or some other approach that I havn't found?

2

There are 2 best solutions below

0
On BEST ANSWER

The safe check is using:

if (Class.GetHandle (typeof (EKReminder)) != IntPtr.Zero) {
    // we know we can use EKReminder
}

However it's a bit costly because it involves reflection. The Objective-C name can differ from the .NET name (e.g. NSURL versus NSUrl and that can only be found by reflecting the Register attribute).

If you know the Objective-C name then you can use the, non-type safe, overload to skip reflection. E.g.

// checking for NSUrl would not work
if (Class.GetHandle ("NSURL") != IntPtr.Zero) {
    // we know we can use NSUrl
}

Again (and to generalize my answer for everyone) it's often best/easier/faster to use the iOS version to do runtime checks for non-hardware features.

if (UIDevice.CurrentDevice.CheckSystemVersion (5,0)) {
    // we know feature X was added in 5.0
}
0
On

Just use the pre-iOS 4.2 technique:

var iosClass = Class.GetHandle ("EKReminder");
if (iOSClass != null)
    ...

The method recommended by Apple seems to be special-cased by gcc/clang, which will not work in MonoTouch.