这是我的协议:
protocol RequestLocationAuthorizationPresenterProtocol {
mutating func handleLoad(for view: RequestLocationAuthorizationViewProtocol)
func handleGivePermissionAction()
}
这是我的协议实现:
struct RequestLocationAuthorizationPresenter: RequestLocationAuthorizationPresenterProtocol {
private let interactor: RequestLocationAuthorizationInteractorProtocol
private let router: RequestLocationAuthorizationRouterProtocol
private weak var view: RequestLocationAuthorizationViewProtocol!
init(with interactor: RequestLocationAuthorizationInteractorProtocol,
router: RequestLocationAuthorizationRouterProtocol) {
self.interactor = interactor
self.router = router
}
mutating func handleLoad(for view: RequestLocationAuthorizationViewProtocol) {
self.view = view
}
func handleGivePermissionAction() {
self.interactor.requestAuthorization { result in
switch result {
case .success:
self.router.goToWeatherView()
case .error:
self.view.presentAlert(with: "Error", message: "The app needs your location in order to work.")
}
}
}
}
当我在View类上调用函数“ handleLoad”时,它可以完美编译。但是,当我从模拟结构调用它时,出现了以下错误:“类型为'RequestLocationAuthorizationPresenterProtocol?的值?没有成员'handleLoad'“
这是我的视图类:
class RequestLocationAuthorizationView: UIViewController {
private let presenter: RequestLocationAuthorizationPresenterProtocol
init(with presenter: RequestLocationAuthorizationPresenterProtocol) {
self.presenter = presenter
super.init(nibName: "RequestLocationAuthorizationView", bundle: .main)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func presentAlert(with title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
self.present(alert, animated: true, completion: nil)
}
@IBAction func givePermissionButtonPressed(_ sender: Any) {
self.presenter.handleGivePermissionAction()
}
}
这是我的模拟结构:
class RequestLocationAuthorizationViewMock: RequestLocationAuthorizationViewProtocol {
private let expectation: XCTestExpectation!
private let expectedTitle: String!
private let expectedMessage: String!
private let presenter: RequestLocationAuthorizationPresenterProtocol!
init(with expectation: XCTestExpectation? = nil,
expectedTitle: String? = nil,
expectedMessage: String? = nil,
presenter: RequestLocationAuthorizationPresenterProtocol? = nil) {
self.expectation = expectation
self.expectedTitle = expectedTitle
self.expectedMessage = expectedMessage
self.presenter = presenter
}
func callPresenterHandleLoad() {
self.presenter.handleLoad(for: self)
}
func callPresenterHandleGivePermissionAction() {
self.presenter.handleGivePermissionAction()
}
func presentAlert(with title: String, message: String) {
if title == self.expectedTitle && message == self.expectedMessage {
self.expectation.fulfill()
}
}
}
当我将实现更改为类而不是结构并删除 muting 字时,它也可以正常工作。我试图寻找类似的错误,但是我没有运气。我在使用Xcode 10.1并使用Swift Compiler 4.2。
欢迎对此问题发表任何想法。
答案 0 :(得分:0)
presenter
是可选的(即使隐式未包装的可选也是可选的),您也必须为可选链接添加一个问号
func callPresenterHandleLoad() {
self.presenter?.handleLoad(for: self)
}
但是错误有误导性,现在您得到了真正的错误
不能对不可变值使用变异成员:“ presenter”是一个“ let”常量
因此,您必须声明主持人为var
有效,并且-强烈建议-作为常规可选内容
private var presenter: RequestLocationAuthorizationPresenterProtocol?
答案 1 :(得分:0)
更仔细地研究这个问题之后,我意识到我正在尝试将一个变异函数称为一个常量值(let),这就是为什么它不起作用的原因。这里的问题是编译器给我一个无意义的错误。我将属性从let更改为var,现在可以使用了。