-
Ch3. Transforming OperatorsRay Wenderlich/Combine 2021. 1. 27. 20:26
collect()
["A", "B", "C", "D", "E"].publisher .collect() .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) .store(in: &subscriptions) // collect에 parameter전달하여 메모리 과다사용 방지 ["A", "B", "C", "D", "E"].publisher.collect(3) .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) .store(in: &subscriptions)
["A", "B", "C", "D", "E"] finished ["A", "B", "C"] ["D", "E"] finished
map(_:)
let formatter = NumberFormatter() formatter.numberStyle = .spellOut [123, 4, 56].publisher .map { formatter.string(for: NSNumber(integerLiteral: $0)) ?? "" } .sink(receiveValue: { print($0) }) .store(in: &subscriptions)
one hundred twenty-three four fifty-six
Map key paths
map<T>(_*:)
*map<T0, T1>(_:_:)
**map<T0, T1, T2>(_:_:_:)
let publisher = PassthroughSubject<Coordinate, Never>() publisher .map(\\.x, \\.y) .sink(receiveValue: { x, y in print( "The coordinate at (\\(x), \\(y)) is in quadrant", quadrantOf(x: x, y: y) ) }) .store(in: &subscriptions) publisher.send(Coordinate(x: 10, y: -8)) publisher.send(Coordinate(x: 0, y: 5))
The coordinate at (10, -8) is in quadrant 4 The coordinate at (0, 5) is in quadrant boundary
tryMap(_:)
Just("Directory name that does not exist") .tryMap { try FileManager.default.contentsOfDirectory(atPath: $0) } .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) .store(in: &subscriptions)
failure(Error Domain=NSCocoaErrorDomain Code=260 "The folder “Directory name that does not exist” doesn’t exist." UserInfo={NSUserStringVariant=( Folder ), NSFilePath=Directory name that does not exist, NSUnderlyingError=0x600003ab2cd0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}})
Flatterning publishers
func decode(_ codes: [Int]) -> AnyPublisher<String, Never> { Just( codes .compactMap { code in guard (32...255).contains(code) else { return nil } return String(UnicodeScalar(code) ?? " ") } .joined() ) .eraseToAnyPublisher() } [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33] .publisher .collect() .flatMap(decode) .sink(receiveValue: { print($0) }) .store(in: &subscriptions)
Hello, World!
Source publisher가 너무 많으면 메모리 낭비 가능성이 있음
그래서 maxPublishers에 2를 넣었더니 P3은 전달이 안되는 것을 볼 수 있다.
replaceNil(with:)
["A", nil, "C"].publisher .eraseToAnyPublisher() .replaceNil(with: "-") // .replaceNil(with: "-" as String?) causes error. cannot return optional .sink(receiveValue: { print($0) }) .store(in: &subscriptions) let tmp = ["A", nil, "C"].publisher .eraseToAnyPublisher() .replaceNil(with: "-")
A - C
replaceEmpty(with:)
let empty = Empty<Int, Never>() // 2 empty .replaceEmpty(with: 1) .sink(receiveCompletion: { print($0) }, receiveValue: { print($0) }) .store(in: &subscriptions)
1 finished
scan(_:_:)
var dailyGainLoss: Int { .random(in: -10...10) } // 2 let august2019 = (0..<22) .map { _ in dailyGainLoss } .publisher // 3 august2019 .scan(50) { latest, current in max(0, latest + current) } .sink(receiveValue: { _ in }) .store(in: &subscriptions)
Key points
Publisher
의 output으로 특정 기능을 수행하는 메소드를 Operator라고 한다.- Operator 또한
Publisher
이다. - Transforming Operator는 Upstream publisher에게 값을 받아 변환한 뒤, Downstream publisher에 전달한다.
collect()
,flatMap()
과 같이 버퍼에 데이터가 쌓이는 operator는 신경 잘 써주셈- Swift의 Transform메소드와 비슷한것들이 Combine에 있으니까 참고하자. Ex)
map
,flatMap
- 여러개의 Operator를 체이닝하여 사용할 수 있다.
'Ray Wenderlich > Combine' 카테고리의 다른 글
Ch5. Combining Operators (0) 2021.02.12 Ch4. Filtering Operators (0) 2021.02.12 Ch2. Publishers & Subscribers (0) 2021.01.27 Ch1. Hello, Combine! (0) 2021.01.27