Мутирующая функция вызова протокола генерирует ошибку «не имеет члена имя-функции» - PullRequest
0 голосов
/ 23 декабря 2018

Вот мой протокол:

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.")
            }
        }
    }
}

Когда я вызываю функцию 'handleLoad' в моем классе View, он прекрасно компилируется.Но когда я вызываю его из фиктивной структуры, это дает мне такую ​​ошибку: "Значение типа '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()
        }
    }
}

Когда я меняю свою реализациючтобы быть классом вместо структуры и удалить мутировавшее слово, оно также отлично работает.Я пытался искать похожие ошибки, но мне не повезло.Я использую Xcode 10.1 и использую Swift Compiler 4.2.

Любые мысли по этому поводу приветствуются.

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

После более внимательного изучения этой проблемы я понимаю, что пытаюсь назвать мутирующую функцию постоянным значением (let), и поэтому она не работает.Проблема здесь заключалась в том, что компилятор выдавал ошибку, не связанную со смыслом.Я изменил свою собственность с let на var, и теперь она работает.

0 голосов
/ 23 декабря 2018

presenter является необязательным (даже неявное развертывание необязательным является необязательным), вы должны добавить вопросительный знак для необязательного сцепления

func callPresenterHandleLoad() {
    self.presenter?.handleLoad(for: self)
}

Но ошибка вводит в заблуждение, теперь вы получаете реальноеошибка

Невозможно использовать мутирующий член в неизменяемом значении: «презентатор» является константой «let»

, поэтому вы должны объявить презентатора как var iable и - оченьрекомендуется - как обычно необязательно

private var presenter: RequestLocationAuthorizationPresenterProtocol?
...