Sobes.tech
Middle

Projelerinizde hiç Combine kütüphanesini kullandınız mı?

sobes.tech yapay zeka

AI'dan gelen yanıt

Evet, kullandım.

Projelerimde Combine'in temel kullanımı, aşağıdaki gibi asenkron olayların işlenmesiyle ilgilidir:

  • Ağ istekleri: API yanıtlarının işlenmesi, veri dönüşümü, hata yönetimi.
  • UI öğelerindeki değişiklikler: Kullanıcı eylemlerine tepki verme, metin alanı değişiklikleri, kaydırıcılar.
  • Yerel verilerin işlenmesi: Veritabanlarındaki değişikliklerin takibi (örneğin, Core Data), FileManager bildirimleri.
  • MVVM mimarisinde View ile ViewModel arasında bağlama için reaktif veri akışlarının oluşturulması.

Combine kullanmanın avantajları:

  1. Asenkron işlemlerle çalışırken kod hacmini azaltma ve okunabilirliği artırma.
  2. Hata yönetimini merkezileştirme ve işlemleri iptal etme.
  3. Operatörler aracılığıyla veri akışlarını kolayca birleştirme ve dönüştürme.
  4. Apple'ın framework'leriyle doğal entegrasyon (SwiftUI, Core Data, URLSession).

Ağ isteği için Combine kullanımı örneği:

import Combine
import Foundation

struct APIResult: Decodable {
    let value: String
}

func fetchData(from url: URL) -> AnyPublisher<APIResult, Error> {
    URLSession.shared.dataTaskPublisher(for: url)
        .map(\data) // Veri tuple'ından çıkar
        .decode(type: APIResult.self, decoder: JSONDecoder()) // Veriyi decode et
        .receive(on: DispatchQueue.main) // UI güncellemeleri için ana thread'e geç
        .eraseToAnyPublisher() // Türü basitleştir
}

// Abonelik örneği
let cancellable = fetchData(from: URL(string: "https://api.example.com/data")!)
    .sink(receiveCompletion: { completion in
        switch completion {
        case .finished:
            print("İstek başarıyla tamamlandı")
        case .failure(let error):
            print("İstek hatası: \(error.localizedDescription)")
        }
    }, receiveValue: { result in
        print("Alınan veri: \(result.value)")
    })
// Bu referansı tutmak, aboneliğin aktif kalmasını sağlar

Ayrıca, MVVM'de özellikleri bağlamak için Combine kullanıyorum:

class ViewModel {
    @Published var text: String = ""
    @Published var isValid: Bool = false

    private var cancellables = Set<AnyCancellable>()

    init() {
        $text
            .map { $0.count > 0 } // Metni boolean değere dönüştür
            .assign(to: &$isValid) // Sonucu isValid özelliğine ata
    }
}

class ViewController: UIViewController {
    let textView = UITextField()
    let validationLabel = UILabel()
    let viewModel = ViewModel()

    private var cancellables = Set<AnyCancellable>()

    override func viewDidLoad() {
        super.viewDidLoad()

        // UITextField ile ViewModel arasında bağlama
        NotificationCenter.default.publisher(for: UITextField.textDidChangeNotification, object: textView)
            .compactMap { ($0.object as? UITextField)?.text }
            .assign(to: \.text, on: viewModel) // Metni ViewModel'e ata

        // ViewModel ile UILabel arasında bağlama
        viewModel.$isValid
            .map { $0 ? "Geçerli" : "Geçersiz" }
            .assign(to: \.text, on: validationLabel) // Metni UILabel'e ata
            .store(in: &cancellables) // Aboneliği sakla
    }
}

Combine ile çalışma deneyimim olumlu, karmaşık senaryolarda eski yaklaşımlara (closures, delegates) göre çok daha basit hale getiriyor.