Миграция с RACSignal на ReactiveSwift или RAC5
Я новичок в Swift, и поэтому я новичок в Reactive Cocoa v5 или Reactive Swift.
Ранее я использовал RACSignal с RAC 2.x, и мне нравилось делать что-то вроде этого:
- (RACSignal *)signalForGET:(NSString *)URLString parameters:(NSDictionary *)parameters {
return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
AFHTTPRequestOperation *op = [self GET:URLString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
[subscriber sendNext:responseObject];
[subscriber sendCompleted];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[subscriber sendError:error];
}];
return [RACDisposable disposableWithBlock:^{
[op cancel];
}];
}];
}
И вот мне очень понравилось, что он отменяет запрос на одноразовые, а также я мог отменить его вручную, позвонив dispose
метод по возвращаемому сигналу.
Я немного запутался во всем этом в Reactive Swift, например, в SignalProducers и т. Д.
Пожалуйста, дайте мне пример, как реализовать то же самое с новейшими версиями Swift / ReactiveSwift / ReactiveCocoa. Главное требование - иметь возможность отменить запрос (или сигнал утилизации), где я хочу, и автоматически отменять запрос при утилизации.
1 ответ
Важная вещь, чтобы понять о Signal
а также SignalProducer
это различие между Hot
а также Cold
Сигналы.
В основном, Hot
Сигнал - это тот, который не заботится о своих наблюдателях. Он отправляет свои значения, независимо от того, есть ли у него один, несколько или вообще нет наблюдателя. И самое важное: новые наблюдения не вызывают побочных эффектов в сигнале, и каждый новый подписчик получит те же самые события, что и другие подписчики (за исключением тех, которые уже произошли до подписки!)! Подумайте о таких вещах, как ввод данных пользователем, данные датчика,... (игнорируя такие вещи, как запуск / остановка датчика).
По моему опыту, настоящий Hot
Сигналы на практике редки..
В отличие от Cold
Сигнал - это тот, который заботится о своих наблюдателях - каждая подписка на Cold
Сигнал потенциально выполняет побочный эффект, и подписчик получает события, основанные на этом побочном эффекте. Таким образом, два разных наблюдателя запускают побочный эффект один раз и получают разные наборы событий.
В RAC, Cold
Сигналы представлены SignalProducer
, Вы также можете подумать о SignalProducer
как фабрика сигналов (отсюда и название) - start
в SignalProducer
выполняет побочный эффект и возвращает Signal
на которые отправляются события.
Это в значительной степени то, что делает ваш фрагмент.
Disposable
С тех пор как RAC 2.x изменился не сильно, вы все равно можете его использовать. Вы, вероятно, только что пропустили, как использовать его при создании SignalProducer
:
func producerForGET(urlString: String, parameters: [String: String]) -> SignalProducer<Data, NSError> {
return SignalProducer<Data, NSError> { observer, disposable in
let operation = GET(url: urlString, parameters: parameters, success: { operation, responseObject in
observer.send(value: responseObject)
observer.sendCompleted()
}, failure: { error in
observer.send(error: error)
})
disposable += {
print("Disposed")
operation.cancel()
}
}
}
Вот быстрый пример того, как это можно использовать:
producerForGET(urlString: "Bla", parameters: [:])
.start() // Performs the request and returns a Signal
.dispose() // Runs the disposable block and cancels the operation