我正在尝试慢慢地从 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 readsoverride 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/