ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Ch3. Transforming Operators
    Ray 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
Designed by Tistory.