iosxamarin.iosweak-linking

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


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?


Solution

  • 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
    }