目标是编写一个Swift插件,它可以访问Objective-C NSDocument子类的公共实例属性。主要应用是Objective-C。这个插件只是Swift。
主应用程序有一个公共的Objective-C文档界面:
@interface ObjcNSDocument : NSDocument
@property (nonatomic, readwrite) NSString *markdown;
@property (nonatomic, readonly) NSString *html;
@end
合理的Swift对手似乎是:
public class SwiftNSDocument: NSDocument {
public var markdown: String = ""
public var html: String = ""
}
以下Swift代码检索当前的NSDocument OK。然而,铸造失败。
public func doFilter() {
let dc = NSDocumentController.shared()
if let document: NSDocument = dc.currentDocument {
print("document.displayName = \(document.displayName)") // works OK
let markdownSource = document as! SwiftNSDocument // FAIL: cannot cast as
}
}
虽然我问这是一般性的,但我的特定测试用例是尽可能接近纯粹的Swift重写macdown-gistit Objective-C插件。
理想情况下,解决方案不需要包含应用程序中的任何Objective-C代码。什么是可能的,即使不理想?
补充观察
对于正在运行的Objective-C插件,应用程序的NSDocument子类.h
文件在插件项目中不包含。
相反,Objective-C插件只有一个相关属性作为NSObject子类。
@protocol MarkdownSource <NSObject>
@property (readonly) NSString *markdown;
@end
然后将NSDocument作为Objective-C中的NSObject子类进行向下转换:
id<MarkdownSource> markdownSource = (id)document;
NSString *markdown = markdownSource.markdown;
理论上,人们会认为类似的东西可能在Swift中起作用,如
public class MarkdownSource: NSObject {
public var markdown: String = ""
}
其中Object-C中的id
将是Swift Any
。我尝试了各种向下广播,例如:
let markdownSource: MarkdownSource = (nsdocument as Any) as MarkdownSource
let markdown: String = markdownSource.markdown
到目前为止,我还没有能够将NSDocument子类转发到任何NSObject子类,只有Swift中的一个所需属性。