Categories
iOS Swift

AnyClass protocol and Objective-C methods

AnyClass is a protocol all classes conform to and it comes with a feature I was not aware of. But first, how to I ended up with using AnyClass. While working on code using CoreData, I needed a way to enumerate all the CoreData entities and call a static function on them. If that function is defined, it runs an entity specific update. Let’s call the function static func resetState().

It is easy to get the list of entity names of the model and then turn them into AnyClass instances using the NSClassFromString() function.

let entityClasses = managedObjectModel.entities
.compactMap(\.name)
.compactMap { NSClassFromString($0) }
view raw AnyClass.swift hosted with ❤ by GitHub

At this point I had an array of AnyClass instances where some of them implemented the resetState function, some didn’t. While browsing the AnyClass documentation, I saw this:

You can use the AnyClass protocol as the concrete type for an instance of any class. When you do, all known @objcclass methods and properties are available as implicitly unwrapped optional methods and properties, respectively.

Never heard about it, probably because I have never really needed to interact with AnyClass in such way. Therefore, If I create an @objc static function then I can call it by unwrapping it with ?. Without unwrapping it safely, it would crash because Department type does not implement the function.

class Department: NSManagedObject {
}
class Employee: NSManagedObject {
@objc static func resetState() {
print("Resetting Employee")
}
}
// This triggers Employee.resetState and prints the message to the console
for entityClass in entityClasses {
entityClass.resetState?()
}
view raw AnyClass.swift hosted with ❤ by GitHub

It has been awhile since I wrote any Objective-C code, but its features leaking into Swift helped me out here. Reminds me of days filled with respondsToSelector and performSelector.

If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading.