Swift: Protocol-AssociatedType
Associated Type, protocol’lerde generic yapı elde etmemizi sağlar ve protocol’e uyma sözü veren tipler tarafından tipinin belirlenmesini beklerler.
Uygulamamızda kullanmak için kamera, mikrofon, fotoğraf galerisi gibi özellikler için kullanıcıdan izin isteriz. Bunun için basit bir protocol tanımlayarak uygulamasını gerçekleştirelim.
1 2 3 4 5 6 7 8 9 10 |
protocol Permission { associatedtype PermissionType var status: PermissionType { get } func request(completion: @escaping (PermissionType) -> ()) } |
Protocol’ümüz “PermissionType” adını verdiğimiz bir associatedtype’a sahip olacak şekilde yaratıldı. İçerisinde ayrıca bu tipte bir değişken ve çağırıldığı yere bu tipi dönen closure sahip fonksiyon bulunuyor.
Şimdi bir tip yaratarak “Permission” protocolüne uymasını isteyelim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
struct MicrophonePermission: Permission { var status: AVAudioSession.RecordPermission { AVAudioSession.sharedInstance().recordPermission } func request(completion: @escaping (AVAudioSession.RecordPermission) -> ()) { AVAudioSession.sharedInstance().requestRecordPermission { _ in completion(self.status) } } } |
“MicrophonePermission” tipimiz, “Permission” protocolüne uyuyor ve associatedtype’a “AVAudioSession.RecordPermission” tipini veriyor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
struct CameraPermission: Permission { var status: AVAuthorizationStatus { AVCaptureDevice.authorizationStatus(for: .video) } func request(completion: @escaping (AVAuthorizationStatus) -> ()) { AVCaptureDevice.requestAccess(for: .video) { (granted) in completion(self.status) } } } |
Yeni örneğimizde Kamera erişimi için izin istedik. Bu kez associatedtype’ımız “AVAuthorizationStatus” tipine sahip oldu ve request fonksiyonunda da bu tipi döndürmektedir.
Yaratmış olduğumuz protocol sayesinde proje genelindeki izin işlemlerinin uymasını istediğimiz bir düzen belirlemiş olduk.
Yeni örneğimizde oluşturduğumuz “TableViewCell” lerin uymasını istediğimiz bir protocol oluşturalım.
1 2 3 4 5 6 7 8 |
protocol Cell { associatedtype DataType func configure(_ type: DataType) } |
“Cell” protocolü içerisinde generic bir tip tanımlıyor ve bu tipi bekleyen bir fonksiyon içeriyor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
struct CreditCard { let cardNo: String let cardOwner: String let availableLimit: Double } class CreditCardCell: UITableViewCell, Cell { func configure(_ type: CreditCard) { print(type.cardNo) } } |
“CreditCardCell”, protocol’e uymak için “configure” metodunu uyguluyor ve beklediği tipe yine bizim oluşturduğumuz “CreditCard” ı bekliyor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
struct Team { let name: String let stadiumLocation: (latitude: Double, longitude: Double) let stadiumName: String } class TeamCell: UITableViewCell, Cell { func configure(_ type: Team) { print(type.name) } } |
“TeamCell”, Cell protocol’üne uyabilmek için “configure” metodunda “Team” tipini bekliyor.
Bu örneğimizde de proje genelinde “TableViewCell” lerin çizilmesi için bir kural belirlendi. Projemizdeki bütün “TableViewCell” ler “DataType” alan bir configure metoduna sahip olup, UI elemanlarının değerlerini burada dolduracaktır.