Erstellen Sie mit Headless Oracle Content Management einen Blog in Swift

Einführung

Eine iOS-Entwicklungsumgebung mit Swift und SwiftUI kann ein leistungsstarkes Tool zum Erstellen von Anwendungen sein, die Inhalte aus Oracle Content Management nutzen. Bewaffnet mit dem richtigen Contentmodell können Sie schnell die Benutzeroberfläche erstellen, aus der eine typische Blog-App besteht.

In diesem Tutorial erstellen wir eine einfache iOS-Bloganwendung in Swift, indem wir Oracle Content Management als Headless-CMS sowie sein Software Development Kit (SDK) für die Bereitstellung von Inhalten nutzen. Dieses iOS-Beispiel ist unter GitHub verfügbar.

Das Tutorial besteht aus drei Schritten:

  1. Oracle Content Management vorbereiten
  2. Bloganwendung in Xcode erstellen
  3. Führen Sie die Anwendung aus

Voraussetzungen

Bevor Sie mit diesem Tutorial fortfahren, sollten Sie zuerst die folgenden Informationen lesen:

Um diesem Tutorial zu folgen, benötigen Sie:

Was wir bauen

Unsere Blog-Anwendung besteht aus drei separaten Seiten, die es Besuchern ermöglichen, in Themen organisierte Blog-Artikel zu erkunden.

Diese animierte Abbildung zeigt die Navigation durch eine Blog-Beispiel-App, beginnend mit Themen, Navigation zu einer Liste von Artikeln und schließlich ein Blog-Artikel im Detail.

Die erste Seite, die Homepage, besteht aus Branding (Unternehmensname und Logo), einigen Links und einer Liste von Blog-Themen.

Die zweite Seite, die Artikellistenseite, zeigt eine Vorschau jedes Blogartikels an, der zum Thema gehört.

Schließlich gibt die Artikelseite den letzten Blog-Artikel aus, einschließlich Informationen zum Autor des Blogs.

Um fortzufahren, benötigen Sie ein aktives Abonnement für Oracle Content Management und müssen mit der Rolle "Content Administrator" angemeldet sein.

Schritt 1: Oracle Content Management vorbereiten

Wenn noch keine Oracle Content Management-Instanz vorhanden ist, finden Sie unter Schnellstart Informationen zur Registrierung für Oracle Cloud, zum Provisioning einer Oracle Content Management-Instanz und zum Konfigurieren von Oracle Content Management als Headless-CMS.

Für dieses Tutorial müssen Sie ein Contentmodell auf zwei Arten erstellen. Es ist ein downloadfähiges Asset Pack verfügbar, das Ihr leeres Repository mit Inhaltstypen und zugehörigen Inhalten füllt, oder Sie können ein eigenes Contentmodell und einen eigenen Inhalt erstellen.

So bereiten Sie Oracle Content Management vor:

  1. Erstellen Sie ein Kanal- und Asset-Repository.
  2. Erstellen Sie ein Contentmodell mit einer der beiden folgenden Methoden:

Channel- und Asset-Repository erstellen

Sie müssen zunächst einen Kanal und ein Asset-Repository in Oracle Content Management erstellen, damit Sie Inhalte veröffentlichen können.

So erstellen Sie einen Kanal und ein Asset-Repository in Oracle Content Management:

  1. Melden Sie sich als Administrator bei der Oracle Content Management-Webbenutzeroberfläche an.

  2. Wählen Sie im linken Navigationsmenü Inhalt aus, und wählen Sie Kanäle veröffentlichen aus der Auswahlliste im Seitenheader aus.

    Diese Abbildung zeigt die Option "Veröffentlichungskanäle", die im Dropdown-Menü im Header der Seite "Inhalt" ausgewählt wurde.

  3. Klicken Sie in der oberen rechten Ecke auf Erstellen, um einen neuen Channel zu erstellen. Benennen Sie den Kanal "OCEGettingStartedChannel" für dieses Tutorial, und halten Sie den Zugriff öffentlich. Klicken Sie auf Speichern, um den Channel zu erstellen.

    Diese Abbildung zeigt den Bereich für die Veröffentlichungskanaldefinition mit "OCEGettingStartedChannel" im Feld für den Kanalnamen.

  4. Wählen Sie im linken Navigationsmenü Inhalt, und wählen Sie dann Repositorys aus der Auswahlliste im Seitenheader aus.

    Diese Abbildung zeigt die im Dropdown-Menü im Header der Seite "Inhalt" ausgewählte Option "Repositorys".

  5. Klicken Sie in der oberen rechten Ecke auf Erstellen, um ein neues Asset-Repository zu erstellen. Benennen Sie das Asset-Repository "OCEGettingStartedRepository" für dieses Tutorial.

    Diese Abbildung zeigt den Bereich für die Repository-Definition mit "OCEGettingStartedRepository" im Feld für den Repository-Namen.

  6. Wählen Sie im Feld Kanäle veröffentlichen den Kanal OCEGettingStartedChannel aus, um Oracle Content Management anzugeben, dass der Inhalt im Repository OCEGettingStartedRepository im Kanal OCEGettingStartedChannel veröffentlicht werden kann. Klicken Sie auf Speichern, wenn Sie fertig sind.

    Diese Abbildung zeigt den Bereich für die Repository-Definition mit "OCEGettingStartedChannel" im Feld "Veröffentlichungskanäle".

Contentmodelle erstellen

Im nächsten Schritt erstellen Sie ein Contentmodell. Sie können eine von zwei Methoden verwenden:

Oracle Content Management-Beispielassetpaket importieren

Sie können ein vorkonfiguriertes Oracle Content Management-Beispielassetpaket mit allen erforderlichen Inhaltstypen und -assets für dieses Tutorial herunterladen. Falls gewünscht, können Sie auch ein eigenes Contentmodell erstellen, anstatt das Beispielassets-Pack herunterzuladen.

Sie können eine Kopie des in diesem Tutorial verwendeten Inhalts aus dem Oracle Content Management Samples Asset Pack hochladen. Dadurch können Sie mit den Inhaltstypen experimentieren und den Inhalt ändern. Wenn Sie das Oracle Content Management Samples Asset Pack importieren möchten, laden Sie das Asset Pack-Archiv OCESamplesAssetPack.zip herunter, und extrahieren Sie es in ein Verzeichnis Ihrer Wahl:

  1. Laden Sie das Oracle Content Management Samples Asset Pack (OCESamplesAssetPack.zip) von der Oracle Content Management-Seite für Downloads herunter. Extrahieren Sie die heruntergeladene ZIP-Datei in einen Speicherort auf Ihrem Computer. Nach dem Extrahieren enthält dieser Speicherort eine Datei mit dem Namen OCEGettingStarted_data.zip.

  2. Melden Sie sich als Administrator bei der Oracle Content Management-Webbenutzeroberfläche an.

  3. Wählen Sie im linken Navigationsmenü Inhalt, und wählen Sie dann Repositorys aus der Auswahlliste im Seitenheader aus. Wählen Sie jetzt OCEGettingStartedRepository aus, und klicken Sie in der oberen Aktionsleiste auf die Schaltfläche Inhalt importieren.

    Diese Abbildung zeigt die Seite "Repositorys", auf der das Element OCEGettingStartedRepository ausgewählt ist.

  4. Laden Sie OCEGettingStarted_data.zip von Ihrem lokalen Rechner in den Ordner Dokumente hoch.

    Diese Abbildung zeigt den Bildschirm zur Uploadbestätigung für die Datei OCEGettingStarted_data.zip.

  5. Wählen Sie nach dem Hochladen OCEGettingStarted_data.zip aus, und klicken Sie auf OK, um den Inhalt in das Asset-Repository zu importieren.

    Diese Abbildung zeigt die ausgewählte OCEGettingStarted_data.zip-Datei mit aktivierter Schaltfläche "OK".

  6. Nachdem der Inhalt erfolgreich importiert wurde, navigieren Sie zur Seite Assets, und öffnen Sie das Repository OCEGettingStartedRepository. Alle zugehörigen Bilder und Inhaltselemente wurden dem Asset-Repository hinzugefügt.

    Diese Abbildung zeigt das Repository OCEGettingStartedRepository mit allen Assets, die gerade importiert wurden.

  7. Klicken Sie oben links auf Alle auswählen und dann auf Veröffentlichen, um alle importierten Assets zum Veröffentlichungskanal hinzuzufügen, den Sie zuvor erstellt haben: OCEGettingStartedChannel.

    Diese Abbildung zeigt das Repository OCEGettingStartedRepository, wobei alle Assets ausgewählt sind und die Option "Veröffentlichen" in der Aktionsleiste sichtbar ist.

  8. Vor dem Veröffentlichen müssen Sie alle Assets validieren. Fügen Sie zuerst OCEGettingStartedChannel als ausgewählten Channel hinzu, und klicken Sie dann auf die Schaltfläche Validieren.

    Diese Abbildung zeigt die Seite "Validierungsergebnisse", wobei der Kanal OCEGettingStartedChannel im Feld "Kanäle" hinzugefügt, alle zu validierenden Assets und die Schaltfläche "Validieren" aktiviert sind.

  9. Nachdem die Assets validiert wurden, können Sie alle Assets im ausgewählten Channel veröffentlichen, indem Sie oben rechts auf die Schaltfläche Veröffentlichen klicken.

    Diese Abbildung zeigt die Seite "Validierungsergebnisse", wobei der Kanal OCEGettingStartedChannel im Feld "Kanäle" hinzugefügt, alle Assets validiert und die Schaltfläche "Veröffentlichen" aktiviert ist.

Anschließend können Sie auf der Seite Anlagen sehen, dass alle Assets veröffentlicht wurden. (Sie können das Symbol über dem Assetnamen angeben.)

Diese Abbildung zeigt die Seite "Anlagen", auf der alle Anlagen abgelegt wurden.

Nachdem Sie das Oracle Content Management Samples Asset Pack importiert haben, können Sie mit dem Erstellen des Blogs in Xcode beginnen.

Eigenes Contentmodell erstellen

Anstatt das Oracle Content Management Samples Asset Pack zu importieren, können Sie auch ein eigenes Contentmodell erstellen.

Für dieses Tutorial verwenden wir den Inhaltstyp "OCEGettingStartedHomePage", um die Homepage für unseren Blog zu erstellen. Diese Homepage besteht aus Branding (Unternehmensname und Logo), einigen URLs für Links und einer Liste von Blogthemen, die auf der Seite enthalten sein sollen.

Diese Abbildung zeigt die Homepage für die Demosite Cafe Supremo.

So erstellen Sie Inhaltstypen für das Contentmodell:

  1. Melden Sie sich als Administrator bei der Oracle Content Management-Webbenutzeroberfläche an.
  2. Wählen Sie im linken Navigationsmenü Inhalt aus, und wählen Sie dann Assettypen aus der Auswahlliste im Seitenheader aus.
  3. Klicken Sie oben rechts auf Erstellen.
  4. Wählen Sie diese Option, um einen Inhaltstyp (kein digitaler Assettyp) zu erstellen. Wiederholen Sie diesen Vorgang für alle erforderlichen Inhaltstypen.

Diese Abbildung zeigt das Dialogfeld "Assettyp erstellen" in der Oracle Content Management-Webbenutzeroberfläche.

Wir erstellen vier Inhaltstypen mit jeweils eigenen Feldern:

Der erste Inhaltstyp, OCEGettingStartedHomePage, muss die folgenden Felder enthalten:

Anzeigename Feldtyp Erforderlich Rechnername
Unternehmensname Einwertiges Textfeld X company_name
Firmenlogo Einwertiges Textfeld X company_logo
Themen Mehrfachwert-Referenzfeld X Themen
Kontakt-URL Einwertiges Textfeld X contact_url
URL Einwertiges Textfeld X about_url

So sollte Ihre OCEGettingStartedHomePage-Contenttypdefinition aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedHomePage". Sie enthält folgende Datenfelder: Firmenname, Unternehmenslogo, Themen, Kontakt-URL und Info-URL.

Der zweite Inhaltstyp, OCEGettingStartedTopic, muss das folgende Feld enthalten:

Anzeigename Feldtyp Erforderlich Rechnername
Thumbnail Bildfeld mit einem Wert X Thumbnail

So sollte der Inhaltstyp OCEGettingStartedTopic aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedTopic". Es enthält dieses Datenfeld: Thumbnail.

Der dritte Inhaltstyp, OCEGettingStartedAuthor, muss die folgenden Felder enthalten:

Anzeigename Feldtyp Erforderlich Rechnername
Avatar Bildfeld mit einem Wert X Avatar

So sollte der Inhaltstyp OCEGettingStartedAuthor aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedAuthor". Es enthält dieses Datenfeld: Avatar.

Der vierte und der letzte Inhaltstyp, OCEGettingStartedArticle, müssen die folgenden Felder aufweisen:

Anzeigename Feldtyp Erforderlich Rechnername
Veröffentlichungsdatum Einzelwert-Datumsfeld X published_name
Autor Einzelwert-Referenzfeld X Autor
Bild Bildfeld mit einem Wert X Bild
Bildunterschrift Einwertiges Textfeld X image_caption
Inhalt des Artikels Einzelwert-Großtextfeld X article_content
Thema Einzelwert-Referenzfeld X Thema

So sollte der Inhaltstyp OCEGettingStartedArticle aussehen:

Diese Abbildung zeigt die Definition für den Inhaltstyp "OCEGettingStartedArticlePage". Es enthält folgende Datenfelder: Veröffentlichungsdatum, Autor, Bild, Bildbeschriftung, Artikelinhalt und Thema.

Nachdem Sie die Inhaltstypen erstellt haben, können Sie diese Inhaltstypen dem zuvor erstellten Repository OCEGettingStartedRepository hinzufügen:

  1. Melden Sie sich als Administrator bei der Oracle Content Management-Webbenutzeroberfläche an.
  2. Navigieren Sie zu OCEGettingStartedRepository.
  3. Bearbeiten Sie das Repository, und geben Sie unter Anlagentypen alle vier neu erstellten Inhaltstypen an. Klicken Sie auf Speichern, um die Änderungen zu speichern.

Diese Abbildung zeigt die Seite "Repository bearbeiten" in Oracle Content Management mit den vier neu erstellten Inhaltstypen, die mit dem Repository OCEGettingStartedRepository verknüpft sind.

Nachdem Sie die Inhaltstypen zum Repository hinzugefügt haben, können Sie das Repository OCEGettingStartedRepository auf der Seite Assets öffnen und mit dem Erstellen der Inhaltselemente für alle Inhaltstypen beginnen.

Diese Abbildung zeigt Inhaltselemente auf der Seite "Anlagen" in der Oracle Content Management-Webbenutzeroberfläche mit Optionen auf der linken Seite für Sammlungen, Kanäle, Sprachen, Typen, Auswahl von Inhaltselementen und Status.

Schritt 2: Bloganwendung in Xcode erstellen

Um unsere Oracle Content Management-Inhalte in einer iOS-Anwendung zu nutzen, können wir das iOS-Blogbeispiel verwenden, das als Open-Source-Repository unter GitHub verfügbar ist.

Hinweis: Beachten Sie, dass die Verwendung des iOS-Beispiels optional ist und wir es in diesem Tutorial für den schnellen Einstieg verwenden. Sie können auch Ihre eigene iOS-Anwendung erstellen.

So bauen Sie den Blog in Swift auf:

  1. Beispiel-Repository kopieren
  2. iOS-Anwendung konfigurieren
  3. Content mit dem Content-SDK abrufen

Beispiel-Repository kopieren

Das iOS-Blogbeispiel ist als Open-Source-Repository unter GitHub verfügbar.

Zunächst müssen Sie das Beispiel von GitHub auf Ihren lokalen Rechner klonen:

git clone https://github.com/oracle-samples/oce-ios-blog-sample.git

Nachdem Sie das Beispiel geklont haben, öffnen Sie die Xcode-Projektdatei BlogDemo.xcodeproj.

Wenn Sie das Beispielprojekt in Xcode öffnen, wird automatisch die Abhängigkeit für Contentmanagement-Swift in das Swift-Package einbezogen, das das Oracle Content Delivery SDK implementiert.

Für diese Anwendung sind keine anderen Drittanbieterabhängigkeiten vorhanden. Daher sind keine weiteren manuellen Installationen erforderlich. Vor der Ausführung der Anwendung ist jedoch eine zusätzliche Konfiguration erforderlich.

iOS-Anwendung konfigurieren

In diesem iOS-Blogbeispiel müssen Sie einige Informationen konfigurieren, damit das Oracle Content Management Content SDK die richtige Instanz-URL mit dem richtigen Kanaltoken als Ziel festlegen kann. Diese Werte werden jedes Mal verwendet, wenn Ihre Anwendung Daten von Ihrer Oracle Content Management-Instanz anfordert.

Öffnen Sie die Datei credentials.json, und ändern Sie beide Schlüssel/Wert-Paare, um Ihre Instanz-URL und das mit Ihrem Veröffentlichungskanal verknüpfte Kanaltoken widerzuspiegeln. Der Kanal für dieses Tutorial ist OCEGettingStartedChannel.

{
    "url": "https://samples.mycontentdemo.com",
    "channelToken": "47c9fb78774d4485bc7090bf7b955632"
}

Content mit dem Content-SDK abrufen

Oracle Content Management bietet ein Swift-Package (Content-Management-Swift), das aus den OracleContentCore- und OracleContentDelivery-Bibliotheken besteht, um Inhalte in Ihren Anwendungen zu erkennen und zu verwenden. Das Package wird auf GitHub gehostet.

Weitere Informationen zum Content-SDK für Swift finden Sie in der Oracle Content Management-Dokumentationsbibliothek:

Sie können diese Content-SDK-Bibliotheken nutzen, um Inhalte abzurufen und in unserer iOS-Anwendung wiederzugeben.

Anwendung einbetten

Um Daten anzufordern, müssen Sie einige erforderliche Informationen für Ihre Bibliothek angeben, die als Onboarding der Anwendung bezeichnet wird. Sie weisen bestimmte Informationen zu, sodass Anforderungen korrekt formatiert sind und auf die korrekte Instanz-URL verweisen.

Beim ersten Start der Anwendung wird in dieser Demo Onboarding.urlProvider als Instanz Ihrer eigenen Klasse MyURLProvider zugewiesen. Dadurch werden die Instanz-URL und das Kanaltoken eingerichtet, die von der Inhaltsbibliothek für jede Anforderung verwendet werden.

Während die Angabe eines URL-Providers nicht unbedingt erforderlich ist (da URL- und Tokeninformationen pro Anforderung angegeben werden können), reduziert die Zuweisung der Provider die für jede Aufrufsite erforderliche Codemenge.

@main
struct BlogDemo: App {
    init() {
        // ... 

        // The sample code expects the URL and channel token to be provided by ``OracleContentCore.Onboarding``
        // Assign your ``OracleContentCore.URLProvider`` implementation to the ``OracleContentCore.Onboarding.urlProvider`` property
        Onboarding.urlProvider = MyURLProvider()
        
        // ...
        
    }
}

Die MyURLProvider-Implementierung liest Daten aus credentials.json, um die URL und das Kanaltoken abzurufen.

{
    "url": "https://samples.mycontentdemo.com",
    "channelToken": "47c9fb78774d4485bc7090bf7b955632"
}

Jedes Mal, wenn die Oracle-Inhaltsbibliothek eine Anforderung erstellen muss, wird die folgende Eigenschaft abgerufen:

/// This function provides the URL to be used for each OracleContentCore request
///
/// Services which implement ``OracleContentCore.ImplementsOverrides`` may provide a different URL and
/// authorization headers (if required) on a call-by-call basis
public var url: () -> URL? = {
  return URL(string: MyURLProvider.credentials.url)
}

Jedes Mal, wenn die Bibliothek eine Anforderung erstellen muss, wird auch das Zustellungstoken abgerufen:

/// This function provides the delivery channel token to be used for each OracleContentCore request
///
/// Services which implement ``OracleContentCore.ImplementsChannelToken`` may override this value
/// on a call-by-call basis
public var deliveryChannelToken: () -> String? = {
  
  return MyURLProvider.credentials.channelToken
}

Darüber hinaus bietet die Zuweisung zu Onboarding.logger die Möglichkeit, Ihre eigene Loggingimplementierung zu definieren. Für diese Demo besteht die MyLogger-Implementierung aus einem einfachen "Drucken" an die Konsole. In Produktionsumgebungen kann Ihr Logger universelles Logging, Kerndaten oder beliebige Technologien verwenden.

@main
struct BlogDemo: App {
    init() {
        // ... 

         Onboarding.logger = MyLogger()
        
        // ...
        
    }
}

Daten mit der Oracle Content-Library anfordern

Hinweis: Der gesamte Netzwerkanforderungscode für diese Demo finden Sie unter BlogNetworking.swift.

Jetzt können wir das Content-SDK nutzen, um Inhalte abzurufen und in der iOS-Anwendung wiederzugeben.

Die Datei BlogNetworking.swift enthält den gesamten Code zum Abrufen von Daten für die Anwendung. Das jeder Seite zugeordnete Modellobjekt ruft verschiedene Methoden auf, um Oracle Content Management-Daten abzurufen.

Homepage-Daten

Die Homepage unserer Anwendung ist BlogDemoMain.swift, eine SwiftUI-Datei mit einem verknüpften Modellobjekt. Das Modellobjekt ist dafür verantwortlich, den Status der Seite beizubehalten und die zum Starten des Datenabrufprozesses erforderlichen Funktionsaufrufe auszugeben. Wenn Daten empfangen werden, ändert sich der Status der Seite, und SwiftUI aktualisiert die UI entsprechend.

Zunächst fordert die Hauptseite zwei verschiedene Datenelemente an:

  1. Zuerst fragen wir nach dem Inhaltselement ab, das die Homepage des Blogs darstellt.
  2. Dann laden wir das vom Inhaltselement referenzierte Logo herunter.

Öffnen Sie BlogNetworking.swift, und suchen Sie die Funktion fetchHomePage(), die die anfängliche Anforderung ausführt.

/// Retrieve the content item which represents the home page of the blog
/// - returns: Asset
public func fetchHomePage() async throws -> Asset {
    let typeNode = QueryNode.equal(field: "type", value: "OCEGettingStartedHomePage")
    let nameNode = QueryNode.equal(field: "name", value: "HomePage")
    let q = QueryBuilder(node: typeNode).and(nameNode)
    
    let result = try await DeliveryAPI
        .listAssets()
        .query(q)
        .fields(.all)
        .limit(1)
        .fetchNextAsync()
        .items
        .first
       
    guard let foundResult = result else {
        throw BlogNetworkingError.homePageNotFound
    }
    
    return foundResult
}

Diese Funktion verwendet Swift-Nebenläufigkeit, um Daten anzufordern. Beachten Sie, dass alle Anforderungsobjekte (oder Services) in DeliveryAPI angegeben sind. In diesem Beispiel lautet das Anforderungsobjekt listAssets().

Im Anschluss an das Anforderungsobjekt stehen eine Reihe von Builder-Komponenten zur Verfügung, mit denen wir unsere Anforderung optimieren können. Hier haben wir einige Abfragedetails angegeben, alle Felder abgerufen und unsere Antwortdaten auf ein einzelnes Objekt beschränkt.

Unsere Anforderung an Oracle Content Management wird mit dem Aufrufverb fetchNextAsync() weitergeleitet.

Hinweis: Da unser Anforderungsobjekt mit "list" beginnt, beginnt das Aufrufverb mit "fetchNext".

"List"-Anforderungen geben Daten zurück, die angeben, wie viele Datensätze zurückgegeben wurden, ob mehr Daten vorhanden sind, und eine Ergebniszusammenstellung (in der Eigenschaft "Elemente").

Unsere Funktion bezieht den ersten Wert aus der Eigenschaft "items" und gibt ihn zurück. Dies ist das Asset, das unseren Blog darstellt und die Logo-ID, den Firmennamen, die Info- und Kontakt-URLs sowie eine Themenliste enthält.

Mit der verfügbaren Logo-ID können wir unsere zweite Anfrage zum Herunterladen des Logos stellen:

/// Download the logo for display on the home page
/// - parameter logoId: The identifier of the logo to download
/// - returns: BlogImageState 
public func fetchLogo(logoId: String?) async throws -> BlogImageState {
    
    do {
        guard let logoID = logoId else { 
          throw BlogNetworkingError.missingLogoId 
        }
        
        let result = try await DeliveryAPI
            .downloadNative(identifier: logoID)
            .downloadAsync(progress: nil)
        
        guard let image = UIImage(contentsOfFile: result.result.path) else {
            throw OracleContentError.couldNotCreateImageFromURL(URL(string: result.result.path))
        }
        
        return .image(image)
        
    } catch {
        return .error(error)
    }

}

Unsere Anfrage und Aufrufe sind in dieser Funktion viel einfacher. Das Anforderungsobjekt wird mit downloadNative(identifier: logoID) erstellt und mit dem Aufrufverb downloadAsync weitergeleitet.

Wenn das Objekt heruntergeladen wurde, werden die Daten in eine UIImage konvertiert und als BlogImageState-Aufzählung mit dem Image selbst als verknüpften Wert zurückgegeben.

Hinweis: In diesem Beispiel wird die Enumeration BlogImageState verwendet, da die verschiedenen Imagestatus dargestellt werden können, ohne dass optionale Werte verwendet werden müssen. Dies macht die Aufnahme in SwiftUI sehr einfach.

Themendaten

Als unser Modell die Homepage-Daten angefordert hat, führte es einen Aufruf aus, der wie folgt aussah:

self.home = try await self.networking.fetchHomePage()   

Wenn die Homepage erfolgreich abgerufen wurde, müssen wir die Sammlung von Vermögenswerten finden, die die Themen in unserem Blog darstellen. Dazu bitten wir um das Feld "Themen", dessen Typ eine Reihe von Assets ist.

self.topics = try self.home.customField("topics") as [Asset]

BlogDemoMain.swift iteriert über diese Themensammlung und stellt jedes Element in einer Rasteransicht dar. Diese UI-Darstellung ist in Topic.swift und dem zugehörigen Modellobjekt TopicModel.swift definiert.

Um Informationen zu einem einzelnen Thema anzuzeigen, müssen wir zwei Aufgaben ausführen:

  1. Wir müssen die detaillierten Informationen zu jedem Thema abrufen.
  2. Wir müssen das Bild herunterladen, das von jedem Thema referenziert wird.

In TopicModel.swift rufen wir den Netzwerkcode an, um das vollständige Asset zu erhalten:

let fullAsset = try await self.networking.readAsset(assetId: self.topic.identifier)

Detaillierte Informationen zum Thema zu erhalten, ist ein einfacher Prozess. Erstellen Sie eine Leseanforderung mit der angegebenen ID, und rufen Sie die Daten ab.

/// Obtain detailed information about an Asset
/// - parameter assetId: The identifier of the asset to read
/// - returns: Asset
public func readAsset(assetId: String) async throws -> Asset {
    let result = try await DeliveryAPI
        .readAsset(assetId: assetId)
        .fetchAsync()
    
    return result
}

Hinweis: Alle Leseanforderungen geben ein einzelnes Objekt zurück und werden mit einem Aufrufverb weitergeleitet, das mit "fetch" beginnt.

Nachdem wir die detaillierten Informationen zu unserem Thema abgerufen haben, müssen wir die Daten extrahieren, die das Thumbnail definieren und dann herunterladen.

In TopicModel.swift erhalten wir die Thumbnail-Informationen, indem wir nach dem benutzerdefinierten Feld mit dem Namen "Thumbnail" fragen. Da benutzerdefinierte Felder zu einem von vielen verschiedenen Typen gehören können, müssen wir explizit angeben, dass es sich bei diesem Feld um einen Assettyp handelt. Nachdem wir das Asset erfolgreich gefunden haben, können wir es abrufen.

imageIdentifier = (try fullAsset.customField("thumbnail") as Asset).identifier

Wenn die ID verfügbar ist, kann TopicModel.swift den Netzwerkcode jetzt anfordern, um die mittlere Wiedergabe des Thumbnail-Images abzurufen.

let imageState = await self.networking.downloadMediumRendition(identifier: imageIdentifier)
return imageState

Der Netzwerkcode zum Abrufen des Images erstellt ein Anforderungsobjekt "downloadRendition", um eine Wiedergabe mit dem Namen "Mittel" im jpg-Format abzurufen. Das Aufrufverb zum Weiterleiten der Anforderung ist "downloadAsync".

Wenn das Objekt heruntergeladen wurde, werden die Daten in eine UIImage konvertiert und als BlogImageState-Aufzählung mit dem Image selbst als verknüpften Wert zurückgegeben.

/// Downloads the "Medium" rendition of an asset and returns the value as a `BlogImageState`
/// Note that any error while downloading the image will result in a placeholder image
public func downloadMediumRendition(identifier: String) async -> BlogImageState {
    
    do {
        let result = try await DeliveryAPI
                                .downloadRendition(identifier: identifier,
                                                   renditionName: "Medium",
                                                   format: "jpg")
                                .downloadAsync(progress: nil)
        
        guard let uiImage = UIImage(contentsOfFile: result.result.path()) else {
            throw OracleContentError.couldNotCreateImageFromURL(result.result)
        }
        
        return .image(uiImage)
        
    } catch {
        return .image(UIImage(systemName: "questionmark.circle")!)
    }

}

Da nun sowohl die detaillierten Themeninformationen als auch das Thumbnail-Bild vorhanden sind, kann SwiftUI die visuelle Darstellung eines Themas erstellen.

Diese Abbildung zeigt die UI, die ein Thema darstellt. Es enthält den Titel "How To", ein Thumbnail-Bild von Kaffeetassen mit kontaing latte und eine Beschreibung, die das Thema als Lernen definiert, um schöne Latte-Kunst zu schaffen und nur die richtige Tasse zu gießen.

Artikellistendaten

Wenn Sie auf ein Thema tippen, navigiert der Benutzer zu einer neuen Seite mit einer Liste von Artikeln, die dem ausgewählten Thema zugewiesen sind.

Das Erstellen der Artikelseiten ist dem Prozess zum Erstellen der Themenliste sehr ähnlich. Bei einer Themen-ID müssen Sie:

  1. Rufen Sie die Liste der Artikel für dieses Thema ab, und
  2. Rufen Sie für jeden Artikel die Thumbnail-Wiedergabe des Assets im "Bild"-Feld ab.

Beim Abrufen der Liste der Assets lautet das Anforderungsobjekt .listAssets().

Ohne weitere Builder-Komponenten würden alle veröffentlichten Assets aus dem in credentials.json angegebenen Veröffentlichungskanal abgerufen. Sie möchten jedoch nur die Assets abrufen, deren Typ OCEGettingStartedArticle lautet und deren Themeneigenschaft mit der übergebenen Themen-ID übereinstimmt.

/// Obtain the collection of articles for a given topic. Limited to a maximum of 50 articles for demo purposes.
/// - parameter topic: Asset
/// - returns: [Asset] representing the articles for the specified topic
public func fetchArticles(for topic: Asset) async throws -> [Asset] {

    let typeNode = QueryNode.equal(field: "type", value: "OCEGettingStartedArticle")
    let fieldsTopicNode = QueryNode.equal(field: "fields.topic", value: topic.identifier)
    let fullQuery = QueryBuilder(node: typeNode).and(fieldsTopicNode)
    
    let result = try await DeliveryAPI
        .listAssets()
        .query(fullQuery)
        .order(.field("fields.published_date", .desc))
        .limit(50)
        .fetchNextAsync()
    
    return result.items
}

Für jeden der abgerufenen Artikel müssen wir festlegen, welches Bild heruntergeladen werden soll. Wir erhalten die ID des Assets, auf das im Feld "Image" verwiesen wird, und leiten damit eine Anforderung zum Herunterladen des Thumbnails weiter.

let identifier = (try article.customField("image") as Asset).identifier
let image = await self.networking.downloadThumbnail(identifier: identifier, fileGroup: article.fileGroup)

Der Netzwerkcode zum Anfordern des Downloads sieht folgendermaßen aus:

/// Downloads the thumbnail rendition of an asset and returns the values as a ``BlogImageState``
/// Note that any error while downloading the image will result in a placeholder image
/// - parameter identifier: The identifier of the asset
/// - parameter fileGroup: The file group of the asset - used to differentiate thumbnails for digital assets, videos and "advanced videos"
public func downloadThumbnail(identifier: String, fileGroup: String) async -> BlogImageState {
    do {
        let result = try await DeliveryAPI
            .downloadThumbnail(identifier: identifier, fileGroup: fileGroup)
            .downloadAsync(progress: nil)
        
        guard let uiImage = UIImage(contentsOfFile: result.result.path()) else {
           throw OracleContentError.couldNotCreateImageFromURL(result.result)
        }
        
        return .image(uiImage)
    } catch {
        Onboarding.logError(error.localizedDescription)
        return .image(UIImage(systemName: "questionmark.circle")!)
    }
}

Wir können jetzt eine Vorschau jedes Artikels anzeigen:

Diese Abbildung zeigt eine Vorschau eines Artikels. Es enthält den Titel "Create Beautiful Latte Art", ein formatiertes Datum, das angibt, wann der Artikel veröffentlicht wurde, ein Miniaturbild von Kaffeetassen mit kontaing latte und einem beschreibenden Text über den Artikel - dass "Mit ein wenig Übung können Sie Designs mit gedämpfter Milch erstellen."

Artikeldaten

Wenn Sie auf eine Artikelvorschau tippen, wird die endgültige Seite der Beispielanwendung angezeigt, d.h. der Artikel selbst. Wie zuvor müssen mehrere Datenanforderungen ausgeführt werden:

  1. Angesichts der ID des ausgewählten Artikels müssen wir seine ausführlichen Informationen abrufen.
  2. Laden Sie den Avatar des Autors herunter.
  3. Laden Sie das anzuzeigende Artikelbild herunter.
@MainActor
func fetchArticle() async throws {

    self.article = try await self.networking.readArticle(assetId: article.identifier)
    
    let author: Asset = try self.article.customField("author")
    let authorAvatar: Asset = try author.customField("avatar")

    Task {
        self.avatar = await self.networking.downloadNative(identifier: authorAvatar.identifier)
    }
    
    Task {
        let hero: Asset = try self.article.customField("image_16x9")
        self.heroImage = await self.networking.downloadNative(identifier: hero.identifier)
    }
}

Das Lesen der detaillierten Informationen für eine Anlage ist ein einfacher Prozess:

/// Obtain detailed information about an Asset
/// - parameter assetId: The identifier of the asset to read
/// - returns: Asset
public func readAsset(assetId: String) async throws -> Asset {
    let result = try await DeliveryAPI
        .readAsset(assetId: assetId)
        .fetchAsync()
    
    return result
}

Das Herunterladen des Avatars und der Artikelbilder erfolgt nach demselben allgemeinen Muster, das zum Abrufen anderer Bilder verwendet wurde:

/// Downloads the native rendition of an asset and returns the values as a ``BlogImageState``
/// Note that any error while downloading the image will result in a placeholder image
public func downloadNative(identifier: String) async -> BlogImageState {
    do {
        let result = try await DeliveryAPI
            .downloadNative(identifier: identifier)
            .downloadAsync(progress: nil)
        
        guard let uiImage = UIImage(contentsOfFile: result.result.path()) else {
           throw OracleContentError.couldNotCreateImageFromURL(result.result)
        }
        
        return .image(uiImage)
    } catch {
        Onboarding.logError(error.localizedDescription)
        return .image(UIImage(systemName: "questionmark.circle")!)
    }
    
}

Das Ergebnis ist ein vollständig formatierter Blog-Artikel:

Diese Abbildung zeigt einen vollständigen Blogartikel. Es enthält Informationen über den Autor (einschließlich eines Avatar-Bildes), das Bild, das verwendet wird, um den Artikel und den HTML-formatierten Text des Artikels darzustellen.

Schritt 3: Anwendung ausführen

Wenn Ihre Anwendung abgeschlossen ist, können Sie sie im Simulator ausführen oder in einem beliebigen iPhone oder iPad mit iOS oder iPadOS 16.0 oder höher bereitstellen.

Schlussfolgerung

In diesem Tutorial haben wir eine iOS-Bloganwendungssite erstellt, die auf GitHub zu finden ist. Diese Anwendung verwendet Oracle Content Management als Headless-CMS. Nachdem Sie Oracle Content Management mit einem Kanal veröffentlichter Inhalte für das Blog-Tutorial eingerichtet und konfiguriert haben, haben wir die Anwendung ausgeführt, um den erforderlichen Inhalt abzurufen.

Weitere Informationen zu Swift finden Sie auf der Swift-Website.

Weitere Informationen zu wichtigen Oracle Content Management-Konzepten finden Sie in der Dokumentation.

Weitere Beispiele finden Sie auf der Oracle Content Management-Seite Beispiele im Oracle Help Center.