Combine에 있어 Operator은 Publisher 에게 받은 값을
가공해서 Subscriber 에게 제공하는 역할을 한다.
Built-in Operator가 많이 존재하는데, 그 중 몇가지를 사용해보았다.
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)
말 그대로 필터역할을 해주는 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")
최신의 데이터를 받아 튜플로 게시해주는 역할을 하는데
아래 사진을 보면 이해가 빠르다.
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)
위의 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")
병합해주는 역할을 하고, 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)")
}
단어 그래도 중복된 데이터를 제거해주는 것이다.
아래에서는 string문장을 공백기준으로 단어로 자르고,
중복된 단어를 지어주었다.
// removeDuplicates
let words = "hi hi my name is lee"
.components(separatedBy: " ")
.publisher
words
.removeDuplicates() // 반복 안받음
.sink { value in
print(value)
}.store(in: &subscriptions)
컨테이너의 각 요소를 호출할 때, 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(_:)