Combine
3PassthroughSubject ve CurrentValueSubject:
PassthroughSubject:
- Bu tür, abonelere değerlerin passthrough edilmesini sağlar. Yani, abone olmadan önce yayıncıya gönderilen değerler, abone olduktan sonra abonelere iletilir.
- send yöntemi kullanılarak değerler yayınlanır.
- Başlangıç değeri yoktur. İlk abone değer yayınlanana kadar hiçbir değer iletilmez.
- Aboneler, yayıncıdan alınan tüm değerlere maruz kalır.
- Birden fazla abone, aynı anda yayıncıdan gelen değerleri alabilir.
import Combine
let subject = PassthroughSubject<String, Never>()
let subscription1 = subject.sink { value in
print("Subscription 1 received value: \(value)")
}
subject.send("Hello")
let subscription2 = subject.sink { value in
print("Subscription 2 received value: \(value)")
}
subject.send("World”)
Ciktilar:
Subscription 1 received value: Initial Value
Subscription 2 received value: Initial Value
Subscription 1 received value: Hello
Subscription 2 received value: Hello
CurrentValueSubject:
- Bu tür, bir başlangıç değeriyle birlikte değerler yayınlar. İlk aboneden önce yayınlanan değerler başlangıç değeri olarak kabul edilir.
- sendyöntemi kullanılarak değerler yayınlanır.
- Bir başlangıç değeri vardır ve bu değer, ilk abone olmadan önce değiştirilebilir.
- Yalnızca en son yayınlanan değer son aboneye iletilir.
- Yalnızca bir abone, en son değeri alabilir.
import Combine
let subject = CurrentValueSubject<String, Never>("Initial Value")
let subscription1 = subject.sink { value in
print("Subscription 1 received value: \(value)")
}
subject.send("Car")
let subscription2 = subject.sink { value in
print("Subscription 2 received value: \(value)")
}
subject.send("Hi”)
Ciktilar:
Subscription 1 received value: Initial Value
Subscription 1 received value: Car
Subscription 2 received value: Car
Subscription 1 received value: Hi
Subscription 2 received value: Hi
import Combine
// Future'u tanımlama
let futureValue = Future<String, Error> { promise in
DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
promise(.success("Hello from the future!"))
}
}
// Future'u abone olmadan yayınlama
futureValue.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("Future value published successfully.")
case .failure(let error):
print("Error publishing future value: \(error)")
}
}, receiveValue: { value in
print("Received future value: \(value)")
})
// Abone olduktan sonra Future değerini yayınlama
futureValue.sink(receiveCompletion: { completion in
switch completion {
case .finished:
print("Future value published successfully.")
case .failure(let error):
print("Error publishing future value: \(error)")
}
}, receiveValue: { value in
print("Received future value: \(value)")
})
Future'ın kullanım alanları
- Asenkron İşlemler: Future, genellikle asenkron işlemlerde kullanılır. Örneğin, ağ isteği yapmak, dosya okuma/yazma işlemleri gibi uzun süren işlemler sonucunda bir değer elde etmek için Future kullanılabilir. Bu, ana iş parçacığını bloke etmeden ve iş parçacığını boşa harcamadan asenkron olarak çalışmaya olanak tanır.
- Zamanlayıcılar: Belirli bir süre sonra bir değer yayınlamak gerektiğinde Future kullanılabilir. Örneğin, bir zamanlayıcı başlatmak ve belirli bir süre sonra belirli bir değeri yayınlamak için Future kullanılabilir.
- Gelecekte Gerçekleşecek Değerler: Bir değerin gelecekte, belirli bir zamanda veya bir olayın gerçekleşmesiyle yayınlanması gerekiyorsa Future kullanılabilir. Örneğin, kullanıcının bir işlemi tamamladığında veya belirli bir koşul gerçekleştiğinde bir değer yayınlamak için Future kullanılabilir.
- UI Güncellemeleri: Future, arayüzdeki (UI) değişiklikleri gerçekleştirmek için de kullanılabilir. Örneğin, bir kullanıcı bir form gönderdiğinde veya bir işlem tamamlandığında UI'da ilgili güncellemeleri yapmak için Future kullanılabilir.
- A Future in Combine, sonunda bir Promise tarafından kolaylaştırılan tek bir değer veya bir hata üreten bir yayıncıdır. Promise, Gelecekteki yayıncı bir olay yaymaya hazır olduğunda çağrılan bir kaçış kapatma içinde eşzamansız işlemleri sarar.
let future1 = Future<Int, Error> { promise in
promise(.success(42))
}
let future2 = Future<String, Error> { promise in
promise(.success("Combine"))
}
// Combining Futures with Zip
let combinedFuture = Publishers.Zip(future1, future2)
// Subscribing to the combined Future
let cancellable = combinedFuture
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print("Received error: \(error)")
}
}, receiveValue: { values in
let (intResult, stringResult) = values
print("Received values: \(intResult), \(stringResult)")
})
Ciktisi: Received values: 42, Combine
func fetchDataFromServer() -> Future<String, Error> {
return Future { promise in
// Simulate a network request
DispatchQueue.global().async {
if let data = try? Data(contentsOf: URL(string: "https://example.com/data")!) {
let response = String(data: data, encoding: .utf8)
promise(.success(response ?? ""))
} else {
promise(.failure(NetworkError.failed))
}
}
}
}
// Subscribing to the Future
let cancellable = fetchDataFromServer()
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error):
print("Received error: \(error)")
}
}, receiveValue: { value in
print("Received data: \(value)")
})
- Combine'daki bir Deferred yayıncı, temel yayıncıyı başlatmadan önce bir abonesi olana kadar bekler. Oluşturmadaki bu gecikme, veri talebi olana kadar gereksiz işlerden kaçınarak performansı optimize etmek için kullanışlıdır. Ek olarak, gibi operatörlerle uyumludur
let deferredPublisher = Deferred {
return Future<User, Error> { promise in
self.asyncAPICall(url: "www.something.com") { (user, err) in
if let err = err {
return promise(.failure(err))
}
return promise(.success(user))
}
}
}
https://medium.com/@viveksehrawat36/understanding-publisher-and-anypublisher-in-swift-7a716c6474fb# AnyPublisher