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

标签 ios objective-c swift

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

我正在使用 Xcode 7.3 (7D175)

下面是一些复制步骤:

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

    extension AppDelegate {
    
        public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    
        }
    }
    

这会导致编译器报错:

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)

我做错了什么?

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

Add override to the method declaration so it reads override public ...

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

error: method does not override any method from its superclass override public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)

最佳答案

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

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

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

extension AppDelegate {
    public func application(app application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {    
    }
}

然后您查看此文件,您会发现类似以下内容:

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

请注意您的扩展方法是如何作为类别添加到 AppDelegate 上的。现在,想象一下如果您的函数形式正确(签名中没有 app)

,这个文件会是什么样子
@interface AppDelegate (SWIFT_EXTENSION(XTNTest))
    - (void)application:(UIApplication * _Nonnull)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData * _Nonnull)deviceToken;
@end

这是对已在 UIApplicationDelegate 协议(protocol)中声明的方法的重新声明。

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

关于ios - 在 Swift 扩展中实现 didRegisterForRemoteNotificationsWithDeviceToken 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37123183/

相关文章:

ios - 如何在不花时间使用 Swift 的情况下从 iPhone 获取所有包含图像的相册?

ios - 为什么 Swift 中的方法可以有没有类型的参数?

objective-c - NSTextField 在自定义 NSWindow 中不可编辑

ios - 尝试为我的应用程序编写一个简短的介绍

ios - 释放 UINavigationController 后内存仍然很高

iOS - 什么是分配泄漏?

ios - UITableViewCell 中的动画立即完成

objective-c - 为什么不是 drawRect : getting called?

ios - 幽灵 View Controller

ios - 线程 1 :signal SIGABRT error