Protocol Kullanımı

Bu yazı linkteki yazının detayı niteliğinde yazılmıştır, konu bütünlüğü açısından öncelikle ilgili yazıdan başlamanızı tavsiye ederim.

Protokol veya delegate kavramı cocoa framework’ün en temel mimarisi aslında. Swift Protocol Oriented Bir Dildir yazısında kullanımıyla ilgili detayları bulabilirsiniz. Yukarıdaki örnek için Protocol kullanımını gerçekleştirelim. Protocol bir iletişim kuralı belirleme yöntemidir. ServiceManager sınıfındaki loadImage methodunu çağırdığınız zaman, belirli durumlar için bir iletişim kurmanız gerekmektedir. Mesela siz yükleme başladığı zaman ekranda bir spinner görüntülemek, başarılı sonuçlanınca spinner’ı sonlandırıp resmi görüntülemek, şayet hata alırsa da bununla ilgili başka bir aksiyon gerçekleştirmek isteyebilirsiniz. Dikkat ederseniz burada 3 farklı iletişim gerektiren durum belirlemiş olduk. Bu durumların her biri için ServiceManager bir şekilde sizi bilgilendirebilecek yapıda olması gerekmektedir. Bunu sağlayabilmesi için  aşağıdaki Protocol’ü hazırlayalım.

protocol ServiceManagerDelagate{
    func basladi()
    func tamamlandi(image : UIImage?)
    func hataAlindi(hataMesaji : String)
}

Protokol içersinde interface tanımı benzeri şeklinde 3 ayrı method tanımı yaptık. Bunu ServiceManager sınıfı ile ilişkilendirebilmek için aşağıdaki şekilde ServiceManagerDelegate değişkeni eklememiz gerekmektedir.

class ServiceManager {
    var delegate : ServiceManagerDelagate!
    .......

Buradaki delegate değişkeni’ni hangi sınıfa mesaj göndermek istediğimizi belirlemek için kullanacağız. Sonuçta ServiceManager nesnesini kullanarak bir resmi indirecek bir başka nesne mevcut olacak. Örneğin ViewController.swift içerisinde ServiceManager().loadImage çağrımını yaptığınızı düşünün. Bu durum da SerivceManager nesnesinin ViewController’a protocol içerisinde bulunan basladı, tamamlandı, hataalindi mesajlarını göndermesi beklenmektedir. İşte bu mesajların ViewController’a gönderilmesini yukarıda tanımlanan delegate değişkeni üzerinden gerçekleştireceğiz.

Örneğimizin anlamlı olabilmesi için resim yükleme işlemlerini URLSession kullanarak yapacağız. URLSession kullanarak bir resmi aşağıdaki şekilde düzenleyebiliriz.

class ServiceManager {
    var delegate : ServiceManagerDelagate!
    func loadImage(filePath : String) {
        if let url = URL(string: filePath) {
            //basladi:  Resim yüklemenin başladığı adım.
            self.delegate.basladi()
            URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
                if error != nil || data == nil {
                    //hataAlindi: İşlemde hata olması durumu
                    self.delegate.hataAlindi(hataMesaji: error!.localizedDescription)
                    return
                }
                //tamamlandi: İşlemde hata olması durumu
                self.delegate.tamamlandi(image: UIImage.init(data: data!))
            }).resume()
        }
    }
}

Yukarıdaki kod içerisinde gerekli olan bölümlere bahsi geçen protocol methodlarının çağrımını ekledim. ServiceManager bölümü hazır şuan. Şimdi ViewController içerisinde bunu nasıl kullanacağımıza bakalım.

class ViewController: UIViewController, ServiceManagerDelagate {
    let serviceManager = ServiceManager()
    override func viewDidLoad() {
        super.viewDidLoad()
        serviceManager.delegate = self
        serviceManager.loadImage(filePath: "***")
    }

    func basladi() {
    }
    func tamamlandi(image: UIImage?) {
    }
    
    func hataAlindi(hataMesaji: String) {
    }
}

Kodun bu bölümünü incelemek gerekirse;

  • class ViewController: UIViewController, ServiceManagerDelagate 
    ViewController nesnesi içerisinde ServiceManager içerisindeki loadImage’i kullanacağımızı biliyoruz. Ve ServiceManager’ı kullanırken bize cevapların ServiceManagerDelagate protocol’ü üzerinden geleceğini konuşmuştuk. İşte bu protocol’ü kullanabilmek için nesneyi tanımlarken yukarıdaki şekilde eklememiz gerekmektedir.
    Protocol’leri interface’den ayıran en önemli özellik, bir nesnenin birden fazla protokolü impelement edebilmedir. ServiceManagerDelegate, UITextFieldDelegate… şeklinde birden fazla protocol eklenebilmektedir.
  • serviceManager.delegate = self
    serviceManager sınıfının içerisine delegate isminde bir değişken eklemiştik. Bu değişkeni protocol methodlarını tetikleyeceğimiz zaman hangi sınıf içerisinde olduklarını anlamak için kullanacağımızı söylemiştik. Burada .delegate = self  diyerek ViewController içerisine eklenen methodların tetiklenmesi gerektiğini belirtmiş olduk.
  • İlgili protocol methodlarının eklendiğini görebilirsiniz. Burada herhangi bir method’un eklenmemesi durumunda aşağıdaki hatayı almış olacaksınız.
Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn
Bu yazıyı beğendiyseniz daha fazla kişiye ulaşmasını sağlamak için paylaşabilirsiniz.

Leave a reply