Swift Package Yapısı ve Modülerleştirme

Cem Kılıç
Paycell Tech Team
Published in
6 min readApr 24, 2024

Merhaba, bu makalede package nedir, nasıl oluşturulur ve projeye nasıl eklenir sorularını cevaplamaya çalışırken modülerleştirme ile nasıl kullanılabileceğine değineceğim.

Package nedir ?

Apple bu soruya şöyle bir cevap vermiş:

“Swift paketleri, geliştiricilerin projelerinde kullanabilecekleri Swift, Objective-C, Objective-C++, C veya C++ kodlarının yeniden kullanılabilir bileşenleridir. Source dosyalarını, binary dosyaları ve resource dosyalarını projede kullanımı kolay bir şekilde paketlerler.”

Swift paketleri, projelerinizde tekrar tekrar kullanabileceğiniz kod parçalarını ayrı bir kaynakta oluşturmanın ve yönetmenin etkili bir yoludur. Bu yol bize karmaşıklığı azaltmak, geliştirmeyi hızlandırmak, düzenleme ve bakımları daha kolay hale getirmekte yardımcı olur.

P..peki ama tam olarak nerede işimize yarar?

Örneğin;

— Modülerleştirme: Uygulamada kullanılacak bileşenleri(components), network ve logging gibi katmanları ayrı paketlere bölerek, kodun organize ve yönetilebilir olmasını sağlayabiliriz.

— Yayımlanabilir: Framework olarak geliştirme yapıp farklı target ve projeler için erişilebilir olmasını sağlayabiliriz. Bu adımda yine Xcode’un sağladığı Swift Package Manager’ı kullanabiliriz.

— Bağımlılıkları yönetme: Circular dependency* durumlarını engelleyebilir, farklı kod parçalarının birbiri ile iletişimi düzgün biçimde sağlayabiliriz.

Bu gibi durumlar için Package yapısı biçilmiş kaftan.

circular dependency, bağımlılıkların aralarında birebir ilişki kurması. Görsel*

Nasıl oluşturulur ve kullanılır?

Örnek olması için boş bir proje oluşturuyorum, UIKit veya SwiftUI ayrımı yok, ben UIKit ile oluşturdum.

Örnek olması için boş bir proje oluşturuyorum, GitHub bağlantısını yapıyorum ve bir workspace’e ekliyorum.

Workspace’im hazır, sıradaki işlem Package’ı oluşturmak. Bunun için File > New > Package yolunu izliyorum.

Library’i seçip devam ediyorum.

— Save As: Package’ın ismini veriyorum.
— Source Control: GitHub’a yükleyeceğim için seçiyorum, siz tercihinize göre işaretleyebilirsiniz.
— Add To: Eklenecek proje, ben workspace’i seçiyorum
— Group: Hangi alana ekleneceği, oluşturduğum boş projeyi de seçebilirim fakat ben ayrı bir modül olarak görmek istiyorum, dolayısıyla workspace’i seçiyorum.

Package oluştu ve workspace’e eklendi;

Modül içerisinde Package.swift isminde bir dosya olduğunu görüyoruz, bu paketimizin özelliklerini yönettiğimiz dosya olacak. Örnek olması için bir kaç satır ekleme yaptım, kısaca açıklamak gerekirse;

name: Package’ın ismi.
platforms: Package’ın destek verdiği hedef işletim sistemleri(iOS, tvOS vs).
products: Package’ın sunduğu ürünler, bir ürün için birden fazla modül olabilir, “targets” isimli elemanları burada veriyoruz
dependencies: Package’ın içerisinde kullanacağımız bağımlılıkları bu dizi içerisinde vermeliyiz, hali hazırda oluşturulmuş başka modülleri de buraya local olarak ekleyebiliriz.*
targets: Package’ın sunacağı modülleri bu dizi içerisine ekleyebiliriz. Her target’in ihtiyacı olan bağımlılığını dependency kısmına eklemeyi unutmamalıyız.**
*Örnek olması için Alamofire isimli kütüphaneyi ekledim.
**Alamofire kütüphanesini ekledim. CMD + S kombinasyonu ile kayıt aldığımda Swift Package Manager’ın otomatik olarak paketi çektiğini ”Package Dependencies” kısmında görebilirsiniz.

Package’a dosya eklemek ve proje bağlantısı

CoreViews isimli klasöre BaseController adında yeni bir swift dosyası oluşturuyor ve bir kaç satır kod ekliyorum;

BaseController adında UIViewController tipinden bir sınıf oluşturdum, “open” access modifier’ı ile diğer modüllerden erişilebilmesini ve kalıtım aktarabilmesini sağladım. Sıra paketi projeye eklemeye geldi;

Projeyi seçip “General” sekmesi altında “Frameworks, Libraries and Embedded Content” alanına oluşturduğumuz modülü ekliyoruz. Tek adım kaldı, projemize varsayılan olarak eklenen ViewController isimli dosyaya modülümüzü çağırıp BaseController sınıfımızdan türemesini sağlıyoruz. Ve ilk deneme..

Voilà! Başarıyla build aldık ve derleme konsoluna printlerimiz yansımış, modülü başarıyla ekleyebildiğimizi anlamış olduk.

Aynı amaç için yazılmış kodları nasıl parçalayabilirim?

Bazen yaptığımız işler dallanıp budaklanabiliyor, bir iş için bir kaç farklı yaklaşım sergilememiz gerekebilir. Basit bir örnek vermek gerekirse CoreViews package’ı altına loglama modülü eklemeye karar verdim, apayrı bir package oluşturmak yerine aynı package içerisinde farklı bir alt modül yaratabiliriz.

Yapmamız gereken tek şey “Sources” klasörü altına bir klasör oluşturup Package.swift dosyamızda yeni bir target oluşturmak ve varolan product’a eklemek. *Satır başlarındaki mavi kısımlar değişiklikleri işaret etmektedir.*
Burada dikkat etmemiz gereken bir nokta var. Eğer yeni modül için gerekli klasörü “ Sources” dışında oluşturursanız Package dosyası yerini bulamayacaktır.

Hemen yeni klasör içerisinde LogManager isimli bir swift dosyası oluşturdum, içeriği şu şekilde;

open class LogManager { 
public static func log() {
print("logged")
}
}

ViewController’a gidip yeni modülümüzü çağırıyoruz. LogManager isimli sınıfın başarıyla çalıştığını görüyoruz.

Oluşturduğumuz package’ı bir dependency olarak eklemek

CoreViews adlı package’ı GitHub’a ayrı bir repository olarak yükleyip workspace’imden tamamen kaldırıyorum ve eklediğim iki yeni modülü xcode’un projemde bulamadığını görüyorum;

“File > Add Packages” yolunu takip ediyorum, bu Xcode’un sağladığı SPM yani Swift Package Manager isimli bağımlılık aracını kullanmamı sağlıyor.

Açılan ekranda arama kısmına package’ımın olduğu repository’nin linkini veriyorum ve “Add Package” butonuna tıklıyorum. Burada “Add to Project” kısmında projemin seçili olduğuna emin oldum.

Gelen ekranda aynı butona tıklıyorum.

Veee karşımızda yeni bir bağımlılık olarak CoreViews, hemen kodumu derliyorum ve başarılı oluyor.

Modülerleşme yolunda ilk adımı attık, devamı sizlerin hayal gücü ve disiplinine kalmakta.

Noktayı koymadan önce

İhtiyacınız olabilecek bir kaç ufak bilgiyi eklemek istiyorum;

  • Projeden bir package’ı silmek veya versiyonunu düzenlemek için .xcodeproj dosyasını açıp projenin kendisini seçmeliyiz (ekran görüntüsündeki gibi)

Açılan ekranda “Package Dependencies” sekmesinden* paketleri düzenleyebiliriz.

*Package Dependencies
  • Xcode’un eski versiyonlarını kullanıyorsanız (<Xcode 15.0) package oluşturulurken hazır olarak gelen aynı isimli struct’ı sildiğinizde bir takım hatalar alabilirsiniz.
  • Dış bağımlılıklarınızı Package.swift dosyalarına girdikten sonra yönetimi Xcode’un kendisi yapmakta. Eğer aynı bağımlılığı birden fazla paket içerisine farklı versiyonlar/tagler/branchler şekilde girmeye çalışırsanız hata ile karşılaşabilirsiniz.
  • Package içerisinde bir değişiklik yapıp kayıt ettiğimizde(CMD ⌘ + S) otomatik olarak build alacaktır, bunu “Report navigator” sekmesi* altındaki workspace içerisinden kontrol edebiliriz ya da manuel şekilde package’ın derlenmesini sağlayabiliriz.
*Report Navigator

Umarım yardımcı olabilmişimdir, bir sonraki yazıda görüşmek üzere 👋

CoreViews GitHub Linki
Proje GitHub Linki

--

--