Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 4 Objective-C Runtime and casting to NSObjectProtocol

In Swift 3, I had a snipped of code that called into Objective-C runtime to check if a certain class is present.

guard let managerClass = NSClassFromString("ASIdentifierManager") as? NSObjectProtocol else {
    return nil
}

This returns AnyClass instance and it is castable to NSObjectProtocol - so I could call methods like responds and perform to work with selectors.

In Swift 4, this still works at runtime, but will emit a warning:

Cast from 'AnyClass?' (aka 'Optional') to unrelated type 'NSObjectProtocol' always fails

Oddly it still works, but I am worried a certain Swift version will kill the code.

What is the proper way to get rid of this warning? To what should I cast the object, to be able to perform selectors on it dynamically?

like image 596
Legoless Avatar asked Aug 30 '17 10:08

Legoless


1 Answers

Looks like you need to cast from AnyObject.Type to AnyObject first to convince the compiler that you're talking about an instance (albeit an instance of a metaclass, as you know):

    guard
        let klass = NSClassFromString("ASIdentifierManager"),
        let managerClass = klass as AnyObject as? NSObjectProtocol else
    {
        return nil
    }

I'm not sure whether this should be considered a compiler bug or not. I'd bet not, and that there's some Swiftian reason that NSObjectProtocol does not apply to ObjC type objects when in a Swift context.

like image 80
jscs Avatar answered Nov 14 '22 23:11

jscs