Press ESC to close

Swift Dispatch Group Nedir?

Merhaba arkadaşlar, bu yazımızda Swift’de Dispatch Group nedir bundan bahsedeceğiz. Dispatch Group, uygulamanızda birden çok işi asenkron bir şekilde yapmanıza olanak sağlar. Örnek olarak Github repomdaki library projesi üzerinden gideceğim. Projeye buradan ulaşabilirsiniz. Projenin genel çalışması aşağıdaki gibidir.

Apple’ın servislerine giderek kullanıcının girmiş olduğu kelimeyi gruplara ayırarak aratıyor. Film, müzik, uygulama ve kitap olarak farklı bölümler var. Kullanıcı nerede arama yapmak isterse o bölümde arama yapıyor. Kullanıcı, müzik kısmını seçtiğinde Apple’ın servislerine gidip müzik kısmında arama yaparken; kitap kısmını seçtiğinde kitap kısmında arama yapıyor. Bunun yerine kullanıcı bir şey arattığında 4 kısımda da arama yapsın. Buna göre de ekranda yükleniyor simgesi gösterelim. 4 farklı servis isteği göndereceğiz ama bazıları daha erken bazıları ise daha geç gelecek ve son işlem tamamlanıncaya kadar ekranda yükleniyor ikonu kalması lazım.

Aşağıdaki gibi bir Interactor’um vardı. Bu her kategori değiştiğinde tekrardan arama yapıyordu.

import UIKit

protocol SearchInteractorOutputs: AnyObject {
    func onMoviesSearched(movies: MoviesModel?)
    func onNextPageFetched(movies: MoviesModel?)
    func onAllCategoriesSearched()
    func onError(error: BaseErrorModel)
}

final class SearchInteractor: BaseInteractor, Interactorable {
    weak var presenter: SearchInteractorOutputs?
    weak var entities: SearchEntities?
    
    func search(searchedText: String, type: SearchTypes) {
        services.searchMovie(searchedText: searchedText, type: type) { movies in
            self.presenter?.onMoviesSearched(movies: movies)
        } errorCompletion: { error in
            self.presenter?.onError(error: error)
        }
    }
    
    func search(searchedText: String, pageNumber: Int, type: SearchTypes) {
        services.searchMovie(searchedText: searchedText, page: pageNumber, type: type) { movies in
            self.presenter?.onNextPageFetched(movies: movies)
        } errorCompletion: { error in
            self.presenter?.onError(error: error)
        }
    }
}

Buraya ek olarak tüm kategorilerde arama yapması için bir fonksiyon yazmam gerekiyor. 4 farklı servis isteği atacağım için aşağıdaki gibi yapıyorum. Bir Dispatch Group oluşturuyorum ve her servis çağırımından önce bu servis işleminin Dispatch Group’a dahil olduğundan emin olun. Servis işlemi bittikten sonra ise bu gruptan çıktığından emin olun. 4 farklı servis çağırımını da bu Dispatch Group’a dahil ediyorum ve işlem bittikten sonra çıkarıyorum. Tüm bu gruba dahil olan işlemlerinin hepsi bittikten sonra group.notify ile kalan işlemi yapabilirim. Eğer ki UI’i güncelleyeceksiniz main thread’inde yaptığınızdan emin olun ama başka bir servise istek atacaksanız global’de yapabilirsiniz.

import UIKit

protocol SearchInteractorOutputs: AnyObject {
    func onMoviesSearched(movies: MoviesModel?)
    func onNextPageFetched(movies: MoviesModel?)
    func onAllCategoriesSearched()
    func onError(error: BaseErrorModel)
}

final class SearchInteractor: BaseInteractor, Interactorable {
    weak var presenter: SearchInteractorOutputs?
    weak var entities: SearchEntities?
    
    func searchAllCategories(searchedText: String) {
        let group = DispatchGroup()
        
        group.enter()
        services.searchMovie(searchedText: searchedText, type: .movie) { movies in
            group.leave()
            self.presenter?.onMoviesSearched(movies: movies)
        } errorCompletion: { error in
            group.leave()
            self.presenter?.onError(error: error)
        }
        
        group.enter()
        services.searchMovie(searchedText: searchedText, type: .music) { movies in
            group.leave()
            self.presenter?.onMoviesSearched(movies: movies)
        } errorCompletion: { error in
            group.leave()
            self.presenter?.onError(error: error)
        }
        
        group.enter()
        services.searchMovie(searchedText: searchedText, type: .app) { movies in
            group.leave()
            self.presenter?.onMoviesSearched(movies: movies)
        } errorCompletion: { error in
            group.leave()
            self.presenter?.onError(error: error)
        }
        
        group.enter()
        services.searchMovie(searchedText: searchedText, type: .book) { movies in
            group.leave()
            self.presenter?.onMoviesSearched(movies: movies)
        } errorCompletion: { error in
            group.leave()
            self.presenter?.onError(error: error)
        }
        
        group.notify(queue: .main) {
            self.presenter?.onAllCategoriesSearched()
        }
    }
    
    func search(searchedText: String, type: SearchTypes) {
        services.searchMovie(searchedText: searchedText, type: type) { movies in
            self.presenter?.onMoviesSearched(movies: movies)
        } errorCompletion: { error in
            self.presenter?.onError(error: error)
        }
    }
    
    func search(searchedText: String, pageNumber: Int, type: SearchTypes) {
        services.searchMovie(searchedText: searchedText, page: pageNumber, type: type) { movies in
            self.presenter?.onNextPageFetched(movies: movies)
        } errorCompletion: { error in
            self.presenter?.onError(error: error)
        }
    }
}

Sorularınız olursa mail veya yorum atarak ulaşabilirsiniz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir