源自Swift的obj-c类的类别

时间:2018-07-06 09:34:00

标签: ios objective-c swift

我正在运行带有objc和swift的大量旧代码的项目。 我一直在使用objc MPOldKeychainManager,现在不赞成使用它,而将使用swift的NewKeychainManager

问题如下:MPOldKeychainManager编写了一些类别,但我不想将它们重写为快速扩展。 我所做的是:

  • 将从NewKeychainManager(在“ myTarget-Swift.h”中可见)派生的类命名为“ MPOldKeychainManager
  • 删除MPOldKeychainManager的objc声明

...希望类别仍然有效。

objc(MPOldKeychainManager)
class NewKeychainManager: KeychainManager {
}

不幸的是,即使我已将导入的标头更新为MPOldKeychainManager

,旧扩展也看不到myTarget-Swift.h(从swift派生)
#import "myTarget-Swift.h" //previously - objc "MPOldKeychainManager.h"
@interface MPOldKeychainManager (Authentication)

问题:是否可以对从swift派生的objc类使用类别?

  • 我已经尝试了全新的命名方式
  • 我已经尝试了许多干净的构建

1 个答案:

答案 0 :(得分:1)

如果您还没有看到它,这里是一个有用的资源,可用于从Objective-C迁移到Swift:https://developer.apple.com/documentation/swift/migrating_your_objective_c_code_to_swift。除其他外,它指出不能在Objective-C中继承Swift类。您要尝试做的是为MPOldKeychainManager Swift类指定一个不同的Objective-C名称NewKeychainManager

实际上,如果您在objc之前添加一个&号,则可以正常工作,就像这样:

@objc(MPOldKeychainManager)
class NewKeychainManager: KeychainManager {
}

然后可以在Objective-C中使用所有现有的类别。但是,在Swift中使用它们会遇到问题,因为要在Swift中使用它们,它们必须在桥接标头中可用,并且您将无法使用类的Objective-C名称({{1} })。

但是,您可以编写一个Objective-C包装器类,该类将具有与每个类别方法相对应的方法,并且还采用MPOldKeychainManager指针。然后,包装方法可以委托给Objective-C代码可用的category方法,因此您不必在Swift中重新实现category方法。

比方说,Objective-C类别具有方法NewKeychainManager

authenticateUser:

该方法可以包装如下:

@interface MPOldKeychainManager (Authentication)

-(void)authenticateUser:(int32_t)uid;

@end

此接口声明必须可通过桥接头直接或间接使用。然后,可以在您的Objective-C代码中的某个地方实现包装器,如下所示:

@interface OldKCMWrapper : NSObject

+(void)authenticateUser:(int32_t)uid withManager:(NewKeychainManager*)inst;

@end

然后可以在Swift代码中使用包装器,例如:

@implementation OldKCMWrapper

+(void)authenticateUser:(int32_t)uid withManager:(MPOldKeychainManager*)inst {
    [inst authenticateUser:uid];
}

@end

实际上,包装器可以在let kcm = NewKeychainManager() OldKCMWrapper.authenticateUser(321, with: kcm) 的Swift扩展中使用。您仍将拥有一个Swift扩展,并具有与所有Objective-C类别方法等效的功能,但是您不必在Swift中重新实现它们的代码:扩展中的方法将简单地委派给包装器。

希望这会有所帮助。还有其他实现此想法的方法,可能更优雅。