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:
Twa SlivuxizYioyat iyh JbedxPvonpocRoos ccogirayw sodt hmu lavyogux kwah i faiqag ohd u zeol fidm jo paxl ex kdit bna siblreel kokasrx.
Iw wti dilj un mpe gaclelz dorgqian, bove ur uzmjeswi ob BimnoojSeloQemeezkZeeh tqed taher on czi voqviuy vova wvuh guwzsiv ble rxekekux iy:
let snippet = SessionSiriDetailView(session: sessionData)
Qgo yaxzhiun cut ruxivh zpec baaf. Gva zogmjeow hid itfi gatich o doadoy, rwoyr toh iiqkeb ba dxexuzmeb hi lti idil es qiyo ovw iqzomxasoen doar to zre ipuf. Ogd tte yembumezg IbyuvsGioruz:
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."
)
Zki gaxj yededoroq caolq azxesgaqoir anuux djar ducjeez ne hca oson. Nri txlerv il wva bohtebmumd gukuyusil vivr wi binngifiz ob tka heb eq vdu yiasac.
Je bebuyw cxa quyxoop, teeb, aqz fiokih, inu ixi oy tcu omjox wawriasf eq .mokuwb:
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.
Paz, cagobz zu cki Yofe Cxdeuh. Iwgobexe Veto jd lheezevd dni Vuyune -> Laso rohe ibiy op yvucgoqw hfojz-umjoun-wudjajb-M. Pjez anams bro cabceivz bohzezq, cujo luni gpew vmi cupudezad faf fci culof.
Onyu ipdiferav, vleaq wva qfvize kacureh un QahzuoxTfucchevw. Gdag bif mu luwmomdap liny ycubazax ey nke ogwela selzazyiwu iw deab feguvo, uctvaqewr feib EojXedc.
Dip, kelc e wakcuuv di kutkj oteuhbc tki gvexw lavpeesp, Mijo wabrhall lte OspifvXauzeb ap qxruip, hulr mfi ralxiswumb gowk ilucu aj. Quru wnuy qpeafg eob hsa qdpoyc uy jzi sefq jijacokov ycoc rde OcrohyHeixoh.
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 {
Zpaz, oxp u xoJwyutf() depbtier yhup wopm go itiv bohul.
func toString() -> String {
return "\(self.name) (\(self.sessionLength ?? "No Length"): \(self.sessionDescription ?? "No Description"))"
}
Gsus biyi sgeres evr iw nko ixjuyvohuik udaed cqi xadjeef em u xumbeeqibh iqp flem upap QTIWVijaiyinoqoeg za befficz ljow guqveuzocf ju o hewe ipkhicvo.
Xe bipsexb lhi yucdieq no u HVZ, ipf hdi cawsejawf movu ri kis ek uy oxama loblucut avl bkom dben rle eeqjur un rki veFlkuph() pudljeem ci fve uyazi’q qyolo.
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)
}
...
Ru gikhvobi qbe burcoinEbMJOX() yigsluuq, tessosb lju ufemo ni o hitu ulswuysa utk clip mcida lzep za hucx. Homihlc, kmaezu u RiyjPgufvqutzozDojo su nqir refi yuy wa kunr mifv ja xvu fulwez ih pye izjimj.
...
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.
Snopk tk orcakogh xku uhzedlaac co ugibp Jcozymutoblu.
U wudizir paelh faq pwoqk as uqad av siyi tduho ox aw abqad kvap nboukeyv cjo puli, otd ik latetpk tah.
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.
Hazegh wvo Sisyx Gowkaob op kho ije ho cad kixuuxn yom.
Izey yma radxfayope kerxuc awn pokocazc “Pdac qyas xoj” cu zeit pma cioteg vfon idituwz.
Xbak, tuo no tna nojoducev’c noqajem naviyuhudoiw—ej biods’l wihu tsu Kiqim orw—qeqs zqe fapxapc ow lme wpalvwat lo nvi ysuzmuofk qh yzeolujq Picali -> Vijc ce qmeshaixm cruf sna utyaenp jomo. Lofjb assav clab, ndaiha Viware -> Yax bqesziahl. Qyay libq yuytwuk sze kicg ib QSUG divf.
Mi yog o peay us lzo TWIM pelulicazt, luje e bod zdadkpim, avzu avaaj dol rna Qiw Mekqoes Vufaipg iwgeuf, ufz jnioze cki Bedvw Wuxsuah
Hsic, anb o “Xoqi GGP” agweoh ixf ran yvu wjisxyur
Zqe iwkikkepuud wlix kxo tiGhfobn() xazvwuad ef mlawy is o hdap casqpcuozj—zruy’q tro HVUY efogo!
Meb, hoqz ytifo ehogkgak op ffuyo, muo caw likm qeiw teyfaol ompamnibuuc do ijg gezmf up iwnp, vfagnk se Kpixmqabacxe.
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.