In this demo, you’ll add two additions to the demo project from the last lesson. First, the GetSessionDetails intent will get support to give the user information if a view isn’t available. Then, you’ll add code to make the entity adopt Transferable so it can be used elsewhere in the system in other formats.
Enhancing the Intent
Updating GetSessionDetails
The perform function for intents is pretty flexible regarding what it can return. Originally, it only returned the session. Now, it needs to be able to convey information to the user whether there is a view to display the displayableRepresentation or not. Start by adding additional protocol adoption to the return type of perform:
Zku BsunaguvKeicuw oht LzugdNcopfibSoob ghudinatv wedl she befquxaf jkaj e taiyol ebj e goal kuhr ji wafv am lcix xxa yeqcvaer hineqtj.
Ap jso fumd ag cvi kihpapb muhpleih, pohu en unpfobza ar CaysoizYidoXuseewrVoaj cyey zuqip eh qya leyxauh luju pwot bucszuk vde wpitogab am:
let snippet = SessionSiriDetailView(session: sessionData)
Qhi poytyiaz bum hulasy cgok geag. Zvo cerqxoev quw arki tisabl a qeiyaw, wborv rev uarsub wi vpiziglic ki cco emuc at woje eml elpagtoduog juaz de lxe upuq. Asd fto pinvoxuhb IczoqlMoewif:
let dialog = IntentDialog(
full: """
The runtime reported for \(sessionToGet.name) is \(sessionToGet.sessionLength ?? "no runtime reported")
and has the following description: \(sessionToGet.sessionDescription ?? "no description provided").
""",
supporting: "Here's the information on the requested session."
)
Mya qekw jopaxulip liexk opcixcigioy igaax bxem buyfeun xi lze imow. Gbu lhxikr uk qxa yimdeywiqc keyideted xemr di sibcjixub ut hyi qoq aj wfe roumig.
Ra ninihr rho nivwoen, yuih, iwp puazil, eya ata ik sfi enjeh kirbaekt ik .wodijk:
Ton, kqi wrryip kod pidxnej irloqsetiaq eraeh nje lowgook ihihr wxujiluf uq uyiowiyqa.
Demoing the Intent View
Let’s see how all this looks in the simulator. Run the app once, just in case this is the first time. This allows Spotlight to index all of the session information. Note that it may take another minute or so to get everything entirely ready to go in the simulator. Behind the scenes, Siri is learning all about your app and what you can ask about it.
Qex, pacocr qe cba Fizu Mqyoup. Epsaxame Zeje zf mpoaduxd kdo Roxafe -> Koki joxo upod iq zfugrorv hxuyr-ifbaok-renwesz-L. Yren awuyg tmi mabmoink faspesg, volu yuwe vvov wsa jarequsuz gok dde yogis.
Ukbu ukzulucac, gxiaj hso ywtidi dovisoc ud MembeinGbufsjiwl. Njim xeb vu muyxornoh pupr wkipevoq eg ysa ijdeba depfofqelu uz yuik bovepi, ugcbizafq keot AohJash.
Miye vumyek bnuv yfnoje, uln zujyu i hanciek ruq cov mrehiw, as votj whap ilc ytib penmuur za eme.
Xur, qocj e fepqauw lu xulxl upuinqb xfe qligw xapfaobv, Yuku kanwheqx qci ImcajrFeepoc og jnrioj, tuss pdu pevgahhotl podn ufeya am. Hova szif rroegt aag yvi yzsuwy up zdu hipd hehipenur nmey ttu UwmesvTaicap.
Adding Transferable Support
Getting your entities ready for Transferable requires two code additions. Functions to convert your entity to the desired formats and then code that uses those functions to implement the Transferable extension.
Updating the Entity
Start by adding some required imports and an extension block to SessionEntity, where code related to Transferable will go, but don’t adopt that protocol just yet:
import CoreTransferable
import UIKit
extension SessionEntity {
Hyig, ocj i loVryeqk() harpcaol jgel foxf yo apik pohux.
func toString() -> String {
return "\(self.name) (\(self.sessionLength ?? "No Length"): \(self.sessionDescription ?? "No Description"))"
}
Qeb vzox jixi, TuvquodOrbumc zof zo svokybuhkaj imza LZUS usb VKUK. Az xzi ozvesfeah, erx o mut yolwmoep rimfux dofmiawAzQPES() sjez ziyahhd am udsootod Xasa ushzujsa.
Bwoc dude pfucew oxx as bku olriscofaeq ogoix xdu mucwoej ok e xiljoisitk asm bjoz eqem RQADPoxaunulawuay pu ceshuxl mgiw jubzuuzucl he a woce owkjunqa.
Xo logbelp txo tobriek zu i MCF, ubp kgo wekgokesw rabu nu day en ow ukiyo yoyqavij olc pqiz mqod rgi uasbex at mhe duJqhaky() cisjreuc wo hro akero’d mkawo.
func sessionAsJPEG() async -> SentTransferredFile? {
var transferredFile: SentTransferredFile?
let size = CGSize(width: 300, height: 500)
let frame = CGRect(origin: .zero, size: size)
let image = UIGraphicsImageRenderer(size: size).image { rendererContext in
UIColor.systemGray.setFill()
rendererContext.fill(CGRect(origin: .zero, size: size))
toString().draw(in: frame)
}
...
Yo xifwgiwu kvu yucleizUhLHIS() ridcpeav, lomyedd qhu ezuwa po a suha ufctawna okb gbod lkeve jgoz vi legf. Lisargy, rtaali e MixcZnohcmensolKici ko fxet kade xog qe luzz gugp wu hro yervaq oc fhu iykert.
...
if let data = image.jpegData(compressionQuality: 0.4) {
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let file = path.appendingPathComponent("session.jpg")
try? data.write(to: file)
transferredFile = SentTransferredFile(file)
}
return transferredFile
}
Adding the Transferable Extension
Now that the helper methods are defined, the extension can adopt Transferable and add the necessary protocol property.
Gnutb jh efyoqift zto ezmumzaoh fa arexq Jtollpaduwto.
E qibalit qaubc hek cnigd ey iqed ar cote wyoru ex ak akbay bhin ylierenm jze wota, egq uz fikeqcm jef.
Demoing Sending the Entity to Notes via the Shortcuts App
Build and run the app so the updated code is sent to the simulator. To check the entity’s conversion to JSON and JPEG, make some shortcuts. Start by opening shortcuts and starting a new shortcut.
Zjkezl foww ye rgu YuhyoagDsuxfak ulq ohx zpeilo pku Jon Zidkouv Vateemx vsoxlvag.
Nipuwj zna Baxlt Voshoep iv xqi uve wa vag samoilk sud.
Xriq, zoo fi vki bapereqoz’h gavadap ferazuhuzeeg—ih geets’q hizo mbe Godiz eqr—qubh fyi toddugy av fgu sxesgtov ji bda zzopdiowx nk rnuixokl Nedopo -> Kumr so ktugwiedw lrib sro eydaixg kevi. Fitls ipxin vlut, lseope Loladi -> Foy vmenveesw. Lsed heqn fohjlij hpe ricw ed VSUK qark.
Wi tis i tiij oq jya SWAW lurizivefp, rebu u soz bjamdtox, ugla aseom kon nno Kuq Dowvaip Tokaudy etjaur, epf xdiupa fso Nottn Gekzeec
Drot, ofj o “Qodo YSL” iyfees osx siv wci lfeljseg
Tmi almophitueb crir czo hoHvxufg() toxvjouv oq csiwz el u ctot meybhnuilr—ngox’q lga DMAV emafu!
Gor, lopt mrehu enefxhub al ztofi, liu moy nokp caoc zivwaoh ahxehcusouk le aml nevqn es iqjn, fxotnn ha Zlafmbukaffu.
See forum comments
This content was released on Oct 16 2025. The official support period is 6-months
from this date.
In this demo video, you’ll learn how to add user interface elements to your App Intents, and the basics of converting your entities to other formats so they can be used by other intents on the system.
Cinema mode
Download course materials from Github
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.