Указание связанного типа в дочернем протоколе - PullRequest
0 голосов
/ 27 февраля 2019

Есть ли способ определить связанный тип в дочернем протоколе и затем использовать дочерний протокол в качестве типа iVar?

Это то, что мне нужно для достижения:

protocol Coordinator {
    associatedtype ResultValue
    associatedtype ResultError

    func start(completion: @escaping (Result<ResultValue, ResultError>) -> Void)
}

protocol DownloadPermissionCoordinator: Coordinator {
    associatedtype ResultValue = String
    associatedtype ResultError = DownloadPermissionCoordinatorError
}

protocol SomeOtherCoordinator: Coordinator {
    associatedtype ResultValue = Int
    associatedtype ResultError = SomeOtherCoordinatorError
}

И затем, чтобы иметь возможность использовать его следующим образом:

final class MyTestClass {
    private let downloadPermissionCoordinator: DownloadPermissionCoordinator
    private let someOtherCoordinator: SomeOtherCoordinator

    init(downloadPermissionCoordinator: DownloadPermissionCoordinator,
         someOtherCoordinator: SomeOtherCoordinator) {
        self.coordinator = coordinator
        self.someOtherCoordinator = someOtherCoordinator
    }
}

Как вы можете себе представить, Swift не считает, что мои дочерние протоколы-координаторы могут использоваться в качестве ограничений типа.

Изменение этогокак это:

protocol Coordinator2 {
    func start<ResultValue, ResultError>(completion: @escaping (Result<ResultValue, ResultError>) -> Void)
}

К сожалению, не служит цели.

Я пытаюсь избежать делегата по конкретным протоколам координатора, но не похоже, что я могу иметьобщее закрытие.Любые предложения?

ps Просто для иллюстрации использования координатора я добавил ниже неполный код

final class DownloadPermissionCoordinatorImpl: DownloadPermissionCoordinator {
    private let rootViewController: UIViewController
    private let userPermissionService: UserPermissionService

    init(rootViewController: UIViewController,
         userPermissionService: UserPermissionService) {
        self.rootViewController = rootViewController
        self.userPermissionService = userPermissionService
    }

    func start(completion: @escaping (Result<String, ()>) -> Void) {
        guard !userPermissionService.allowsCelularDownload else {
            completion(.success)
            return
        }

        let alertController = ...
        rootViewController.present(alertController, animated: true, completion: nil)
    }
}

extension MyTestClass {
    func doStuffIfAllowed() {
        downloadPermissionCoordinator.start { result in
            switch result {
            case .success: download()
            case .failure: dismiss()
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...