Как реализовать продвинутый шаблон координатора в Swift - PullRequest
0 голосов
/ 20 ноября 2019

Мы находимся в процессе миграции проект Obj-C для Swift, и мы пытаемся сохранить тот же уровень функциональности в то же время пытается сделать что-то в более Свифта-подобным же образом.

1002 *Мы широко используем шаблон координат, но у меня возникают проблемы при его создании. Основной проблемой является возможность вызывать делегат в рамках реализации базовой. 1004 * Class Based Solution 1006 * Ниже на основе координатор класса, который является реализацией Swift координатора Obj-C мы. использовали 1008 * Протокол:
protocol CoordinatorDelegate: class {
    func coordinatorDidCancel(_ coordinator: Coordinator)
    func coordinatorWillCancel(_ coordinator: Coordinator)
}

Класс:

class Coordinator {

    weak var delegate: CoordinatorDelegate?

    private(set) var navigationController: UINavigationController
    private(set) var childCoordinators: [Coordinator]

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
        self.childCoordinators = []
    }

    func start() {}

    func tearDown() {}

    final func cancel() {

        // Here we call the delegate from within the base class
        delegate?.coordinatorWillCancel(self)

        tearDown()

        cancelChildCoordinators()

        // And here
        delegate?.coordinatorDidCancel(self)

        delegate = nil

    }

    final func cancelChildCoordinators() {
        childCoordinators.forEach { childCoordinator in
            childCoordinator.cancel()
            removeChildCoordinator(childCoordinator: childCoordinator)
        }
    }

    final func addChildCoordinator(childCoordinator: Coordinator) {
        childCoordinators.append(childCoordinator)
    }

    final func removeChildCoordinator(childCoordinator: Coordinator) {
        childCoordinators = childCoordinators.filter { $0 !== childCoordinator }
    }

В нашей реализации Obj-C, когда мы подклассы наш координатор мы можем переопределить наш delegateследующим образом:

@property (nonatomic, weak) NSObject <ContentCoordinatorDelegate, CoordinatorDelegate> *delegate;

Теперь в нашем подклассе мы можем вызывать любые методы, объявленные в ContentCoordinatorDelegate И методы в CoordinatorDelegate. Однако, как мы не можем изменить тип переопределенных собственностей в Swift, мы не можем делать вещи таким образом:

Свойство «делегатом» с типом 'ContentCoordinatorDelegate? не может переопределить свойство с типом 'CoordinatorDelegate?

Протокол на основе решения

1028 * Я понимаю, что все учебники из там пользователя протокол, основанный решение, поэтому я попытался это тоже. К сожалению, это не работает для нас либо по той же самой причине, мы должны определить тип делегата в координатору, но тогда мы не можем изменить этот тип в нашей реализации.

Другие варианты

1032 *Я исследовал, используя связанные типы, но не смог получить эту работу из-за ошибки:

«координатор» протокол может быть использован только в качестве общего ограничения, так как он Сам, или связанные с ними требования типа

1038 * Я также попытался использовать дженерики, но получил ошибку:

Тип протокола «ContentCoordinatorDelegate» не может соответствовать «CoordinatorDelegate», потому что только конкретные типы могут соответствовать протоколам

1043*

у меня есть подозрение, что я что-то очевидное здесь, но любая помощь будет оценена отсутствует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...