iOS-app
[AEM, hoofdloos as a Cloud Service]{class="badge informative"}
Voorbeeldtoepassingen zijn een geweldige manier om de mogelijkheden zonder kop van Adobe Experience Manager (AEM) te verkennen. Deze iOS-toepassing laat zien hoe u inhoud kunt opvragen met behulp van AEM GraphQL API's met behulp van doorlopende query's.
Bekijk de broncode op GitHub
Vereisten prerequisites
De volgende gereedschappen moeten lokaal worden geïnstalleerd:
AEM
De iOS-toepassing werkt met de volgende AEM implementatieopties. Alle plaatsingen vereisen de Plaats van WKND v3.0.0+om worden geïnstalleerd.
- AEM as a Cloud Service
- De lokale opstelling die SDK van AEM Cloud Servicegebruikt
De toepassing van iOS wordt ontworpen om met een AEM het milieu van Publish te verbinden, nochtans kan het inhoud van AEM Auteur als de authentificatie in de configuratie van de toepassing van iOS wordt verstrekt.
Hoe wordt het gebruikt
-
De gegevensopslagruimte
adobe/aem-guides-wknd-graphql
klonen:code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
-
Open Xcodeen open de omslag
ios-app
-
Wijzig het bestand
Config.xcconfig
en werkAEM_SCHEME
enAEM_HOST
bij zodat deze overeenkomen met uw doel AEM Publish-service.code language-plain // The http/https protocol scheme used to access the AEM_HOST AEM_SCHEME = https // Target hostname for AEM environment, do not include http:// or https:// AEM_HOST = publish-p123-e456.adobeaemcloud.com
Als u verbinding maakt met AEM auteur, voegt u de eigenschappen
AEM_AUTH_TYPE
en support voor verificatie toe aan deConfig.xcconfig
.Basisauthentificatie
Met
AEM_USERNAME
enAEM_PASSWORD
kunt u een lokale AEM verifiëren met toegang tot WKND GraphQL-inhoud.code language-plain AEM_AUTH_TYPE = basic AEM_USERNAME = admin AEM_PASSWORD = admin
Symbolische authentificatie
AEM_TOKEN
is een toegangstokendat aan een AEM gebruiker met toegang tot de inhoud van GraphQL WKND voor authentiek verklaart.code language-plain AEM_AUTH_TYPE = token AEM_TOKEN = abcd...0123
-
De toepassing samenstellen met behulp van Xcode en de toepassing implementeren in iOS-simulator
-
Een lijst met avonturen van de WKND-site moet in de toepassing worden weergegeven. Het selecteren van een avontuur opent de avontuurdetails. Voor de avonturenlijstmening, trek om de gegevens van AEM te verfrissen.
De code
Hieronder volgt een overzicht van hoe de iOS-toepassing is gebouwd, hoe deze verbinding maakt met AEM Headless om inhoud op te halen met GraphQL persisted query's en hoe deze gegevens worden gepresenteerd. De volledige code kan op GitHubworden gevonden.
Blijvende query's
Na AEM Beste praktijken zonder hoofd, gebruikt de toepassing van iOS AEM GraphQL voortgezette vragen om avontuurgegevens te vragen. De toepassing gebruikt twee voortgeduurde vragen:
wknd/adventures-all
persisted query, die alle avonturen in AEM met een verkorte set eigenschappen retourneert. Deze hardnekkige vraag drijft de aanvankelijke lijst van het avontuur van de mening.
# Retrieves a list of all Adventures
#
# Optional query variables:
# - { "offset": 10 }
# - { "limit": 5 }
# - {
# "imageFormat": "JPG",
# "imageWidth": 1600,
# "imageQuality": 90
# }
query ($offset: Int, $limit: Int, $sort: String, $imageFormat: AssetTransformFormat=JPG, $imageWidth: Int=1200, $imageQuality: Int=80) {
adventureList(
offset: $offset
limit: $limit
sort: $sort
_assetTransform: {
format: $imageFormat
width: $imageWidth
quality: $imageQuality
preferWebp: true
}) {
items {
_path
slug
title
activity
price
tripLength
primaryImage {
... on ImageRef {
_path
_dynamicUrl
}
}
}
}
}
wknd/adventure-by-slug
persisted query, die één avontuur retourneert vanslug
(een aangepaste eigenschap die een avontuur op unieke wijze identificeert) met een volledige set eigenschappen. Dit bleef vraagbevoegdheden de meningen van het avontuurdetail.
query ($slug: String!, $imageFormat:AssetTransformFormat=JPG, $imageSeoName: String, $imageWidth: Int=1200, $imageQuality: Int=80) {
adventureList(
filter: {slug: {_expressions: [{value: $slug}]}}
_assetTransform: {
format: $imageFormat
seoName: $imageSeoName
width: $imageWidth
quality: $imageQuality
preferWebp: true
}) {
items {
_path
title
slug
activity
adventureType
price
tripLength
groupSize
difficulty
price
primaryImage {
... on ImageRef {
_path
_dynamicUrl
}
}
description {
json
plaintext
html
}
itinerary {
json
plaintext
html
}
}
_references {
... on AdventureModel {
_path
slug
title
price
__typename
}
}
}
}
GraphQL-query uitgevoerd
AEM voortgeduurde vragen worden uitgevoerd over de GET van HTTP en zo, kunnen de gemeenschappelijke bibliotheken van GraphQL die de POST van HTTP zoals Apollo gebruiken, niet worden gebruikt. In plaats daarvan, creeer een douaneklasse die de voortgezette vraagHTTP- verzoeken aan AEM uitvoert.
AEM/Aem.swift
instantieert de klasse Aem
die wordt gebruikt voor alle interacties met AEM Headless. Het patroon is:
-
Elke voortgezette query heeft een overeenkomende openbare functie (bijv.
getAdventures(..)
ofgetAdventureBySlug(..)
) de weergave van de iOS-toepassing wordt aangeroepen om gegevens over avontuur op te halen. -
De openbare functie roept een privéfunctie
makeRequest(..)
aan die een asynchrone HTTP-aanvraag tot AEM Headless aanroept en de JSON-gegevens retourneert. -
Elke openbare functie decodeert vervolgens de JSON-gegevens en voert de vereiste controles of transformaties uit voordat de Adventure-gegevens naar de weergave worden geretourneerd.
- AEM GraphQL JSON-gegevens worden gedecodeerd met de structs/klassen die zijn gedefinieerd in
AEM/Models.swift
, die zijn toegewezen aan de JSON-objecten en die mijn AEM Headless hebben geretourneerd.
- AEM GraphQL JSON-gegevens worden gedecodeerd met de structs/klassen die zijn gedefinieerd in
/// # getAdventures(..)
/// Returns all WKND adventures using the `wknd-shared/adventures-all` persisted query.
/// For this func call to work, the `wknd-shared/adventures-all` query must be deployed to the AEM environment/service specified by the host.
///
/// Since HTTP requests are async, the completion syntax is used.
func getAdventures(params: [String:String], completion: @escaping ([Adventure]) -> ()) {
let request = makeRequest(persistedQueryName: "wknd-shared/adventures-all", params: params)
URLSession.shared.dataTask(with: request) { (data, response, error) in
if ((error) != nil) {
print("Unable to connect to AEM GraphQL endpoint")
completion([])
} else if (!data!.isEmpty) {
let adventures = try! JSONDecoder().decode(Adventures.self, from: data!)
DispatchQueue.main.async {
completion(adventures.data.adventureList.items)
}
}
}.resume();
}
...
/// #makeRequest(..)
/// Generic method for constructing and executing AEM GraphQL persisted queries
private func makeRequest(persistedQueryName: String, params: [String: String] = [:]) -> URLRequest {
// Encode optional parameters as required by AEM
let persistedQueryParams = params.map { (param) -> String in
encode(string: ";\(param.key)=\(param.value)")
}.joined(separator: "")
// Construct the AEM GraphQL persisted query URL, including optional query params
let url: String = "\(self.scheme)://\(self.host)/graphql/execute.json/" + persistedQueryName + persistedQueryParams;
var request = URLRequest(url: URL(string: url)!);
// Add authentication to the AEM GraphQL persisted query requests as defined by the iOS application's configuration
request = addAuthHeaders(request: request)
return request
}
...
GraphQL-responsgegevensmodellen
iOS geeft de voorkeur aan het toewijzen van JSON-objecten aan getypte gegevensmodellen.
src/AEM/Models.swift
bepaalt decodableSwift structs en klassen die aan de AEM JSON reacties in kaart brengen die door AEM JSON reacties zijn teruggekeerd.
Weergaven
SwiftUI wordt gebruikt voor de diverse meningen in de toepassing. Apple verstrekt een het worden begonnen leerprogramma voor bouwend lijsten en navigatie met SwiftUI.
-
WKNDAdventuresApp.swift
De vermelding van de toepassing en bevat
AdventureListView
waarvan de.onAppear
-gebeurtenishandler wordt gebruikt om alle avonturgegevens op te halen viaaem.getAdventures()
. Het gedeeldeaem
voorwerp wordt hier geïnitialiseerd, en blootgesteld aan andere meningen als EnvironmentObject. -
Views/AdventureListView.swift
Hiermee geeft u een lijst met avonturen weer (op basis van de gegevens van
aem.getAdventures()
) en geeft u een lijstitem voor elk avontuur weer met behulp vanAdventureListItemView
. -
Views/AdventureListItemView.swift
Toont elk punt in de avonturenlijst (
Views/AdventureListView.swift
). -
Views/AdventureDetailView.swift
Toont de details van een avontuur met inbegrip van de titel, de beschrijving, de prijs, het type van activiteit, en primair beeld. In deze weergave wordt AEM gevraagd of er details zijn met betrekking tot volledige avontuur met
aem.getAdventureBySlug(slug: slug)
, waarbij de parameterslug
wordt doorgegeven op basis van de rij met de selectielijst.
Externe afbeeldingen
Afbeeldingen waarnaar wordt verwezen door adventure Content Fragments, worden AEM. Deze iOS-toepassing gebruikt het veld path _dynamicUrl
in de GraphQL-reactie en plaatst de voorvoegsels AEM_SCHEME
en AEM_HOST
voor het maken van een volledig gekwalificeerde URL. Als _dynamicUrl
zich ontwikkelt tegen de AE SDK, wordt null geretourneerd, zodat de ontwikkeling terugvalt op het _path
-veld van de afbeelding.
Als verbinding wordt gemaakt met beveiligde bronnen op AEM waarvoor toestemming vereist is, moeten ook referenties worden toegevoegd aan afbeeldingsaanvragen.
SDWebImageSwiftUIen SDWebImageworden gebruikt om de verre beelden van AEM te laden die het beeld van het Avontuur op AdventureListItemView
en AdventureDetailView
meningen bevolken.
De aem
-klasse (in AEM/Aem.swift
) vereenvoudigt het gebruik van AEM afbeeldingen op twee manieren:
-
aem.imageUrl(path: String)
wordt gebruikt in weergaven om het AEM aan te vullen en het pad van de afbeelding te hosten, zodat een volledig gekwalificeerde URL wordt gemaakt.code language-swift // adventure.image() => /adobe/dynamicmedia/deliver/dm-aid--741ed388-d5f8-4797-8095-10c896dc9f1d/example.jpg?quality=80&preferwebp=true let imageUrl = aem.imageUrl(path: adventure.image()) // imageUrl => https://publish-p123-e456.adobeaemcloud.com/adobe/dynamicmedia/deliver/dm-aid--741ed388-d5f8-4797-8095-10c896dc9f1d/example.jpg?quality=80&preferwebp=true
-
De
convenience init(..)
inAem
stelt HTTP-autorisatieheaders in op de HTTP-afbeeldingsaanvraag op basis van de configuratie van iOS-toepassingen.- Als basisauthentificatie wordt gevormd, dan wordt de basisauthentificatie in bijlage aan alle beeldverzoeken.
code language-swift /// AEM/Aem.swift /// /// # Basic authentication init /// Used when authenticating to AEM using local accounts (basic auth) convenience init(scheme: String, host: String, username: String, password: String) { ... // Add basic auth headers to all Image requests, as they are (likely) protected as well SDWebImageDownloader.shared.setValue("Basic \(encodeBasicAuth(username: username, password: password))", forHTTPHeaderField: "Authorization") }
- Als symbolische authentificatie wordt gevormd, dan is de symbolische authentificatie in bijlage aan alle beeldverzoeken.
code language-swift /// AEM/Aem.swift /// /// # Token authentication init /// Used when authenticating to AEM using token authentication (Dev Token or access token generated from Service Credentials) convenience init(scheme: String, host: String, token: String) { ... // Add token auth headers to all Image requests, as they are (likely) protected as well SDWebImageDownloader.shared.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") }
- Als geen authentificatie wordt gevormd, dan wordt geen authentificatie in bijlage aan beeldverzoeken.
Een gelijkaardige benadering kan met SwiftUI-inheemse AsyncImageworden gebruikt. AsyncImage
wordt ondersteund door iOS 15.0+.