I'm trying to slowly migrate from Obj-C to Swift. My first step is to migrate small, simple methods to Swift extensions so I decided to try and migrate didRegisterForRemoteNotifications
but that didn't work because it thinks the method is implemented somewhere else in my Objective-C code. It is not.
I'm using Xcode 7.3 (7D175)
Here's some reproduction steps:
AppDelegate-Extension.swift
. This also creates a Bridging header file.#import AppDelegate.h
to the Briding header file.Go to the empty Swift file and type:
extension AppDelegate {
public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
}
}
This causes to compiler to complain:
method 'application(_:didRegisterForRemoteNotificationsWithDeviceToken:)' with Objective-C selector 'application:didRegisterForRemoteNotificationsWithDeviceToken:' conflicts with previous declaration with the same Objective-C selector public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { ^ __ObjC.AppDelegate:38:17: note: 'application' previously declared here public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
What am I doing wrong?
EDIT: Some suggestions that I've tried:
Add
override
to the method declaration so it readsoverride public ...
This returns the following error (in addition to the original error)
error: method does not override any method from its superclass override public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
Your problem is that you can't use an extension in this way in a mixed Swift & Objective-C environment.
In Swift, you can use an extension to provide implementations for functions that have been declared in a protocol that is adopted by a class. This is the core of 'protocol-oriented-programming'
In Objective-C, a category is used to add additional functions to an existing class. When you create your Swift extension, Xcode creates a targetname-Swift.h file in the derived-data folder. Now, you can't see this file because your compile is failing, but if you change your extension slightly so that the compilation works
extension AppDelegate {
public func application(app application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
}
}
and then you look at this file you will find something like:
@interface AppDelegate (SWIFT_EXTENSION(XTNTest))
- (void)applicationWithApp:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken;
@end
Note how your extension method has been added as a category onto AppDelegate
. Now, imagine what this file would look like if you had the correct form of your function (no app
in the signature)
@interface AppDelegate (SWIFT_EXTENSION(XTNTest))
- (void)application:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken;
@end
This is a re-declaration of a method that is already declared in the UIApplicationDelegate
protocol.
The upshot of all this is that you either need to adopt Swift on a class-by-class basis or you need to use subclassing if you want to use a function-by-function basis since there is a difference between an Objective-C category and a Swift extension.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With