CodeNest
431 mots
2 minutes
Tutoriel avancé sur Swift : Programmation concurrente avec Combine

Tutoriel avancé sur Swift : Programmation concurrente avec Combine#

Introduction#

Ce tutoriel couvre l’utilisation avancée du framework Combine de Swift pour la programmation réactive et concurrente. Nous explorerons les concepts clés et les mettrons en pratique à travers des exemples concrets.

Table des matières#

Bases de Combine#

Combine est un framework de programmation réactive introduit par Apple dans iOS 13. Il permet de traiter des valeurs au fil du temps de manière asynchrone.

import Combine

let publisher = Just(5)
let cancellable = publisher.sink { value in
    print("Received value: \(value)")
}

Publishers et Subscribers#

Les publishers émettent des valeurs, tandis que les subscribers les reçoivent.

let subject = PassthroughSubject<Int, Never>()
let subscription = subject
    .sink { value in
        print("Received: \(value)")
    }

subject.send(1)
subject.send(2)
subject.send(completion: .finished)

Opérateurs#

Les opérateurs permettent de transformer, filtrer et combiner des flux de données.

let numbers = (1...10).publisher

numbers
    .filter { $0 % 2 == 0 }
    .map { $0 * $0 }
    .collect()
    .sink { squares in
        print("Carrés des nombres pairs : \(squares)")
    }

Gestion des erreurs#

Combine offre des mécanismes puissants pour gérer les erreurs de manière élégante.

enum MyError: Error {
    case customError
}

let failingPublisher = Fail<Int, MyError>(error: .customError)

failingPublisher
    .catch { error -> AnyPublisher<Int, Never> in
        print("Erreur interceptée : \(error)")
        return Just(0).eraseToAnyPublisher()
    }
    .sink { value in
        print("Valeur reçue : \(value)")
    }

Schedulers#

Les schedulers permettent de contrôler sur quel thread les opérations sont exécutées.

let queue = DispatchQueue(label: "com.example.myqueue")

Just(5)
    .receive(on: queue)
    .map { value -> Int in
        print("Current thread: \(Thread.current)")
        return value * 2
    }
    .receive(on: DispatchQueue.main)
    .sink { value in
        print("Résultat final sur le thread principal: \(value)")
    }

Projet pratique#

Implémentons un gestionnaire de téléchargements concurrents utilisant Combine.

class DownloadManager {
    private var cancellables = Set<AnyCancellable>()
    
    func download(urls: [URL]) -> AnyPublisher<[Data], Error> {
        urls.publisher
            .flatMap(maxPublishers: .max(3)) { url -> AnyPublisher<Data, Error> in
                URLSession.shared.dataTaskPublisher(for: url)
                    .map(\.data)
                    .mapError { $0 as Error }
                    .eraseToAnyPublisher()
            }
            .collect()
            .eraseToAnyPublisher()
    }
    
    func startDownloads(urls: [URL]) {
        download(urls: urls)
            .receive(on: DispatchQueue.main)
            .sink(
                receiveCompletion: { completion in
                    switch completion {
                    case .finished:
                        print("Tous les téléchargements sont terminés")
                    case .failure(let error):
                        print("Erreur de téléchargement : \(error)")
                    }
                },
                receiveValue: { dataArray in
                    print("Nombre de fichiers téléchargés : \(dataArray.count)")
                }
            )
            .store(in: &cancellables)
    }
}

// Utilisation
let manager = DownloadManager()
let urls = [
    URL(string: "https://example.com/file1.pdf")!,
    URL(string: "https://example.com/file2.pdf")!,
    URL(string: "https://example.com/file3.pdf")!
]
manager.startDownloads(urls: urls)

Ce tutoriel couvre les aspects avancés de la programmation concurrente avec Combine en Swift. Il aborde les concepts fondamentaux, la manipulation des flux de données, la gestion des erreurs, et l’utilisation des schedulers. Le projet pratique démontre comment ces concepts peuvent être appliqués pour créer un gestionnaire de téléchargements concurrents robuste.

Articles Similaires