Дождитесь завершения делегата обратного вызова для завершения функции в Swift - PullRequest
0 голосов
/ 19 января 2019

У меня есть сторонний SDK, где архитектура выглядит следующим образом:

  • Я вызываю метод службы (давайте назовем его TheirService)
  • Как только этот метод завершитсяделегат этой службы (давайте позвоним TheirServiceDelegate получит уведомление onSuccess в случае успешного вызова или onFailure в случае сбоя.

Проблема в том, что методы TheirService зависят друг от друга, поэтому я в конечном итоге получаю «цепную реакцию», при которой каждый следующий метод TheirService вызывается из предыдущего обратного вызова.

Обратите внимание, что TheirService является однопоточным и действительноПривыкну, чтобы предыдущий метод был завершен до того, как я смогу запустить следующий.

В настоящее время мои взаимодействия со службой выглядят так:

protocol MyClientListener { 
    notifyOnFailure()
    notifyOnResult(result: SomeObject)
}

class MyClient: TheirServiceDelegate {

    static let instance = MyClient()

    let myService = TheirService()
    var myResult: SomeObject?
    var resultListener: MyClientListener

    private init() { }

    func start(resultListener: MyClientListener) {
        self.resultListener = resultListener
        myService.initialize()
    }

    // TheirServiceDelegate method
    func onInitializeSuccess() {
        myService.bootstrap()
    }

    // TheirServiceDelegate method
    func onBootstrapSuccess() {
        myService.login(user, password)
    }

    // TheirServiceDelegate method
    func onLoginSuccess() {
        myService.doSomethingUsefulStep1()
    }

    // TheirServiceDelegate method
    func onDoSomethingUsefulStep1Success() {
        myService.doSomethingUsefulStep2()
    }

    // TheirServiceDelegate method
    func onDoSomethingUsefulStep2Success(result: SomeObject) {
        // ah, look, now I have some object I actually wanted!
        resultListener.notifyOnResult(result)
    }
}

Мне также приходится иметь дело со случаем сбоя для каждогоиз них. И я не могу пропустить или изменить порядок шагов, что создает какой-то неуклюжий конечный автомат.

Вместо этого я хотел бы взаимодействовать со службой через логические функции, которые завершают определенные этапыпроцесс от начала до конца, ожидая результатов между шагами:

 class MyClient {

    static let instance = MyClient()

    let myService = MyService()

    private init() { }

    func connect() throws {
        myService.initialize()
        // wait for success or failure, throw on failure
        myService.bootstrap()
        // wait for success or failure, throw on failure
        myService.login(user, password)
        // wait for success or failure, throw on failure
    }

    func doSomethingUseful() -> SomeObject {
        myService.doSomethingUsefulStep1()
        // wait for success or failure, throw on failure
        myService.doSomethingUsefulStep2()
        // wait for success or failure, throw on failure
        // on success, it will get an object it could return
    }

Вызывается так:

try MyClient.instance.connect()
let x = try MyClient.instance.doSomethingUseful()

Так есть ли способ превратить комментарий «ждать успеха или неудачи»в реальный код, который ждет, чтобы этот однопоточный сервис перезвонил?И куда в таком случае поместится делегат?

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