다양한 Combine Operator 사용해보기

이재영·2023년 1월 24일
0

what is operator?

Combine에 있어 OperatorPublisher 에게 받은 값을
가공해서 Subscriber 에게 제공하는 역할을 한다.
Built-in Operator가 많이 존재하는데, 그 중 몇가지를 사용해보았다.


map

publisher의 모든 요소를 transform, 변환해준다.
데이터를 받아 2배해준 값을 출력해주었다.

// Transform - Map
let numPublisher = PassthroughSubject<Int, Never>()
let sub = numPublisher
    .map { $0 * 2 }
    .sink { value in
        print("Transformed value: \(value)")
    }

numPublisher.send(1)
numPublisher.send(2)



filter

말 그대로 필터역할을 해주는 Operator이다.
받은 문자열중 a라는 문자가 있는 데이터만 출력해주도록 filter처리 하였다.

// Filter
let stringPublisher = PassthroughSubject<String, Never>()
let sub2 = stringPublisher
    .filter { $0.contains("a")}
    .sink { value in
        print("Filtered value: \(value)")
    }

stringPublisher.send("abc")
stringPublisher.send("bcd")
stringPublisher.send("cdea")



CombineLatest

최신의 데이터를 받아 튜플로 게시해주는 역할을 하는데
아래 사진을 보면 이해가 빠르다.

let strPublisher = PassthroughSubject<String, Never>()
let intPublisher = PassthroughSubject<Int, Never>()
 
strPublisher.combineLatest(intPublisher).sink { (str, num) in
    print("Received : \(str), \(num)")
}

strPublisher.send("a")
intPublisher.send(1)
strPublisher.send("b")
strPublisher.send("c")
intPublisher.send(2)



Advanced CombineLatest

위의 combine latest 성질을 이용하여 간단한 로그인시스템을 작성한 것이다.
사용자의 비밀번호 자리가 12자리가 넘어야 valid하게 해주었다.

let usernamePublisher = PassthroughSubject<String, Never>()
let passwordPublisher = PassthroughSubject<String, Never>()

let validSubscription = usernamePublisher.combineLatest(passwordPublisher)
    .map { username, password in
        return !username.isEmpty && !password.isEmpty && password.count > 12
    }
    .sink { valid in
        print("is it valid? : \(valid)")
    }

usernamePublisher.send("jaylee")
passwordPublisher.send("aaaa1234eeeee")



Merge

병합해주는 역할을 하고, Publisher의 데이터 타입이 같아야한다.
아래는 두개의 publisher를 merge 한 것이다.


let publisher1 = [1, 2, 3, 4, 5].publisher
let publisher2 = [300, 400, 500].publisher

let mergePublisher = publisher1.merge(with: publisher2)
    .sink { value in
        print("Merge : subscription received value : \(value)")
    }



removeDuplicates

단어 그래도 중복된 데이터를 제거해주는 것이다.
아래에서는 string문장을 공백기준으로 단어로 자르고,
중복된 단어를 지어주었다.


// removeDuplicates
let words = "hi hi my name is lee"
    .components(separatedBy: " ")
    .publisher

words
    .removeDuplicates() // 반복 안받음
    .sink { value in
        print(value)
    }.store(in: &subscriptions)



compactMap

컨테이너의 각 요소를 호출할 때, nil 이 아닌 배열을 반환한다.
아래에서는 컨테이너 중 실수인 요소만 받아 처리하는 것을 작성하였다.

// compactMap
let lists = ["a", "123", "dce", "0.52"].publisher

lists
    .compactMap { Float($0) }
    .sink { value in
        print(value)
    }.store(in: &subscriptions)





참고자료 및 사이트 https://rhammer.tistory.com/311
https://developer.apple.com/documentation/combine/just/combinelatest(_:)
https://sujinnaljin.medium.com/combine-advanced-combining-operator-1ee9928bc873
https://developer.apple.com/documentation/swift/sequence/compactmap(_:)

profile
기록

0개의 댓글