Ios 如何使用通知。名称从swift 3扩展到Objective-C
我为Ios 如何使用通知。名称从swift 3扩展到Objective-C,ios,swift3,notifications,extension-methods,nsnotification,Ios,Swift3,Notifications,Extension Methods,Nsnotification,我为通知创建了一个扩展名。Name如下所示: public extension Notification.Name { public static let blahblahblah = Notification.Name(rawValue: "blahblahblah") } 现在我想在Objective-C中使用这个扩展,但即使它是公共的,也无法访问它 您能告诉我如何在Objective-C和swift中访问和使用此swift扩展吗 以前我在Objective-C中使用常量值,但
通知创建了一个扩展名。Name
如下所示:
public extension Notification.Name {
public static let blahblahblah = Notification.Name(rawValue: "blahblahblah")
}
现在我想在Objective-C中使用这个扩展,但即使它是公共的,也无法访问它
您能告诉我如何在Objective-C和swift中访问和使用此swift扩展吗
以前我在Objective-C中使用常量值,但现在为了升级代码,我想使用此扩展。
通知。名称在Objective-C中不存在。Objective-C类型通知名称
实际上只是一个NSString
。要在Objective-C中使用Swift stuff,该类必须在两者中都可用,并且不能是Swift结构(比如Notification
或String
)
因此,要实现您想要的功能,您需要有两个扩展:
- 一个用于Swift
通知。Name
,如您所述;以及
- 一个用于Objective-C对象(
NSString
,或者如果您愿意,也可以是NSNotification
)
1) 将Objective-C兼容的对象扩展名添加到Swift文件:
public extension NSNotification {
public static let blahblahblah: NSString = "blahblahblah"
}
注:在Swift 4中,为了与Objective-C兼容。这看起来像:
@objc public extension NSNotification {
public static var blahblahblah: NSString {
return "blahblahblah"
}
}
注意computed属性中的var
:computed属性不能是不可变的,因此不能使用let
2) 在Objective-C文件中,导入Xcode生成的Swift头文件(位于任何其他导入的下方):
注意:用项目的实际名称替换YourProjectName
。因此,如果您的项目名为“CoolGameApp”,Swift标题将为“CoolGameApp Swift.h”。如果项目名称中有空格,如“酷酷游戏应用”,请将其替换为破折号:“酷酷游戏应用Swift.h”
3) 重建项目
现在,您应该能够访问Objective-C中的扩展:
[[NSNotificationCenter defaultCenter] postNotificationName:NSNotification.blahblahblah object:self];
swift文件中的我的扩展名
extension Notification.Name {
static let purchaseDidFinish = Notification.Name("purchaseDidFinish")
}
@objc extension NSNotification {
public static let purchaseDidFinish = Notification.Name.purchaseDidFinish
}
@leanne的回答非常有用除了这里的答案之外,我还必须在我的Obj-C代码看到它之前将@objc添加到我的NSNotification扩展名中(Swift 4)。它对我有效。我试图使用@objc
,但它只能用于类和协议的成员,不能用于扩展。谢谢@leanne还有一件事,对于扩展NSNotification
,我使用了let
,而不是var
,它成功了。(显然,它应该可以工作)因此,如果存在常量字符串,则无需使用computed属性。我们甚至不需要公共静态
,只有扩展
应该是公共的;根据文件,Swift 4确实如此。使其成为静态意味着它在类上可用,而不需要实例。快乐编码!(确保点击复选标记,表明我的答案对您有效。)极好的解决方案!非常感谢^^但是,为了能够在objc代码中使用它,必须在第二个扩展名(NSNotification)上添加“@objc”,当然是由于swift 4 objc新的推理规则;)(正如@janineanne回答中提到的)polo987是正确的。构建设置中“Swift 3@objc推理”设置为OFF的项目如果要使用该属性,则需要“@objc”。默认情况下,将创建此设置为“关闭”的新项目。这是最佳解决方案。我甚至为我的通知添加了一个协议,Notification.Name扩展名和NSNotification扩展名都采用了该协议。这让我知道我的通知肯定可以用两种语言提供。事实上,在Xcode 10中,我得到“一些对象文件具有不兼容的Objective-C类别定义。一些类别元数据可能会丢失。所有包含Objective-C类别的文件都应该使用相同的编译器生成。”通知时出现扩展警告。
extension Notification.Name {
static let purchaseDidFinish = Notification.Name("purchaseDidFinish")
}
@objc extension NSNotification {
public static let purchaseDidFinish = Notification.Name.purchaseDidFinish
}
// OBJECTIVE-C
#import YourProjectName-Swift.h
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(purchaseDidFinish) name:NSNotification.purchaseDidFinish object:nil];
// SWIFT
NotificationCenter.default.addObserver(self, selector: #selector(purchaseDidFinish), name: .purchaseDidFinish, object: nil)
@objc func purchaseDidFinish(notification: Notification) {
print("purchaseDidFinish")
}