首页 > 解决方案 > 将 ClassKit 协议合并到 Objective-C++ 项目中

问题描述

我正在尝试将 Apple Classroom Manager 的 ClassKit 合并到 Xcode 10.0 和 ios 11.4 下的现有 Objective-C++ 应用程序中,并且在使用 Xcode 生成的快速桥接头 MyProject-Swift.h 时遇到问题,无法识别 ClassKit 协议 CLSDataStoreDelegate。

CLSDtaStoreDelegate 继承自 NSObjectProtocol,文档说这是所有 Objective-C 对象的基础,并以 NSObjectProtocol 的名称导入到 Swift 中。(不清楚“导入 Swift”是什么意思——它是在制作同名的 Objective-C 协议的 swift 版本吗?)

CLSDataStoreDelegate 在 Swift 文件 MenuLibrary.swift 中声明:

@objcMembers
class MenuLibrary : NSObject, CLSDataStoreDelegate
{
    @objc
    static var mShared = MenuLibrary()

    @objc
    var mArrMainTopics : [MainTopic] = []

    override init()
    {
        super.init()
    }
...
}


class dummySwiftClass : NSObject
{
    required init (coder aDecoder : NSCoder)
    {
        fatalError ("init (coder:) has not been implemented")
    }
}

如果将桥接头导入到 Objective-C++ .mm 文件中,则会发生错误,即使 .mm 文件没有 swift 代码也是如此。

// AppDelegate.mm

#import "MyProject-Swift.h"

xcode 生成的 Swift 桥接头中的相关结果是:

@class CLSContext;

SWIFT_CLASS("_TtC15ObjectiveC_Test11MenuLibrary")
@interface MenuLibrary : NSObject <CLSDataStoreDelegate>
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) MenuLibrary * _Nonnull mShared;)
+ (MenuLibrary * _Nonnull)mShared SWIFT_WARN_UNUSED_RESULT;
+ (void)setMShared:(MenuLibrary * _Nonnull)value;
@property (nonatomic, copy) NSArray<MainTopic *> * _Nonnull mArrMainTopics;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
- (CLSContext * _Nullable)createContextForIdentifier:(NSString * _Nonnull)identifier parentContext:(CLSContext * _Nonnull)parentContext parentIdentifierPath:(NSArray<NSString *> * _Nonnull)parentIdentifierPath SWIFT_WARN_UNUSED_RESULT;
@end

SWIFT_CLASS("_TtC15ObjectiveC_Test15dummySwiftClass")
@interface dummySwiftClass : NSObject
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
+ (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable");
@end

错误发生在第四行,其中 CLSDataStoreDelegate 为:“AppDelegate.mm 包含的文件中没有名为 'CLSDataStoreDelegate' MyProject-Swift.h 的类型或协议”。

其他帖子已列出在协议声明中添加“@objc”,但 CLSDataStoreDelegate 是 ClassKit 的一部分,我无权访问。我尝试对它进行子类化,但这没有用。

似乎桥接头包含所有 Swift 类,即使它们没有“@objc”属性或函数,如 dummySwiftClass 和其他未列出的类所证明的那样。这可能是尝试划分 Swift 文件的问题。我还发现桥接头无法识别 swift 文件中的结构和枚举。

如果从 MenuLibrary 中删除“CLSDataStoreDelegate”,我可以从 Objective-C++ .mm 文件访问 Swift 类中的属性和函数,但如果我要将 ClassKit 与 Objective-C++ 文件一起使用,则委托是必需的。看起来 ClassKit 的设计考虑了纯 Swift 项目,但是将我的应用程序完全翻译成 Swift 是令人望而却步的。

任何帮助,将不胜感激。

标签: objective-cswiftxcodeprotocolsobjective-c++

解决方案


推荐阅读