SignalProducer не запускается в моем случае с использованием ReactiveSwift

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

func getAuthorizationCode() -> SignalProducer<String, MoyaError> {
    if let authCode = UserDefaults.string(forKey: .authorizationCode) {
        return SignalProducer(value: authCode)
    }

    let provider = ReactiveSwiftMoyaProvider<UserService>()
    return  provider.request(.authorization).flatMap(.concat) {
        response -> SignalProducer<String, Moya.MoyaError> in

        let json = JSON(data: response.data)
        log.debug("Authorization response:\(json) ")
        let authCode = json["authorizationcode"].stringValue
        return SignalProducer(value: authCode)
    }

}

getAuthorizationCode().start { событие в случае let .value(value): print(value) case let .failed(error): print(error) } Более того, если я хочу выполнить другой сетевой запрос, что мне делать? делать?

Любая помощь приветствуется.


person Alex Chan    schedule 04.05.2017    source источник
comment
Вы сами тестировали ReactiveSwiftMoyaProvider<UserService>, чтобы убедиться, что он работает?   -  person jjoelson    schedule 04.05.2017
comment
О, спасибо! Я нашел причину, provider был уничтожен после вызова функции. так что есть предложения, как увеличить срок службы SignalProducer?   -  person Alex Chan    schedule 05.05.2017
comment
Можете ли вы опубликовать некоторые подробности о том, как реализован ReactiveSwiftMoyaProvider? Что касается управления памятью, я думаю, что производитель, возвращенный из getAuthorizationCode(), должен сохранить производителя из provider.request(.authorization) через flatMap. Поэтому я думаю, что provider должен каким-то образом избавляться от производителя при деинициализации.   -  person jjoelson    schedule 05.05.2017
comment
Что ж, проверьте здесь: github.com/Moya/Moya/blob /master/Источники/ReactiveMoya/   -  person Alex Chan    schedule 05.05.2017
comment
Да, похоже, что производитель, возвращенный из provider.request(.authorization), слабо ссылается на поставщика, поэтому он может использовать его для запуска запроса. Я думаю, вам просто нужно держать провайдера в собственности. Если вы хотите поумничать, чтобы избежать использования сохраненного свойства, возможно, вы можете захватить его в этом закрытии flatMap, чтобы поддерживать его в рабочем состоянии, пока жив ваш SignalProducer.   -  person jjoelson    schedule 05.05.2017


Ответы (1)


Как обсуждалось в комментариях, provider необходимо поддерживать в рабочем состоянии, чтобы ваш SignalProducer работал. Чтобы избежать необходимости хранить provider где-то в переменной экземпляра, вы могли бы сделать то, что предлагает Мэтт Галлахер в это сообщение Cocoa with Love, в котором нужно поместить withExtendedLifetime(provider) {} где-нибудь в закрытие flatMap, чтобы сохранить provider живым, пока жив ваш продюсер. По сути, это просто способ сохранить provider без жалоб компилятора на неиспользуемую переменную.

person jjoelson    schedule 05.05.2017
comment
Здесь есть лучшее решение: github.com/ReactiveCocoa/ReactiveSwift/issues/358 - person Alex Chan; 11.05.2017
comment
Это лучше! Я понятия не имел, что вы можете просто использовать _ = ..., чтобы избежать предупреждения о неиспользуемом выражении. - person jjoelson; 11.05.2017