MVVM Base Protocols Hakkında Her Şey
Giriş
MVVM çok tercih edilen bir mimari. Ben de projelerimde MVVM mimarisini sıklıkla tercih ediyorum. Son zamanlarda farkettim ki yeni bir projeye başlarken sürekli önceki projelerimden kopya çekiyorum hatta birçok yerini kopyala-yapıştır yapıyorum. Bundan sıkılıp daha iyi bir yol aradım ve karşıma SDK üretmek çıktı. Üstelik bunu beğenen herkesin kullanımına sunabilirim.
Ben MVVM mimarisini kolayca kullanılmasını sağlayacak bir SDK üretmeyi amaçladım. Bu makaleyi, bu SDK’nın nasıl kullanılacağını açıklamak için hazırladım.
Kimler için
Benim gibi her yeni projesinde baştan kopyala yapıştır yapan ve MVVM mimarisini tercih eden herkes için.
Umarım özellikle yeni başlayanların bu SDK’yi kullanırken MVVM mimarisini daha kolay öğrenmesini sağlamış olurum.
Açıklama
MVVM mimarisi gereği 3 ayrı class ya da struct üzerinde şekillenir, doğal olarak SDK’de de bunlar mevcut:
• Model
• View
• ViewModel
Ve bunlara ek olarak SDK fazladan 2 extension içeriyor:
• NSObjectExtension (classların isimlerini döndüren bir NSObject extension’ı)
• ViewController+TapGesture (Herhangi bir ViewController’da boş alana dokununca klavyeyi kapatan ViewController extension’ı)
Dosya Yapısı
Extensionlar
NSObjectExtension
Storyboard isimlerini string olarak elle girmek, daha sonra basit hatalara sebep olacağından bundan kaçmak için kullandığım bir yöntem. Özellikle, Storyboard ve UIViewController ya da UITableViewCell gibi classlarla aynı ismi paylaşan durumlarda kullanmak faydalı oluyor.
Kısacası, NSObject class’ından türemiş her class veya struct’ın adını string olarak geri döndürür.
ViewController+TapGesture
Hazırladığınız uygulamada, kullanıcı klavyeyi açtı, yazdı. Peki ya sonra? Boş alanlara tıklansa da klavye kapanmıyor, bunun çözümü için ben bu basit extension’ı kullanıyorum.
Klavyenin kapanması istenmeden öncesinde hideKeyboardWhenTappedAround() metodunun çağırılması lazım. Bunu garantiye almak için viewDidLoad‘ın altında çağırmak mantıklı geliyor.
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
}kaynak: https://stackoverflow.com/a/27079103/14814820
Protocoller
BaseModelProtocol
İçinde kural barındırmayan tek protocol bu. Model struct’larında ortak olarak bulunması gerekir diyebileceğim bir özellik olmadığı için burası boş kaldı. Olası kurallar için yine de kaldırmadım.
BaseViewProtocol
MVVM mimarisinde bir view, ilgili viewModel’le etkileşimde olmalıdır. Bu durum her sayfa için geçerli olacağından BaseViewProtocol’e eklemek doğru olacaktır.
Bir de UI’lar farklı storyboardlarda tutulabileceği için.(Ben hepsini ayrı tutmak taraftarıyım zaten.) Burada karışıklık çıkmaması için; her view sınıfının, kendi storyboard ismini tutmasını zorunlu kıldım.
Get Emin Teyhan USLU’s stories in your inbox
Join Medium for free to get updates from this writer.
instantiate func
Bu extension sadece UIViewController’a conform edilen sınıflarda kullanılabilecektir. Bunu “where Self: UIViewController” ifadesi sayesinde kazanmış oldu.
Geri kalanının yeterince açık olduğunu düşünüyorum. Önce storyBoard, sonra da viewController oluşturuluyor. Ve referansı döndürülüyor.
BaseViewModelProtocol
MVVM mimarisinde bir viewModel, view ve model’le etkileşim içinde olmalıdır. O zaman bu diğer elemanları, viewModel’le ilişkilendirmek her durumda karşımıza çıkacağı için bu durumu BaseViewModelProtocol’le eklemek lazım diye düşündüm.
startPage func
Sayfa geçişlerinin hep viewModel içinde yönetilmesini tercih ettim. startPage extension’ı, başka bir sayfaya geçmek için kullanılıyor.
Kodları açıklamak gerekirse, öncelikle view’ın instantiate(BaseViewProtocol içindeki custom method, yukarıda açıklandı.) methodu çağırılır. Böylece view başlatılmış olur. ViewModel’in delegate’ine bu oluşturulan view’ın instance’ı atanır. İlgili viewController’ın viewModel property’sine, üzerinde çalıştığımız viewModel’in referansı atanır.
Uzun lafın kısası startPage metodu sayesinde, BaseProtocol’lerin içindeki propertie’lerin değerleri atanmış olur. <ViewModel>.delegate ve <ViewController>.viewModel
Örnek kullanım:
İlgili sayfanın startPage metodu çağırıldığında dönen viewController’ı navigationController’a push’lamak gerekiyor sadece.
Ben Nasıl Kullandım?
Herhangi bir sayfa oluşturulmadan önce sayfa adının sonuna Contract ifadesini eklediğim bir dosya açmayı ve tüm protocolleri burada toplamayı tercih ettim . O sayfaya dair her özelliği burada başlıklar halinde görebilecektim.(method adları ve bazı değişkenleri)
Her MVVM elemanı için yeni protocol oluşturdum. Örneğin DetailPageViewModelProtocol, bu protocol BaseViewModelProtol’i conform etmelidir. Ayrıca viewType’ı, hemen alttaki, DetailPageViewControllerProtocol ve ModelType’ı DetailPageModelProtocol olmalıdır diye belirttim. Bu bilgileri de where ifadesinden sonrasına ekleyerek ifade etmiş oldum.
Bunları yerleştirmem sayesinde BaseProtocol’lerin içindeki delegate veya viewModel gibi değişkenler buraya verdiğim protocolleri conform eden sınıflardan oluşturulmak zorundadır. Ayrıca burada olması çok daha derli toplu gözükmesini sağlıyor.
Her bir protocol’e ilgili sınıflarda fazladan olması gereken metotların adlarını ekliyorum.
Örnek: DetailPageViewModel Sınıfı
Sayfaya özel protocoller hazırlandıktan sonra, sıra bu protocolleri conform edecek sınıfları yazmakta.
Bilindiği üzere bir protocol conform edilince protocol’ün şart koştuğu metodları xcode sayesinde o sınıfa ekleyebiliyorsunuz. typealias’ları yazdıktan sonra, burası için, ViewModel’in değişkenleri olan model ve delegate’in tipi de otomatikman belirlenmiş oluyor. xcode, sonradan bunları da eklememizi sağlıyor. İkinci tıklamayla hepsi hazır oluyor yani.
Sıra o sınıf için geriye kalan metotların içini doldurmaya kalıyor. Bu işlemler diğer elemanlar için de aynı şekilde devam ediyor.
Örneğin tamamı için: https://github.com/TeyUs/Sample_CoreData_MVVM
Sonuç
Kuralları net olan yerleri tekrar tekrar yazmak yerine her projenin başında BaseProtocolleri eklemek yeterli olacak.
Son zamanlarda yaptığım tüm küçük uygulamalarda kopyala yapıştır yapmaya başlamıştım, artık bundan kurtuldum.
Hem de beğenen herkesin kullanabileceğini bilmek çok mutlu ediyor.
SDK Nasıl Kullanılır
Bunun için paketi projeye eklemek gerekiyor.
File > Add Packages… > linki üstteki arama çubuğuna yapıştırın: https://github.com/TeyUs/MVVMBaseProtocols.git > Add Packages
Sonrasında benim gibi kullanırsanız o dosyanın başına “import MVVMBaseProtocols” yazdıktan sonra bu makale boyunca açıkladığım gibi kullanabilirsiniz.

![Observable 101]](https://miro.medium.com/v2/resize:fit:1358/format:webp/0*LKQFqHVxhh3wCWeh.png)
![Observable 101 [TR]](https://miro.medium.com/v2/resize:fit:1358/format:webp/1*EqiM0q0b9GZUPZu1YHPgaw.png)







