如何使 Swift class 符合 Objective-C 协议,而不将其暴露给 Objective-C?
How to make Swift class conform to Objective-C protocol, without exposing it to Objective-C?
我有一个名为 LoginCoordinator
的 Swift class,它执行“使用 Apple 登录”请求。为了响应回调,它符合 ASAuthorizationControllerDelegate
。由于这个要求,我还需要使这个 class 成为 NSObject
:
的子class
class LoginCoordinator: NSObject { ... }
extension LoginCoordinator: ASAuthorizationControllerDelegate { ... }
这个 class 根本不会被任何 Objective-C class 使用。它旨在供其他 Swift classes(即 LoginViewController
)使用,而 Objective-C classes
确实会使用它
问题如下。我最终通过以下方式将 top-level Swift classes 导入 Objective-C:
#import "MyProject-Swift.h"
这会导致生成的 MyProject-Swift.h
文件出现 compile-time 错误,内容为:
找不到 'ASAuthorizationControllerDelegate' 的协议声明;你是说 'UINavigationControllerDelegate'?
此错误出现在生成的 Objective-C 类别对应的行上,该类别对应于我上面在 Swift 中编写的扩展名,其中我使 LoginCoordinator
符合 ASAuthorizationControllerDelegate
.
如果在导入 MyProject-Swift.h
之前,我还导入了 <AuthenticationServices/AuthenticationServices.h>
,那么错误就会消失。但是我不想在我导入 Swift.
的任何地方导入它
如果我理解正确的话,发生的事情是这样的:当我将 Swift 文件导入 Objective-C 时,它会导入 MyProject-Swift.h
中生成的所有 headers .但是其中一个类别 headers (LoginCoordinator
) 引用了一个尚未导入的协议 (ASAuthorizationControllerDelegate
),这会引发错误。
我注意到 MyProject-Swift.h
只有在我将其设为 NSObject
的子 class 后才开始为 LoginCoordinator
生成代码。删除 subclassing 会删除生成的代码,但当然它不能符合协议。
有没有办法让 Swift class 成为 NSObject 的子 class 并符合 Objective-C 协议,而不在导入时暴露它 Swift 文件在 Objective-C?
您可以创建一个实际符合 ASAuthorizationControllerDelegate 的私有对象,并将消息转发给 LoginCoordinator。很丑,但是可以解决问题
class LoginCoordinator {
private lazy var authDelegate: LoginCordinatorASAuthorizationControllerDelegate {
LoginCordinatorASAuthorizationControllerDelegate(coordinator: self)
}
}
//MARK: functions from ASAuthorizationControllerDelegate, but not conforms it
extension LoginCoordinator {
private func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization....)
}
private class LoginCordinatorASAuthorizationControllerDelegate: NSObject, ASAuthorizationControllerDelegate {
weak var coordinator: LoginCoordinator!
init(coordinator: LoginCoordinator)
}
您还可以将您的 LoginCoordinator 设为嵌套的 class,它无法公开给 Objective-C。
enum Login {
class Coordinator: NSObject, ASAuthorizationControllerDelegate {...}
}
最简单的方法是添加
#import <AuthenticationServices/AuthenticationServices.h>
到 Objective-C 桥接头,即 MyProject-Swift.h
我有一个名为 LoginCoordinator
的 Swift class,它执行“使用 Apple 登录”请求。为了响应回调,它符合 ASAuthorizationControllerDelegate
。由于这个要求,我还需要使这个 class 成为 NSObject
:
class LoginCoordinator: NSObject { ... }
extension LoginCoordinator: ASAuthorizationControllerDelegate { ... }
这个 class 根本不会被任何 Objective-C class 使用。它旨在供其他 Swift classes(即 LoginViewController
)使用,而 Objective-C classes
问题如下。我最终通过以下方式将 top-level Swift classes 导入 Objective-C:
#import "MyProject-Swift.h"
这会导致生成的 MyProject-Swift.h
文件出现 compile-time 错误,内容为:
找不到 'ASAuthorizationControllerDelegate' 的协议声明;你是说 'UINavigationControllerDelegate'?
此错误出现在生成的 Objective-C 类别对应的行上,该类别对应于我上面在 Swift 中编写的扩展名,其中我使 LoginCoordinator
符合 ASAuthorizationControllerDelegate
.
如果在导入 MyProject-Swift.h
之前,我还导入了 <AuthenticationServices/AuthenticationServices.h>
,那么错误就会消失。但是我不想在我导入 Swift.
如果我理解正确的话,发生的事情是这样的:当我将 Swift 文件导入 Objective-C 时,它会导入 MyProject-Swift.h
中生成的所有 headers .但是其中一个类别 headers (LoginCoordinator
) 引用了一个尚未导入的协议 (ASAuthorizationControllerDelegate
),这会引发错误。
我注意到 MyProject-Swift.h
只有在我将其设为 NSObject
的子 class 后才开始为 LoginCoordinator
生成代码。删除 subclassing 会删除生成的代码,但当然它不能符合协议。
有没有办法让 Swift class 成为 NSObject 的子 class 并符合 Objective-C 协议,而不在导入时暴露它 Swift 文件在 Objective-C?
您可以创建一个实际符合 ASAuthorizationControllerDelegate 的私有对象,并将消息转发给 LoginCoordinator。很丑,但是可以解决问题
class LoginCoordinator {
private lazy var authDelegate: LoginCordinatorASAuthorizationControllerDelegate {
LoginCordinatorASAuthorizationControllerDelegate(coordinator: self)
}
}
//MARK: functions from ASAuthorizationControllerDelegate, but not conforms it
extension LoginCoordinator {
private func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization....)
}
private class LoginCordinatorASAuthorizationControllerDelegate: NSObject, ASAuthorizationControllerDelegate {
weak var coordinator: LoginCoordinator!
init(coordinator: LoginCoordinator)
}
您还可以将您的 LoginCoordinator 设为嵌套的 class,它无法公开给 Objective-C。
enum Login {
class Coordinator: NSObject, ASAuthorizationControllerDelegate {...}
}
最简单的方法是添加
#import <AuthenticationServices/AuthenticationServices.h>
到 Objective-C 桥接头,即 MyProject-Swift.h