Indeed, you cannot mark the protocol extension function as @objc (or dynamic ), which is equivalent, by the way). You can only send class methods using Objective-C runtime.
In your specific case, if you really want to do this through a protocol extension, I can offer the following solution (assuming your original protocol is named ObjcProtocol ).
Create a wrapper for our notification handler:
final class InternalNotificationHandler { private let source: ObjcProtocol init(source: ObjcProtocol) { // We require source object in case we need access some properties etc. self.source = source } @objc func presetLoaded(notification: NSNotification) { // Your notification logic here } }
Now we need to expand our ObjcProtocol to introduce the required logic.
import Foundation import ObjectiveC internal var NotificationAssociatedObjectHandle: UInt8 = 0 extension ObjcProtocol { // This stored variable represent a "singleton" concept // But since protocol extension can only have stored properties we save it via Objective-C runtime private var notificationHandler: InternalNotificationHandler { // Try to an get associated instance of our handler guard let associatedObj = objc_getAssociatedObject(self, &NotificationAssociatedObjectHandle) as? InternalNotificationHandler else { // If we do not have any associated create and store it let newAssociatedObj = InternalNotificationHandler(source: self) objc_setAssociatedObject(self, &NotificationAssociatedObjectHandle, newAssociatedObj, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) return newAssociatedObj } return associatedObj } func registerForPresetLoadedNotification() { NSNotificationCenter.defaultCenter().addObserver(self, selector:
I know this may not seem very elegant, so I would think about changing the main approach.
Note: You can restrict the extension of the protocol.
extension ObjcProtocol where Self: SomeProtocolOrClass
source share