我试图从API设计的角度来思考,因为最终我想把代码发布给我自己或其他人。
让我们做一些假设,以获得一个简洁的场景。我们假设我有一些代码,它通过我的服务器进行身份验证并返回一个user对象。简单地定义如下:
public struct User: Codable {
public let id: UUID
public let email: String
public let name: String
}我将这段代码作为SDK发布给自己或第三方,在那里所有AUTH的核心都会得到处理。使用Apples新的组合框架,我可能会像这样向我的SDK的消费者公开一个发布者。
public enum CurrentUserError: Error {
case loggedOut
case sessionExpired
}
public struct MyAuthFrameworkPublishers {
static let currentUser: CurrentValueSubject<User?, CurrentUserError> = CurrentValueSubject<User?, CurrentUserError>(nil)
}现在,我的私有身份验证可以完成它的任务并检索用户,然后将其发布到SDK之外的任何它监听的内容,如下所示:
class AuthController {
func authenticate() {
///Get authenticated user.
let user = User.init(id: UUID(), email: "some@some.com", name: "some")
MyAuthFrameworkPublishers.currentUser.send(user)
}
}
let authController = AuthController.init()
authController.authenticate()有没有办法阻止这个SDK的用户向发布者发送它自己的User对象?比如combine中的私有或访问控制器.send()函数?
发布于 2020-05-15 09:06:27
您真的想使用CurrentUserError作为您的Failure类型吗?发送失败将终止对主题的所有订阅,并立即使新订阅失败。如果会话过期,您不想让用户重新登录吗?这将需要发布另一个User?输出,如果您发布了一个失败的输出,则不能这样做。
相反,使用Result<User?, CurrentUserError>作为Output类型,使用Never作为Failure类型。
现在,让我们来回答你的问题。通常,防止用户调用send的方法是提供AnyPublisher而不是Subject
public class AuthController {
public let currentUser: AnyPublisher<Result<User?, AuthenticationError>, Never>
public func authenticate() {
let user: User = ...
subject.send(user)
}
public init() {
currentUser = subject.eraseToAnyPublisher()
}
private let subject = CurrentValueSubject<Result<User?, AuthenticationError>, Never>(nil)
}https://stackoverflow.com/questions/61808451
复制相似问题