如何让Swift类继承NSObject并遵循Objective-C协议且不被Objective-C暴露?
这里有几个方法可以解决你的问题,最直接且贴合需求的是利用Swift的专属属性,让LoginCoordinator仅对Swift代码可见,同时保留它继承NSObject和遵循协议的能力:
方法1:用@available(swift, only: true)隐藏类
给你的LoginCoordinator类加上这个属性,它会告诉编译器:这个类只对Swift开放,不会被生成到自动导出的MyProject-Swift.h头文件里,自然也就不会被Objective-C代码感知到:
@available(swift, only: true) class LoginCoordinator: NSObject { // 你的类业务逻辑实现 } @available(swift, only: true) extension LoginCoordinator: ASAuthorizationControllerDelegate { // ASAuthorizationControllerDelegate协议方法实现 }
原理说明
这个属性不会影响Swift内部的代码访问——哪怕你的LoginViewController会被Objective-C调用,它依然能正常使用LoginCoordinator。同时因为类依然继承NSObject,完全可以正常遵循ASAuthorizationControllerDelegate协议,处理Sign In with Apple的回调逻辑。
方法2:全局导入协议头文件(临时 workaround)
如果你暂时不想修改Swift类的声明,也可以在Objective-C项目的**前缀头文件(.pch)**中添加#import <AuthenticationServices/AuthenticationServices.h>。这样所有Objective-C文件在导入MyProject-Swift.h时,都会自动包含这个协议的声明,编译错误就会消失。不过这个方法只是绕过了错误,并没有真正隐藏LoginCoordinator类。
方法3:私有基类封装协议遵循
你还可以创建一个私有基类来实现ASAuthorizationControllerDelegate协议,再让LoginCoordinator继承这个基类。私有基类不会被暴露给Objective-C,搭配@available(swift, only: true)可以进一步隔离Objective-C的访问:
private class _AppleLoginDelegateBase: NSObject, ASAuthorizationControllerDelegate { // 实现协议的必要方法 func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { // 基础实现或留给子类重写 } func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) { // 基础实现或留给子类重写 } } @available(swift, only: true) class LoginCoordinator: _AppleLoginDelegateBase { // 你的业务逻辑,可按需重写基类的协议方法 }
这个方法能把协议遵循的细节封装起来,让LoginCoordinator的对外接口更简洁。
内容的提问来源于stack exchange,提问作者haskel-lightricks

