반응형
Swift Combine이란?
애플이 WWDC 2019에서 공개한 Combine은 비동기 이벤트 처리를 위한 프레임워크입니다. 기존의 NotificationCenter, KVO(Key-Value Observing), Completion Handler, Delegation 방식과 달리, Combine을 활용하면 선언형(Declarative) 방식으로 데이터를 처리할 수 있습니다.
Combine의 핵심 개념
Publisher와 Subscriber
- Publisher: 데이터를 방출하는 역할을 합니다.
- Subscriber: 데이터를 받아서 처리하는 역할을 합니다.
- 예제 코드:위 코드에서 Just는 단일 값을 방출하는 Publisher이며, sink는 Subscriber 역할을 합니다.
import Combine
let myPublisher = Just("Hello, Combine!")
let mySubscriber = myPublisher.sink { value in
print(value)
}
Operator
- Combine에는 다양한 연산자(Operator)가 존재하여 데이터 변환, 필터링 등을 수행할 수 있습니다.
- 예제 코드:
import Combine
let numbers = [1, 2, 3, 4, 5]
let publisher = numbers.publisher
let subscription = publisher
.map { $0 * 2 }
.filter { $0 > 5 }
.sink { value in
print(value) // 6, 8, 10 출력
}
Subject
- PassthroughSubject와 CurrentValueSubject가 있으며, 직접 값을 방출할 수 있습니다.
- 예제 코드:
import Combine
let subject = PassthroughSubject<String, Never>()
let subscription = subject.sink { value in
print("받은 값: \(value)")
}
subject.send("안녕하세요!")
subject.send("Combine 예제입니다!")
Combine을 활용한 비동기 처리
URLSession과 Combine
import Combine
import Foundation
let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")!
let cancellable = URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: Post.self, decoder: JSONDecoder())
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("완료!")
case .failure(let error):
print("오류 발생: \(error)")
}
}, receiveValue: { post in
print("받은 데이터: \(post)")
})
struct Post: Codable {
let userId: Int
let id: Int
let title: String
let body: String
}
모듈 간 데이터 전달
import Combine
class DataProvider {
let dataPublisher = PassthroughSubject<String, Never>()
}
class DataReceiver {
var cancellables = Set<AnyCancellable>()
func subscribe(to provider: DataProvider) {
provider.dataPublisher
.sink { data in
print("받은 데이터: \(data)")
}
.store(in: &cancellables)
}
}
let provider = DataProvider()
let receiver = DataReceiver()
receiver.subscribe(to: provider)
provider.dataPublisher.send("새로운 데이터 도착!")
SwiftUI와 Combine 연동 (계산기 예제)
import SwiftUI
import Combine
class CalculatorViewModel: ObservableObject {
@Published var input: String = ""
@Published var result: String = "0"
private var cancellables = Set<AnyCancellable>()
init() {
$input
.map { self.calculate(expression: $0) }
.assign(to: &$result)
}
func appendValue(_ value: String) {
input += value
}
func clear() {
input = ""
result = "0"
}
private func calculate(expression: String) -> String {
let exp = NSExpression(format: expression)
if let value = exp.expressionValue(with: nil, context: nil) as? Double {
return String(format: "%.2f", value)
}
return "Error"
}
}
struct CalculatorView: View {
@StateObject var viewModel = CalculatorViewModel()
let buttons: [[String]] = [
["7", "8", "9", "/"],
["4", "5", "6", "*"],
["1", "2", "3", "-"],
["0", ".", "=", "+"]
]
var body: some View {
VStack {
Text(viewModel.result)
.font(.largeTitle)
.padding()
ForEach(buttons, id: \ .self) { row in
HStack {
ForEach(row, id: \ .self) { button in
Button(action: {
if button == "=" {
viewModel.input = viewModel.result
} else {
viewModel.appendValue(button)
}
}) {
Text(button)
.font(.title)
.frame(width: 80, height: 80)
.background(Color.gray.opacity(0.2))
.cornerRadius(10)
}
}
}
}
Button("Clear") {
viewModel.clear()
}
.font(.title)
.padding()
}
}
}
Combine은 비동기 데이터 흐름을 쉽게 관리할 수 있도록 해주는 강력한 프레임워크입니다.
반응형
'클라이언트' 카테고리의 다른 글
[GameKit] 간단한 가위바위보 멀티게임 만들기 (0) | 2025.02.16 |
---|---|
[iOS] iOS 앱 리버싱 간단한 예제 (0) | 2025.02.16 |
[iOS] iOS 앱 보안을 위한 최적화 방법 (0) | 2025.02.16 |
[iOS][Swift] iOS Swift에서 사용할 수 있는 암호화 방식 (0) | 2025.02.16 |
[iOS] UserDefaults 동작 방식과 보안 (0) | 2025.02.15 |