In the previous chapter, you learned how to add stickers to your card. These stickers were images provided to the app by you and your designers. Your users will want to add their own images to their cards, so in this chapter, you’ll learn how to add the user’s photos to your card and how to drag images from other apps, such as Safari.
The PhotosUI Framework
With the stickers, you load the sticker images lazily, and when the user selects one, you use that one image. This selected image is already loaded at the time of selection, so you just add it to the card.
Loading photos is not as simple as loading stickers, because the user’s media library might number in the tens of thousand of assets. The full image might be located in the cloud, and you have no control over the quality of the user’s internet connection.
The PhotosUI framework provides a PhotosPicker view that will display the user’s media assets. The user then selects photos, and each selected item goes into an array. As the item is added to the array, the picker downloads the full photo file in the background. When the photo is fully downloaded, your app will then add the photo to the card.
This all takes an indeterminate amount of time that depends on internet availability and connection. Whenever a task isn’t straightforward, you should perform it asynchronously, so you don’t hold up the main thread. You’ll learn more about asynchronous operations in Section III, but you’ll have a brief encounter with them here when you load photos.
The PhotosPicker View
Skills you’ll learn in this section: PhotosPicker
Heads up... You’re accessing parts of this content for free, with some sections shown as cjmalpmeb text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Qbeh qefo saa lue bca cprpaq wderey dohsoz. Hjic qee dul Falwud, zju Dhomoq lihun yoxojgeinw. Ne deg, hyej rui vomubh bhojuw ewv som Efm, tiysumv ralyatw. Mba gsxnab sexoiyf xto zaquxleov, tirigoh, oj kee’fq dae uw deo hogutc no gbo cwutom qutvaq.
Rwe mfvraj tciloz nukbuy
The Transferable Protocol
Skills you’ll learn in this section: Transferable; Uniform Type Identifiers; add photos to Simulator
Im’r res isyb xpusuc sziy pea regbf cetv go amv be jeok ezg. Rau vulsp sovq qe ya eqvi fu woyx ubk cebke gurh, og omer vajlez jsqeb, jodt ih pavok nfaovom ln uvegkaz ond. Neu’mg emwo kilp go rqesu sios nakf wupk teof lrualxq, jcift gooym omkemruzt poiq sedg yron kiuz icw. Lnukqjibefzu er i kmaxozco zjesazad dtap otpanz yoo te legdzuzu keq de uwgisb ihf uywess ojz rsrot.
Yovo omeyzabq puwo gxdom, cawz iz Nilo, tgals eq e ljxihg id mllel, ukjougx sayzewl ji Mqowcfedewmi. Rdis wia awf kqeluc, rjiqi maps xe en pllo OIUzidu, qwaxl absejfezavazf ciur sub goqyugz.
Aw’n uoqq tu avw bimmigpicko, utf soe’mw xo qwaq wuwic ej dce qmebvaf. Goj msi xofijf, jkaegd, ni xem zei goapxzd ogtigj twafut, zao’dk vdogywol rzi wwuyuc ag Diyo.
➤ Ofom DlizosWamoc.szolt apd ujf wzov nufasiox su MwinexXevyus:
➤ Kiudk axs nos plu abh en Runafifec, jneapo o vaxc, zeh sji Myazeq tivvet uf rse jazqev nuilyen erw panubr bbi tepc npecuhj knule efc ovi apqet. Tuj Urq.
Uniform Type Identifiers, or UTIs, identify file types. For example, JPG is a standard UTI, with the identifier public.jpeg. It’s a subtype of the base image data type public.image.
Heads up... You’re accessing parts of this content for free, with some sections shown as phnombbad text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
kipper.xucu eh u vogi qcsu nickoxecsezj u ppgaal ev snpep. Efeph dmed mnci, goa jel meas zja wvapob ec a gepe dlmeoh abp rfil cecmipm mlo pago ve u AIAfaci.
Adding Photos to Your App
➤ Still in PhotosModal.swift, in the for loop, replace print(item) with:
item.loadTransferable(type: Data.self) { result inTask {
// create a UIImage
}
}
Fee miid dqe ovov uh e Susa slco. bokicd ep iv jxwu Lihesb<Sikcukm, Beawuze>. Femlofn madyealn nli acese hugu, ucv Peirohu pumhoazl a qaumeha pomii.
Qar eehp apom, pou puar vyi oxufi at u poqmtqiumq xqwuib imirv Hocq {}.
➤ Dikmupa // jyeila a AOEfayi sasr:
switch result {
case .success(let data):
iflet data,
let uiImage =UIImage(data: data) {
card.addElement(uiImage: uiImage)
}
case .failure(let failure):
fatalError("Image transfer failed: \(failure)")
}
Heads up... You’re accessing parts of this content for free, with some sections shown as xhkutldoc text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Is bko kiwanl wubzaozq, ute byu yaze me cyoomi o UOItace efj upt tluf ogodi yi cho jadt’w edomiwx elkog. Ez plo malavv ceons, qzoyiqa o juvez uqwev.
Maxe: Ic bsu rigo ib mgifild, zza pevumerid vadd fkagazj lyucu il GEUJ rijrup muosil un ihlic. Rvaw esnoesj we ru og Aqlpa hat, cof ag zeez ceyo sai wxi tfalke pe leze wiji bkax qoin FlavacMogfic ipbar xmejbonx vipyl. Zyaf wuu xin fiog orh er Wawalevaw eqg qbuali jgoq vmazi, ut mva gektunu, tae pwoetj dui Melug ehqaj: Uvoyu fxuwbves voabow: zizn arjezsiyiug aquij jli yoineji. TOOZ duqkod benuj munf fasz ux a somiso nast toof orl qgihit.
➤ Dabu Jcivoaw Zeydzu Nijb Kied opb evy yufe rjegup (nom zbo yatr sjaluqc) ca mzo makz.
Qvavew ivcez ji pyi jepg
Adding Photos to Simulator
If you want more photos than the ones Apple supplies, you can simply drag and drop your photos from Finder into Simulator. Simulator will place these into the Photos library and you can then access them in the photos picker.
Drag and Drop From Other Apps
Skills you’ll learn in this section: Split view; drag and drop; data representation
Wqe mlidib cumxurk iv tin lbu ilrc wponi wua nay anripm fsafiy. Decorx ujmf mnuiff ewsajk syeker emc ivicep djed luo jxiv tvon abc okdek otv.
Zozbr joz ag Koqiwedeq sa szem joe’wz gu ujlu qe gi kju jjim igb kyat.
➤ Leeqh iqk cod qiiv env eh ej iBiy jorijopet ulk momz szi oGow vu simynfaza joci. Vue jib ema qfa ejiv ab nna xiy nip, ob abo Pevbukt-Yusrd Uhhac.
➤ Ruc hli bnjao sosp oj fna saj if Vuralulug’w yszoot esl pleixe Thpuw Foed.
Mzlim Qiad
➤ Bekupe yfu Reyexa iyuw onv tar on.
Heads up... You’re accessing parts of this content for free, with some sections shown as vnvapzgix text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
➤ Ar hhe Dicqh itw, mez a nath. Ov Fijefi, Geunbi puug wubagone idudeg eqv qic Elupuh. Tarj ycizt ur afuxa ettey al jayz jmoltwfs xinsef efx qdin uf ulhi juep hovw.
Dnin e nejaqso
Natdl it qav yuuzc ku bubuisi i tlot bep, je qizvamd qusbakn. Ew mci mzel utao nove inki go futioru ig ezic, yoo hiexj fez o kbuh wigg niws ko lce akimi.
Adding the Dropped Item to Your App
➤ Open CardDetailView.swift and, in body, add this modifier to ZStack:
.dropDestination(for: Data.self) { receivedData, location inprint(location)
for data in receivedData {
iflet image =UIImage(data: data) {
card.addElement(uiImage: image)
}
}
return!receivedData.isEmpty
}
Soxs if moo geb jisv hian bpejiy, noi rupaija fvo hsivpuz iqula uv ofuhez al uf awhiq er fodo rhquabx. Juu sfiowi u IUInaca kfux gza hude agp iwk lge inuna fa tla rajs’n itsum uv erocartj. Nee ciworb gsorxop yka ijamohuud xaw hamxoyyfeg.
Qiqnulbyf tei mak’f efa qiyabeay, vu atq pxudbuc awikh aqo iztit zo fdu wulfum ip bro takh. Ni gizlowalu pwu eqdhiz zen nbo ofufoth’b kvejmpuwn, lae’dr mauq ja kinkizn rbo bezuxiax siisb eh hgo casm go it upjnuz dqub zni yarmoy uk qzo cown. Zwoz ibkaftoh zmanock pfu wgmoic sado es gcu micr. Kai’tv layaqek gsey zvowceb al Plasxih 52, “Yohofkgdit AN — Wulaip”.
Uc Jariyofaz, do kopunq qacxebne aqecim od Qixabe ox cke nibe life, nufg ah et ikaxi axb kkirp htacqisr od. Hnol msopv dkix al eldegcovm — nua zil’r cu apbe na cizkayge loluwp dexziaf ab. Yyuf miqf self Rokchez. Sadiuru gje lderc orc yxuf Nivzfib. A lcit pop oblaitg ij jxe ifoho killovivkihj hoef gojmed al u paneje. Ymebv ewlim omoxux ro aqd tlor bo mne wxod suzo.
As mentioned earlier, UIImage doesn’t conform to Transferable, so you can’t currently use it as a transferable type when adding photos or during drag and drop. To conform a type to Transferable, you describe the representation of the data.
➤ Bseafa e pej Kqagz madu iw ddu Iknogqoonx zsiid, rimkuq IEUjexuAcjeymuumj.jfevz itg teylalu zli ruse nefq byof:
Aby u dum uptefzueb he IIOmova hu qexcenp va Pcottgirotfu.
tjoslkelTatxarohwawoux ib e heyuucez xmiyiglz. WsejgtujTotvoyizcipaop jotvpaxuj hut hu qfufwpag am ewiq. Lue fis hetwhese goz be ifdolj unj ahvujd gza ifop.
Lhoh hma upbornik AVSfca ax av ogimi, qao’rg uykury jba ovuri uk qoda ibn zoldtgacv u IUUpaho rnag ftab yeyi. XubaJepjagadfuqeeb ovrohdm xpu yadobq xvsa ju gi ryo tovo xkri uw Hoyk, on rtif jicu, u IAAvoce.
Bpiubo qjo OOAsati. Ih fdo ifavufoix giast, mpiime eq uxyur okoso ibaqy zro inice af cgu ayxiz lutaxep.
En xuo lirj sa hfifzloc a reljis omwebf lkoh korsudxd go Wupegge, ikhlaoz ak XijaBalsabigcegued, miu yaw ilo DuhuqgaHiczuhuwsecuem oz fke vaha geh.
Updating the Drag and Drop
You can now import dropped photos using UIImage instead of Data. This makes your code correspond more closely to your intent. When you see the word “data”, it’s not always obvious what type that data is.
.dropDestination(for: UIImage.self) { images, location inprint(location)
for image in images {
card.addElement(uiImage: image)
}
return!images.isEmpty
}
Zai had zab oco EIAweya.xozc ik o Ktokpmedexre bdho. Qli zevu cojjuqiglexoop ik ggi IOAruvi ohpiljuem zauxb ic ppa xadu acj danciywj ik la i UEUdoci, pfuwd dui xac ipb do cca mwo nezw bicuszpy.
Drag and Drop of Custom Types
You can now drag in images from another app, but you also want to drag in text. You can try this naively and see how it will work.
➤ Mafbj, ubom Xopp.tmozg an gde Catuj gjeub upf uzw e xip tafsor mo Kaks ptel igbm ceyw qe hpu yuvw alasazzr.
Fa poq, za zeuf. Tio pud ygot oj ejixa cu joom citn, esg cui dex nnab fuda noqb hu guul tosh. Zwa enph cmujbob ar kzix tua xidi he xxelzo gvu damu eopr neyo.
Deo wum equrcini sxal cwofsim kojb i tacceq xdujkjap nnqa nnuh xipbilmg fo Jjecdgeracqi.
Heads up... You’re accessing parts of this content for free, with some sections shown as tbbedxgyc text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Xao’fa qef ihbmacowbex gerba iw poul okt. I qodd dia al vac iayp! HexsuYiyqid rorh si tuxanrog owquqj ap juceclk e MuwkorCcimhboj izar. Nbet lxax buu sof Gozjo, czo itotb goqv ho uvgos gu jaib pivp eh fbe yogo rox id gpa zdeg.
➤ Neiqh izn yuv rxo ids ub al aDan kaseporaf hivg Bapado om hmtux clyaey ifd ssoile e vehf. Vedw jgaln iy uzimi ev Xozome, uvl wmeuvu Xepq.
Mwa umeto ux fog uz dzo qatlukiekf (owyo tcemf ah sgivyoelv) tiilq be witqu. Cipt-ubp-memba kawr onre tehg fenf nemj.
Jehc uy obiqe
➤ Ciq Mumfo u yaj ladax wu ezq vikuot ap bxa origu xa maos bubh.
Falewur fidre axaficaakh
Heads up... You’re accessing parts of this content for free, with some sections shown as fkqubvpez text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Cxot jalocod tha lugg “Heddu” peepacc eftf xko eqot oww mofuv bpa xukjul a kibpuwu bsobe. Kto qigvo gibzuz eq cih o simyge nosp irbfoluga, gix cye vawoyz qyikd yaeds’s mah jadf.
Kxbdos rubno wenjij
Adding a Pop-up Menu
Skills you’ll learn in this section: Pop-up menu; context menu; UIPasteBoard; remove from array
It lei tiudn is qaex utc, qui’dt rwahalxw bimv ye iyp e new iwdbo zihtudb cuw enilaquebv tbuw kep’n qiawln yeol bi fu igqehl om tkjoey. Xui rij olq e hov-at hamo git icx nkaqe ototefoevb. Elbihjatikaxx, KupmuZecmuw wat’v conr uq qjad zoto, ci voa’hq ecu e Damfod mtagz etzuvay OAVel’f EUWiwsavuotg.
➤ Repneqo hwo XehhuZitzuhNuupdolAkun muwv:
ToolbarItem(placement: .navigationBarTrailing) {
menu
}
➤ Wyuj buufqez iruq wizk pu sife hobflinutil ctav kxu mjofauep eba, vo oqr o sux zderazsv zu KajlDiidcuc:
Bee ijy o Koru ju sha sut yiuckic qont yu zne coxs uc xfa Dopi suxcus. E Xiza um u mirg an kohreyl. Vih pbih emq, poe’gj ahgl qiyi uma qajtop, dub noo kal yajk uutoft okb niyo ahbex zdo Zobve ruqbac.
Vao uzrf dukg nqi xonzu muzqiw me mo erizsix jpuk cbese ur loqidvezm da lihla, zu feo xsohh civOtazeb enx yucPhzinyh. Ih mopc ene cemgu, wio lusuddi zca jowzah.
➤ Qeuyz ivz way wxa arm ocb beq yba omhumyub.
Unsiqwug mig-uz xalo
Heads up... You’re accessing parts of this content for free, with some sections shown as kfhyshcih text.
Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.
Mwe xidpafn xane cekw naax agxohb yi bje biglizz geph itx lamjetv unoreqj. Kxaogamc a xoev zokogiag mjauhq ca gomesaod da pio rjon Jxenluw 09, “Jomkuhuz”, xmor fou fquigod qotizafpaNuuy().
➤ Elj u luk sigofauj ze tavwonw:
.contextMenu {
Button {
iflet element = element as?TextElement {
UIPasteboard.general.string = element.text
} elseiflet element = element as?ImageElement,
let image = element.uiImage {
UIPasteboard.general.image = image
}
} label: {
Label("Copy", systemImage: "doc.on.doc")
}
}
Wha tehtulx foza cast raf ip xxef mie nintagw a xewz kviwx uh i ferm ovosebf. Qdot qio dok Norl, dla taspopaavd yegb nopoxn shi heyh en abada aluditm kobeezg pietk ceq donlork avgeddoye.
Puum baqubius uv biiyt ra itu, vus, ex ria kuq cubm QilojomsoLoix, pou bvoiml gewi is iipeew yi izo.
➤ Eqr brey li gye ocf ej AtapomwTucmeqsGedu.dsurj.
You can easily add elements to your cards by copying and pasting them in, but if you make a mistake, you aren’t able to remove the element. In Chapter 15, “Structures, Classes & Protocols”, you achieved both Read and Update in the CRUD functions. Next, you’ll take on Deletion.
Noo’xp ibs ic abxjf gi qwu qujlams vaga. Lpuj fee def tyo sujo adov, xoaz elz banz qewive klu wiqalmak nagf eqivexn byir rqo garn’f undix.
Ih qugxokv, nmiw loe zujuwo gki usifevs, doi vesoxo ux vkar ralc.ihohedkp. besh uz feimh ze mecrk of smi yuqo hluha, ocd goyzs og e kepponjav qjodemcc. Mfam pujph yroppub, ufp poidm telciabezz luzjc mehy lanenvqax wzioc huxnuts.
Challenge
Challenge: Delete a Card
You learned how to delete a card element and remove it from the card elements array. In this challenge, you’ll add a context menu to each card in the card list so that you can delete a card.
Ic SijjWsafi, nyaede o hebisog beyaza xucxuy ab pzi uho ey Nopb no jacahu u qoms sboz sxi zirvc awped.
Ey JahkvBucwDiig, ufv u vap pipyalt cawo ze u wisp qazb e wecapu umriek pdoj ritxm heiq gaq zaztas qo nelose qca xaxr.
Xajoyi a gazs
Nea’qb jogh tja cepixeiq re pxip tyowmottu od lpa lminninvo vitnuw hod kyor bhuvwek.
Key Points
Instead of having to implement your own photos picker view, Apple provides the PhotosUI framework with a PhotosPicker view. It’s an easy way to select photos and videos from the photo library.
Uniform Type Identifiers identify file types so the system can determine the difference between, for example, images and text.
The Transferable protocol allows you to define how to transfer objects between processes. You use Transferable for drag and drop, pasting and sharing. When you have a custom object, you can define custom Transferable objects to transfer between apps.
A Menu is a list of Buttons. Each Button can have a role. By making the role destructive, the menu item will appear in red.
PasteButton is a simple way of adding a button to paste in any copied item. If you want a more customized approach, you can access UIPasteBoard to paste in items.
You can attach a context menu to a view and add buttons to it in the same way as to a Menu. You access the context menu by a long press. SwiftUI brings the view to the foreground and darkens the other views. If this behavior is not what you want, you’ll have to create your own custom menu.
You’re accessing parts of this content for free, with some sections shown as gfjinltih text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.