在Swift扩展中实现didRegisterForRemoteNotificationsWithDeviceToken不起作用

oli*_*esF 5 objective-c ios swift

我正在尝试从Obj-C慢慢迁移到Swift.我的第一步是将小的,简单的方法迁移到Swift扩展,所以我决定尝试迁移,didRegisterForRemoteNotifications但这不起作用,因为它认为该方法是在我的Objective-C代码中的其他地方实现的.它不是.

我正在使用Xcode 7.3(7D175)

这是一些复制步骤:

  • 创建一个新的Obj-C项目.
  • 创建一个名为的新的空Swift文件AppDelegate-Extension.swift.这也会创建一个Bridging头文件.
  • 添加#import AppDelegate.h到Briding头文件.
  • 转到空的Swift文件并键入:

    extension AppDelegate {
    
        public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这导致编译器抱怨:

方法'application(_:didRegisterForRemoteNotificationsWithDeviceToken :)'与Objective-C选择器'application:didRegisterForRemoteNotificationsWithDeviceToken:'与之前的声明冲突与相同的Objective-C选择器公共func应用程序(应用程序:UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken:NSData){^ __ObjC.AppDelegate :38:17:注意:'application'以前在这里声明了public func application(应用程序:UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken:NSData)

我究竟做错了什么?

编辑: 我尝试过的一些建议:

添加override到方法声明,以便读取override public ...

这将返回以下错误(除了原始错误)

error:方法不会覆盖其超类覆盖公共func应用程序中的任何方法(应用程序:UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken:NSData)

Pau*_*w11 4

您的问题是您无法在混合 Swift 和 Objective-C 环境中以这种方式使用扩展。

在 Swift 中,您可以使用扩展来为类采用的协议中声明的函数提供实现。这是“面向协议编程”的核心

在 Objective-C 中,类别用于向现有类添加附加功能。当您创建 Swift 扩展时,Xcode 会在导出数据文件夹中创建一个targetname-Swift.h文件。现在,您看不到此文件,因为您的编译失败,但如果您稍微更改扩展名以便编译工作

extension AppDelegate {
    public func application(app application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {    
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你查看这个文件,你会发现类似的内容:

@interface AppDelegate (SWIFT_EXTENSION(XTNTest))
    - (void)applicationWithApp:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken;
@end
Run Code Online (Sandbox Code Playgroud)

请注意您的扩展方法如何作为类别添加到AppDelegate. 现在,想象一下如果您的函数具有正确的形式(app签名中没有),这个文件会是什么样子

@interface AppDelegate (SWIFT_EXTENSION(XTNTest))
    - (void)application:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken;
@end
Run Code Online (Sandbox Code Playgroud)

这是对协议中已声明的方法的重新声明UIApplicationDelegate

所有这一切的结果是,您要么需要逐个类地采用 Swift,要么如果您想使用逐个函数的基础,则需要使用子类化,因为 Objective-C 类别之间存在差异和一个 Swift 扩展。