29. Oktober 2019

Bibliotheken per Swift Package Manager in iOS-Projekte einbinden

Mit Xcode 11 wurde der Swift Package Manager zur Verwendung in iOS-Projekten erweitert. Es können nun damit iOS-Frameworks/Module erstellt werden und diese in Xcode-Projekte eingebunden werden. Damit wird das Tool eine Alternative zu Cocoapods und Carthage für das Verwalten der Abhängigkeiten eines iOS-Projektes.

Das folgende Tutorial zeigt die Schritte zur Einbindung der 3rd-Party-Bibliothek Kingfisher zum asynchronen Laden von Bildern - diese stellt bereits die für den Swift Package Manager benötigten Metadaten bereit.

  1. Lade den Start-Stand für das Beispielprojekt Countries. Dieses enthält den Grundaufbau für eine App, die Bilder in einem TableViewController anzeigt:

    UITableViewController im Countries-Beispiel
  2. Öffne die Projektseite von Kingfisher und kopiere die Clone-URL des Projektes:

    Clone-URL von Kingfisher kopieren
  3. Wähle in Xcode File » Swift Packages » Add Package Dependency… um eine neue Abhängigkeit hinzuzufügen:

    Xcode: Add Package Dependency
  4. Gib die Clone-URL der Kingfisher-Bibliothek an:

    File » Swift Packages » Add Package Dependency…
  5. Belasse die Versionseinstellungen - die Bibliothek wird bis zum nächsten Major Release automatisch aktualisiert:

    Xcode Package Options
  6. Füge nur das Kingfisher-Produkt zum Target der App hinzu (die Bibliothek enthält auch eine optionale Integration für SwiftUI):

    Xcode Add Package
  7. Die Bibliothek wird nun im Projekt eingerichtet und im Projekt Navigator angezeigt:

    Xcode Swift Package Dependencies
  8. Im Projekt unter Swift Packages kann z.B. die Versionsangabe geändert werden:

    Swift Packages im Xcode-Projekt
  9. Verwende die Bibliothek im CountriesTableViewController: Importiere dort das Kingfisher-Modul und verwende die kf-Extension um ein Bild-Download asynchron im Hintergrund zu starten:

    import UIKit
    import Kingfisher
    
    // …
    
    class CountriesTableViewController: UITableViewController {
    
    // …
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CountryCell", for: indexPath) as! CountryTableViewCell
            let country = self.countries[indexPath.row]
    
            cell.countryNameLabel.text = country.name
            let placeholder = UIImage(named: "placeholder")
    cell.countryImageView.kf.indicatorType = .activity
    cell.countryImageView.kf.setImage(with: country.landmark.imageUrl, placeholder: placeholder)
            
            return cell
        }
    
    }

Fragen & Antworten

Wo wird das ausgecheckte Modul abgelegt?

Im Derived Data Ordner von Xcode:

Was passiert, wenn das Projekt geöffnet wird ohne das die Bibliothek bereits heruntergeladen wurde?

Die Bibliothek wird von Xcode automatisch heruntergeladen:

Was passiert, wenn eine neue Version der Bibliothek erscheint?

Der verwendete Commit-Hash der Bibliothek wird im Xcode-Projekt unter project.xcworkspace/xcshareddata/swiftpm/Package.resolved abgelegt. Diese Angabe wird verwendet, um die Bibliothek herunterzuladen. Es erfolgt also kein automatisches Update sondern die Version der Bibliothek ist auf diesen Stand festgelegt.

Die Abhängigkeit kann mit File » Swift Packages » Update to Latest Package Versions aktualisiert werden.