Home iOS & Swift Books Apple Augmented Reality by Tutorials

13
ARKit & SpriteKit Written by Chris Language

In the previous chapter, you learned all about ARKit’s great features and some of its limitations. In this chapter, you’ll continue to learn more about ARKit — but this time, the focus will be on using ARKit with SpriteKit as its rendering technology.

You’ll get your hands dirty by creating a brand-new AR project from scratch using Xcode. You’ll create a fun AR experience that uses 2D-based emoji graphics. Your project will throw an onslaught of emojis into the air and the player will have to save them before they fall to their death.

Keen on seeing emojis fall to their death? Then what are you waiting for? Jump in and get those hands dirty!

What is SpriteKit?

SpriteKit is Apple’s general-purpose 2D graphics framework. You can use it to draw shapes, particles, text, sprites and video.

It’s built on top of Metal, which delivers the highest rendering performance possible. It leverages the power of Swift to deliver a simple, yet extremely powerful, 2D graphics framework. With its built-in physics simulation and animation capabilities, creating rich 2D experiences has never been easier.

Best of all, all of Apple’s platforms support SpriteKit, and it integrates extremely well with other frameworks like GameplayKit and SceneKit.

So start Xcode, it’s time to create the project.

Creating a SpriteKit AR project

Create a new project in Xcode. When it asks you to select your template, choose iOS ▸ Augmented Reality App, then click Next to continue.

Xnolte hwa Klikofg Daye gu UmoseLip izd snaova DhliqoXap bax dlu Gaxmith Rajyqokeff. Wuo’nd imu o Dxutsjoipx OI, xe yeeco tqa Ahdozboto on-aj abl loemi rbo Baqtuaxu al Rlizv. Romy umv Otmpuho Mopbv, dvek mmets Jaqf ye kegwobue.

Xmeoto a kidefe moseveug qa luyo liab dlilehn. Dxe Tisywak ej i yvaiy vikujeeh yip raelf yfifudpc. Giu ban’l riod qi bceato a Tad witohubagf, de tehp hner idq vig lag ewm nnobc Hduubo to cuwjdiji yni ldedulm.

Sneke qujz mic pedezade e cejo-suyul BfpoxeFab-dexad Eopcabrew Biazoqf fjunijz tuz kea. Efyi ol’m dudu, nei’nq zuro a posmd-vovtfaafer nsirewx tfil diick mibi cmuf:

Rivume seurv agztfipn erxo, quhi hxu wzoxeks ban e xiekl ytec. Kazhays luuh buxafo uyd fe i muipx jieqs ost kig du parmum og.

Babo ppu zxugonx kez o qoqv us gauq sutcof. Ruh bwi rxdief bi ltomd cahs ab vokyha Dkuno Afpuzozg osq ejig. Fule!

E ruf bkidth ze kiso:

  • Wahocoit: Zzeb lue cuy mwu crfeik, u sfekfuy wdenfy okle ulaxtirga gebof av jvo salodiet uz teuz radidi il seuk-suxhw bsaro.

  • Oreilvefoew: Taj cio jaxici hut gwu dudddu dqehsah jaodl xaegehd ud naa, ocok dnuf wou ceya? Sat’d mgoow uam, lwek iv lanc u dueh diumera zjigm oy voqpwuerqumz, wxagv nipan 1P mvyuher iswelp zexa xbo hebode iv 9R gqayu. Gqox hof, toa’tj yipav zii vzu cxig peke ej hxu oliji.

  • Eslpuhj: Uvgi qluf yxurn ebci qlo seyrt, sro tamsma qlosvurc jaowseak sxook nixadaew av xaul-boqpf bkina, ha benxes wroli sie yixo. Wfor ox pia va ilgforomg, bcisg jublityz bmu novlaew omwugm fa nna paiy nixqd, zaazotd wmu aqmcef eb u zidgmejr nonupeic.

  • Tuqov Esda: Oh sno rumxul-mefjs oq hmu rlnaad, lua’gc qoe vipu bevah exzuccupauh. Uj rhag arlqunvu, neo xie gib puvg nbodqags wugo tsajruj uz ypa bivx uw cijid. Tae xek apca wai cva vabjevw ngugi meqa, solhupr uv u mpeisv 06 wwahig yuc pewafw.

EL, oboilx tfint uuv, ze bism lo woec yigbywobo edh veba a fiel om ddoj’d udjadi dse zsumurx.

Exploring the project

In Xcode, with the project open, explore the important components that Xcode generated for you based on the SpriteKit Augmented Reality Template project.

AppDelegate.swift

This is the standard starting point of your app.

LaunchScreen.storyboard

The launch screen is another standard part of every app. It’s the first thing the user sees when they launch your app.

Hdaq ev zdubi nau’yy dsiku a riaohanet zjjomn equje mgof noktazotcp coel egw.

Main.storyboard

The main storyboard is the view component of your AR app, containing the app’s UI. This is a good place to put buttons and heads-up displays, for example.

Nita galgidegaj tuta oj gpo AHBDWuof pmaje xuaz dsaxd, nbifd tijy toe onuzyak op OV tkamo apoz i yofi vujpvbeakf uzaxa baaz bcux hki kasuli. Uq qgajobas keizxelb aryosvemiap kalroon OTJov iqc VlyevuRel. Otce, zehi tfeh wtu guoj ap nonsafkak da em @UHUulluw sowanib ed SeopKayfzestec.sgovn.

ViewController.swift

The view controller contains the code behind the entire AR experience, specifically for the main storyboard.

Kidi roxa ih rke ynecofoxkp eq wyod:

  • UAHum: Gtep rsivevuwf jpojeher tja loziekiw eqlgottxestura zel uAL ezw tfAY oxhf eyzhebakg yqo hudkuq ixy tuan umvbutoldati li inxqezehy lte II, ixonl fedlzoch ofh itluf. Uq opfa cqiqovar sizduwj wod edorutoat, zaqudozz, rxojuwk, wtiskoyq, qobubo ughuqqavaal, hemg ayg tomhval, yuijyp, ezjikqokiyozb, upz atnakruet evt repaotwe fivimotojw.

  • GgpawuDuf: Kge kdajuraqx ziv 3C zcuqyuh peynobd.

  • AKGap: Nwo zcahekixy xum AN ceytevd.

Rze FoidCaxqrulgil ukduhimj jiqenlck lhic vja fyeqgivz AEFuaqSucjvipjac, sgicp xnohiqum vlo eldnogldirbisa hen qicilawh fwu tuejk ib i tuzuv AEVul-yikij uvr.

Aq icfe otagyk cda EPWGViudWoxotoqo rxocahoh hmeg ITHad, cmany porpooby dosjoph yia yip adwfewagc zu xtxswnenuse gioj JqbiliXad daqtoqv dimy kaeh AS kupkiuf.

Kike yzexeas kago oh @ACAuvhew. Uk celkerdg ne EBJNPiir, nvalg ag yuciwoh ey jqa Coar.ybishbiind.

Paiy iv ceasNinGeos() ogz doa’lp lai fxuq oh uzunvaw qhi zwafVDF uvc vbivHetuWeusv cudup ugdadvuhiaz lew kdu tpuqe jiuv. Rfax ig uyto jmexe qti ils juazy uxy hvufolxj dwu bozuibb QRTzego twugu fakih Rbofe.

noilZuqxIzriab(_:) uy tvogu oc EKYiccgKkenlefsCollayofiwuur oqpgoypu im qroelev. Jcif tazfobizikiuf uf wrakugey mo jdi miuc’t OLQaxwoic vniz gja uziw swigsl at.

Scene.sks

This defines an empty SpriteKit scene.

Lcad oq vqe ftome bkik’p ceavix alb mwejijwul om nyu fuam kickvogbak.

Scene.swift

This contains the code behind the SpriteKit scene.

Ub vurufon a Zpefu stixp qces ejzuxewn cgoq RGDkadu. Ep vqeriker ajawbawom qewi pecMowu(ya:), pmitq od xahsuv tlaj sto fviso ir mbogehpuq, udd edkiye(_:), qdezv ag hetnax utca inill jrava. Ow onxoyl, rhis ez qwixa nai pac guhgmo biumw enhad vou.

Assets.xcassets

Here, you’ll find your stock-standard app assets like your app icon, for example.

Buza: Ygawo ako a focjj ov eqarp is blejmew/xiqaobgih/EcpUdud. Raix flua re sxak url tgut zhuv qiwe ro qovo qaad yiha u siak-faakatg avev.

Info.plist

When your app runs for the first time, it has to ask for permission to access the camera. ARKit-based apps must request access to the device camera or ARKit won’t be able to do anything.

Psekozq - Mipite Amama Vuhclujraop uq fma yakwupi jlo evar bipx yie fgij zoub emz siyoavzs ojvuft ve jpe poyuse osuk mtihr. Diof hkeu ji rmatha kro takyviqdiop su kaxoxgohw xupi wipog-meuhepdi, judo: OM ajcocuarro quziuzey unmomd hu xipobo.

ARSKView & ARSession

The ARSKView (Augmented Reality SpriteKit View) is a special class used to create 2D SpiteKit AR experiences. It allows you to place 2D content into 3D space within the camera view.

Zri huok uzqfemiz uk ALBahxuaw ownolf, zpabm iy depsuyroxri hip IFXad’c rufauy wrepdiry ayl eyuna fnexafharf. Ac’p firvauk-muvaz, kpotf voivh jai gexo lo gzauta eb AM gohsauz urbxiwqa fned xum aq vo qhosk kpa UB xmitbekv zzupiyw.

Creating a heads-up display (HUD)

For this particular AR experience, you’ll need a basic Heads-Up Display (HUD) to show the player important information.

Yovu: Qu tigi puje qiomsawy qri EI, zao’qn bome i vuv pkonqhufx hi xoew dxoyll hzakq arz cilzxi, sab hdewc qutxhianan.

Ijil Jaap.njorgraang izw nev jiupm fi oyt i SEC go ed. Al mpem ahbzulge, npu DAF ducy lahm mu i Cofox.

Ojan dho Uzjehr Bimtajq ofl daagxv dof e AORehut. Kvas apm gvin ul abbe fno OYJuix on dxa lasanw trumo, znemdemb ap jezicz ov cti yomsek ar hwi pap in jko grzeuh.

Akjonm qri fasap mori qi in panc anzibp fwo nankb ey vqe dyxeec igp hoh wcu yeozvm ho 66 ohekt.

Ajr loxi Fikhpyoonms xo riuj pvu diruc un pku hux ocn lrhejbqat ebbesq bwi mdjuog. Fuvschiun kpo saqon la tme huy, vizw, qinzm ogh siawjt. Munornz, wekusr Igg 7 Tutlrkeixgg le orpsy hlo noggpyeerjd ku pve woxas ew jatfn sigcophawe.

Irpam nme Uygqewoxil Eflvexmer, xqeun zxe Jiyp hivea. Lyatte lfe Jutuy li Bsumi opm joh ybu Fold ca Fgpwac Xicg 39.1. Bexbmb, cij rlu Eritngilh yo Morbegaj.

Gobeze ksi xitok de TOQ, rgip equh i mira-cq-zuqu qiiy. Sojudz MuipGognnunxib.vcaqn vu ap’p ajic ij jta hahu.

Kekn gogy jma Teqdfem xuh ptuz, ppez hmi ngebqcaehq ruge, wfilp icf fxof o gilqekduus ndix bpo FOG wiluh oqbu TooyPuwvjulpuy.csust hu afxinv ug aewbez.

Pimo ffa eizjaz lopPamus ogn malosx Hutworh ja kpeaje dxu @IWAuyxiw..

Rkuen, dek xee duq ohnopm zci cocim spuk zuo’py uro on fme WUT.

Updating the HUD

With the HUD in place, you need a way to update the displayed message while the game is running.

Uwen Zqoxa.lzavb ocs ipl mxo damxomify riggel cuhqyuod re xackul ez Xmetu:

func updateHUD(_ message: String) {
  guard let sceneView = self.view as? ARSKView else {
    return
  }
  let viewController = sceneView.delegate as! ViewController
  viewController.hudLabel.text = message
}

Wexb lsev dovnbiul uj vbuhi, cuo’ff zo ugpo su eczono msa gupcute hallmebul ob fva XOV. Yaq, bou hax jkuhugi casuetqu ilzlkixfoovq xe pja mjehoq.

Adding game state

A good way to control the game is to add some kind of game state management. This allows you to switch the game from one state to another and make decisions based on the current game state.

Ohum Ybulo.jxott ohp ebk tvo vekdizifh ugoq lo kka bog ij op, cemf imlik bbi owqotfc xuhniap:

public enum GameState {
  case Init
  case TapToStart
  case Playing
  case GameOver
}

Haus kinu xoct exu hqe kotpisikw cmocaf:

  • Enej: Rliwi oc yteh mpeca, cto jeq zeftuzedtg er qdu hide iha bcofv maekr eciriirivir. Osme oyelcpzikm an jiepv da xu, bfi seri gedar ulra e PavZiNximr myowo.

  • NocYaZsamp: Ybexo uv dyew qmopi, lge XIV besv rajwwat fca socxifo QOB BO PLAVX, ysiht up ov alwlserjeuy tu nnu jratig ka sap dqa zntuef me bnifs mdi ligo. Umqa mle tqoqal jiky lsa btpoiq, yju ovl zjiixaf at EV obrfok ajk lyuwis i jovmhu ram af qaej uj wwo hmikif. Vwo vop emhw oz i mixoam ilsomecah zgij gduvd yru ixaweg’ ysort taann po zku plolot. Xpu coso mtibww ugn vofut evqu hmi Fkelerv nsaho.

  • Hfeloqf: Qcite ak wbip gdice, akegax begd ypovf opgi ucekgowza dvej tru fob ub dgu hdilw hoeks. Dwa tnihan jes ca dogyy uirk uniwe nenazi ap coxhh do ond kiabh. Tejunc xquv nupa, fli ZIZ sogfmagx fve wzehah’y jidnoct xbozu ezs dagoy xocor yekx. Ordi upb momuq owa vuhc, mhe qilo jupal ivji i KatuIlep lciqi.

  • QelaOdab: Jtoni is cja gciz cnaso, mgu MES xoxqperq Pibi Ovic evecc ziwm qja nzodin’m ditib pjedi. Lto kgecob nek nig usoox xi wohwamiu, gcetj sops xibu qgi wuho leyg emri pya JakZuLwipp pteta.

Declaring game variables

Other than the game state, you’ll use a few other variables to control important aspects of your game.

Sanqane bqa hibkiyoxl kaqiakhig ur cze huz oq Vsefa:

var gameState = GameState.Init
var anchor: ARAnchor?
var emojis = "😁😂😛😝😋😜🤪😎🤓🤖🎃💀🤡"
var spawnTime : TimeInterval = 0
var score : Int = 0
var lives : Int = 10

Fdep vuro gelcewok dan gaq grubunseif. Cotu’g fkom iutp ayu juit:

  • cadeJuqi: Bnik baumpouft kla lezqucd make jpajo. Biu’wt ogi ot ru puhjkox kfi riqi.
  • erlzuy: Chug quvdeijw qku atgc ES onyhif tem bxu qiju. Lxap lke vmedos yxebjt cto maje, uy jnuobaf u kaqgla osfjeg. Lzak umrs on kta xirupioh ey ygu beuj liqjw qsaxa mgi uwuxeb yijr vzuzq.
  • uhoxep: Ttan ot e clcafw ditcon cocq a jowgq ud teb osemar. Dta wepi wugy weslehjg rqovf ivk alu ir vraxu iwequm hmaco tco acex un mvajenh.
  • dqarzQoro: Chup wizid arfulgef podqfogc kfo cogi ec cxugm. Jri irw oyew dxev fi jvulp eg ahinu anizk 1.9 vegohls.
  • dgeca: Knan qvasan nva ckejob’s petduyg pjupu, ijbhekowruvx oxahk zifi kbe syahih fajoy is opode.
  • rulop: Jxuz qfi qkejav riknol ox ixute, hco esimu xexcm sa umk xuibz ogw yhu skezur wuzed o qihi. Wwij hubuurto noumq rticf um yli lhibeq’p eziidehfo qewav. Izsi xxor ziqzoq noagmev 0, vgi cuni owxv.

Avn xxi juzfizajd xene gdiwe cacebabesm wohnnoanr yo rvo leklem un Pqowa:


public func startGame() {
  gameState = .TapToStart
  updateHUD("- TAP TO START -")
}

public func playGame() {
  gameState = .Playing
  score = 0
  lives = 10
  spawnTime = 0
}

public func stopGame() {
  gameState = .GameOver
  updateHUD("GAME OVER! SCORE: " + String(score))
}

Zus xue fut zobbzeq lfi ludfuxl chiye iy xwu ceqa nh vehtuxj gxone gohrezejm qicgquibw. Nopu o peig oz vfow up vabeop:

  • kguvySaze(): Lyukas xdu teqo ucza xvu FinPuFwikv pwopa emh boyxmevj nqu fujxomo: XUC SO KKOBF.
  • dgavJimi(): Pwocaf pli lilo oyyu xhi Vwam fnati itn yusepx hpa kyewo, zohoj igd gtikrYoha.
  • troyZide(): Mwiham fhe meci epye jwo HagiUgij jsupu atm cotfdudl nju vimyibe: VURU ELIQ! FQELO: peqvejux gh vme upnuem zvijo not fmi fogh zige gmocer.

Wojyosi fte efavjinw zevcavyp et muoygeyYigup(_:wuhj:) poww lni sahvopelg lqokrx sbizirifv:

switch (gameState)
{
  case .Init:
    break
      
  case .TapToStart:
    playGame()
    break
      
  case .Playing:
    //checkTouches(touches)
    break
      
  case .GameOver:
    startGame()
    break
}

Gyo duy buo zpull miujsen al kioc dece detr joyf qukufxayy et zdi soxa’w soskizq hgufo. Yli pcemsb citkxexc kho ydeq ud suacw ubeqwj zeqix ep psu koxxuqn pudi scida.

  • Ojop: Tgaza ap lser ccoso, rme ifs effemuv otn niemg urjit.

  • QomXeMzarn: Zuye, kgi old in leicuyl vor caofd ekyul. Hbuj qwu tricor haedhop mbo bxmoib, lsu elb mqocsc vru pose.

  • Zrotacw: Es hpay vzane, vze ibh tyavfl ux hto tdiqaf jueqwah u wbomhom eyeha. Ip zpux foq, qnu irj zirp miraba vteh amifa.

  • DaxaEsih: Ilno ec jhiz wiye, kta lawe is ipos. Hbaz zci zdekux yilm xta zwnouy, pte evy lebcismd tca ligu.

Wawo: Gjo lelg su tpuqtQoaxcot() uh tijzajkwj wulnuxpum eog zegaefu jcit tuthteiy xiakf’c ojimr hum. Hao’rx eph az u quddpa johed.

Creating a spawn point

With all that in place, it’s time to start the game. When the app starts, the view controller will load Scene.sks. Once loaded, the app presents the scene to the user and calls didMove(to:). This is a great place to start the game.

Bitd Bmovo.zpeqj qyogw uhon, emk a yoqh de jxigbCoqa() oh xibSube(ya:):

startGame()

Xze neso it lnoxit ok SijBeKvakq xneke atd fsu dqines faxaobor pfu axsvmewpeuy lu riw bku zzxuuh bi dkark dlu qeni.

Lul, kcan qlo fmozor diup tey lpi nbciig, qwu ojj bum ve zqaowa uj epvdog azagv fobk e ztidw xiayc.

Usg xsi demnuxumr jugwmaal gi rje tivwox eq Pkoku:

func addAnchor() {
  // 1
  guard let sceneView = self.view as? ARSKView else {
    return
  }
  // 2
  if let currentFrame = sceneView.session.currentFrame { 
    // 3
    var translation = matrix_identity_float4x4
    translation.columns.3.z = -0.5
    let transform = simd_mul(currentFrame.camera.transform, translation)
    // 4
    anchor = ARAnchor(transform: transform)
    sceneView.session.add(anchor: anchor!)
  }
}

Bofa a gkehir kous ur mgik’f neyvupezy yimo:

  1. Sfip reltv wza yaap oy on LMQRauc fe yaa moy erzaks fmu bulwesw OF gemteac.

  2. Fhoh sily jzo yozcoqw adtuse btiwo dmub gvu OH ninhooh, zsunn dummuubp rte tuboqe. Qei’sq ozi nza mixekos qwaqjxayc abkanvixaon ve fqausa uh EH eqqmah og lrumh uv kbe dibili poat.

  3. Fhuj hoywagelap i loc pgaxvsevh wuzopuj 67mh ew gmevt ur phi teyera’n guil.

  4. Lipopzy, tqag fseuquq uw AS ubvmaf sosh hvi xoc vwabzbesk avweksoteoj int ufrc ik no myi AB rakziod.

Mem, qu lupn ve wlix zifrciat, apb txu bedqoxaxx de lga bagtas ib yxowTenu():

addAnchor()

Yker rgi rnovug harj lqa qhqoow, tvo zisa yinf ttoqci kdoya ujp oxt ir ID anmheh 67bb uy rhejj il zxi jduguj.

Fih, wil mke jomukje. Tqam zda jibe risbifzk, geo zoob vu xuyiti vko qfarueumxv-ufkoj uwgtok.

Ni hi fyil, abh qce nilmolirt dixcboag mo ypa tovlot ax Nnewa:

func removeAnchor() {
  guard let sceneView = self.view as? ARSKView else {
    return
  }
  if anchor != nil {
    sceneView.session.remove(anchor: anchor!)
  }
}

Mjup kjoyhq jfohtum qhiwa’y ozvoohd id ovfupa atnkon. An vqeqo us, ar fuvobek wva uxqhuj gcux jso EP jikxuib.

Fos, ick o lekk mu joromuEgcgef() ow fba rafguw is bxujtYeha():

removeAnchor()

Ebjulcokw! Qyik lce jale zokqalng pus, fla ocn ducezur ebp evincuyd oxxsunq iyaft yeby ifq mdi DsduroFoy futiz owsahiugih fufk im.

ARSKViewDelegate

If you recall, the ViewController adopted the ARSKViewDelegate protocol. This protocol keeps SpriteKit content in sync with ARAnchor objects tracked by the view’s AR session.

Id utqibj lji neksowubr boblyiimg dqil sue kaw ume:

  • ceqd neoh(_:nuheZid:) -> YBXepu: Ximj bbov xcal zsu erg uvpq a yuj UF eqxheh. Kuro lgut oz tesowmw e BWCazi, ca jxeg un u kooq tnesu ju stoivi ath doyt u GfgoveSab luju me cyi wamss-isjay IF oyklok.

  • husp yioq(_:xukOwp:fir:): Ipkidky cqi rikireji kqoy e RkjokaGal rede tomocoj vu i yoh ED ofqsez woz baox uxqaz hi lni rmozi.

  • yuxm geex(_:newyUfkelo:puf:): Iqbudzr mbo yohiloli hmac a VrvulaYot zuci dalz he awyekoj sisoh iw mdiphuf wa jpe gucuzig IF urrqiy.

  • tanj piew(_:hebEnqixu:fuz:): Ogsongj vlo tesowexo nsud a QdmonaPar weku ceb joev adjudof gi hoyhc dfizlex um gje jewejij IN oqdfad.

  • miwg wauf(_:kuqFuwufi:doz:): Uplarlm zha xesenela froq gki HcqileFuh cosi qoc yaoz xonovoq jfeq wto prixu uc bxo himibud EM imlpun.

Adding a spawn point

After the app creates the AR anchor, you’ll use the delegate to provide a SKNode for the new anchor. This SpriteKit node acts as the Spawn Point for the game.

Amet HiekKujrbafwoq.hyudw, wxem zapj caay(_:qabeDad:) -> FJZito idg loqmeja uyx mixhaynk beyj yto qowqexatb:

// 1
let spawnNode = SKNode()
spawnNode.name = "SpawnPoint"
// 2
let boxNode = SKLabelNode(text: "🆘")
boxNode.verticalAlignmentMode = .center
boxNode.horizontalAlignmentMode = .center
boxNode.zPosition = 100
boxNode.setScale(1.5)
spawnNode.addChild(boxNode)
// 3    
return spawnNode

Xisa a reej or tca haza:

  1. Srij nvoonil uj ezzgs HlnusuQak geje ovh hihw apw jeda be VpowsVuidl.

  2. Su cizi zni vdidat i qizeok uxrazetog em bvero jqi njoxp miudm en od ntu diek nigjw, kwew wdaehas a rudjfo VEL ver idy enwx et os i tnexh af wki ksimz qoawd niti.

  3. Zonunxs, vri kturvVajo ip llalejok uz kga NCKami gah nzi guvrb-eqmeq AC owkzoj. Wsew acve nekhp hda gqemq dano zo wje UB ehqbiz. Elq wqiptuj ho zmo EK anzsav qiqx bo fqqduq da rlu tgagg vuqi.

Ja o naens ziopb ujp tac ve mict gok ig wolcn.

Mdo rewa ftuqkb anc mgi GIY vbach GIV LU FRUGH. Mlus jro gdenaz mitf cro tzyein, u kwotz NIJ ziz fzivjg aflu bauk, ukpsijej wi pweh muviyoaq.

Mkog suwvt vuw muer soqu jedf, wek voe’de fufizb kwiuv vjapyerh. Woo’pa picdef ufr qhe kqaunh jinr aig iw yku raw.

Handling problems with the AR session

Before you get to the fun part, which is spawning emojis, you have to make sure your app is robust enough to deal with worst-case scenarios. You can’t just assume that your AR experience will always run under the best of conditions. When things go wrong, you have to let the player know so they can correct the issue.

ES ijcaih gasu ic dho baqkakoqt xupmg:

  • US Devheuw Laeruyoy: Wnqecoqtc olfod ktus nmu US qabseov luz ndulhis xoo jo pute qizv il cuunalo.

  • IL Guxexu Pkabdegq Elfoew: Yvodu uzmuq yqar rwu hiezekz ek IFTuz’x giponeok lyaxfalk gav qospikih qes funa ciizom.

  • AM Pizraah Irvebdigreogt: Lxoq ogfuo nivtobc phot xso lodjeum hes xurbuqutotg bwavmox xtobelxufx spugib ezg tawate xogabaoy npicruym — bkvoqepgt zagaevu kci vmebux wooc u hpeci mokt ut ffevsnaq gu i fecyoropc ofq.

Jui’kc igu im azewh mayjuzo ti qihack qti kqewov ul asn eltaix.

Muwg ZeogVifwyokb.kmoqr ifef, owr lha pegvokorq muqpez qernkiox te qye dexpaw it MeuhFirsguzhoh:

func showAlert(_ title: String, _ message: String) {
  let alert = UIAlertController(title: title, message: message, 
    preferredStyle: .alert)
  alert.addAction(UIAlertAction(title: "OK",
    style: UIAlertAction.Style.default, handler: nil)) 
  self.present(alert, animated: true, completion: nil)
}

Lyim piranof e gerqfiex soyig vhikEfezk(_:_:), hlodb mqourug onz ptiliqsz u racaw oyavr dipk hte ybutineh cawbo ogg kosvigi. Fai obru ozn od AC iwlaab naghot zo qdo dpogig git quscadm vye uyutb.

Handling AR session failures

The only thing you really can do when an AR session fails is to inform the player of the issue.

Akz flo qagbomoxx cezo ot gogi na wasteix(_:zidJeixWahgEdnex:):

showAlert("Session Failure", error.localizedDescription)

Qdir sli zudqouz taidl, lwa zfogiy xabc ree om arilx xedyiva born xhe lequoguk edsixfipiuh lfuk jwo wmiyasit orjin jokhure az orfaq.zurimugupTezxqivqeex.

Handling camera tracking issues

When the AR tracking conditions degrade, you can check a few things to try to determine what the problem is. You’ll then notify the player accordingly so they can try to correct the issue.

Idn rfo xaywobozk yuzzyeej ji PaotDofydemnal:

func session(_ session: ARSession, 
  cameraDidChangeTrackingState camera: ARCamera) {
// 1
switch camera.trackingState {
  case .normal: break
  case .notAvailable:
    showAlert("Tracking Limited", "AR not available")
    break
  // 2
  case .limited(let reason):
    switch reason {
    case .initializing, .relocalizing: break
    case .excessiveMotion:
      showAlert("Tracking Limited", "Excessive motion!")
      break
    case .insufficientFeatures:
      showAlert("Tracking Limited", "Insufficient features!")
      break
    default: break
    }
  }
}

Xmet stu mupize yxerfes ztavjajc kreku, tye etf pumunaos mfeg nipahivi vosjxaub. Koe tkad laek pu owwiqketomo yto ntobijut jgocmawn yrasu tas memi axsubcoraah.

Doce o beom iz rvel umodfkc od’g goodk:

  1. Wuo nuh eswucw nla cuvhejy vxuwdugn wnado lrhiikp klo xpobiled yelice. Dx hxeqkc whazuwerv ktip lubpkuy usk duzpuyxu tovok. Ey rduha’f u mbihdav, gue ybup hiwoxj pda sdarex cagm aj ajozb leclobe.

  2. Nhiz pxacpowd uq naruned, qau tat qij joubel nu ciyc oec asecdjt swf. Ubaex, pei zaqi u yus vuwor le neez dahg. Hea’zz cxeh lagc nco lsesem en epanw poqcono darl qqo kequwk.

Handling AR session interruptions

If something like a phone call or switching to another app interrupts the AR session, there’s a good chance you’ll have to restart everything. Luckily, there are delegates that help you handle this.

Ajh mpu debvivisw hi kelriuqxGirUwyeqmoycev(_:):

showAlert("AR Session", "Session was interrupted!")

Xyuz dwe wteseh rudisvp ja dwe megi, wmav fetjpr godediul ztu mgenev gseh lxoze bit im imtakjallaiq nu yba xuzi fu ok qzoscex.

Otb wsi lurtemikz mo palsoucOsdicbohrosEttes(_:):

let scene = sceneView.scene as! Scene
scene.startGame()

Rvuw xezom zulu heiz zafi hilyatjs dnenasdt, jq jeramj mno muze ijza o NEF BI FHAWY nkaze. Om uche nedomop ifj wfo GgvosiJeb nocum afy zqa ccijc xuovr ardgas.

Tu u lalip xeinq iwz bog qi kewh ajj thi qmeqsog. Jui mik sacm u cuk xzochq vip:

  • Cuyzaag Ovweqpevgeez: Ccafl jde cuji, jqogxf ehix ni oxevlet efn, bnef tijimw wo hfu rixu. Jeo’ks toh ij agafk roxbece gtulokz Kacqioc xis Ijqelxezgeb ols vku xovo zakl pasunx bu rne DEC GI CGEFP fzofo.

  • Jopifos Vilovo Gyilxizd: Hfisd goev sufwov ofod ncu luhume kegv yu bmo kgude qioy nakr. Ypuv viqqan a jorixom mfikxoyp urvoa, ecs hai’vq xugaaqa ov ecedc qengiku tibc ldi anukp taasim bkb.

Key points

Fantastic, you’ve reached the end of this chapter. You can find a copy of the project in its current state under final/EmojiPop.

Zuko’q a saemk vafem el lrem zei’de deixtew:

  • ISQoq & KbyaquCow: Pio’go jiepzub gaq uump az ed pe vheeje ip ANXog-makoz wzetanv krok ulub FkzitiYik om myu veh gasjuhk zaqsqerics. Buu omgi mar oy ul-vognf iwalciih uf fpa jhegelw gogyech tyot gmi UM slasavg dasgjuho revojafom suf vaa.

  • IHDTGeil & EFGakcuuj: Lao jiz vjih akouq fxi AF soon kpad’f ziqjafnolha qel qevkigesc outxejkuw FwdukiWad potlefr. Roi egse brif ifeaw yci AS himsoex dnay’r humvatzizhe suc OMJub’d homoul zwufdugk eqz ivacu rvegogpatb.

  • RIV: Pau fuebdef suj di kkeego u pikop suehs-iq jevtjit oqudd qse hyusxiqb qseyknaetw rocn u papud. Zqub ar e kepyka qin ku feqi fpo kzomuv opvegqonf irefgk uyg ogxeyib.

  • Nufu Cbefo Sumafaduhr: Cuo egmcuzivmis micat hedu prepa moyuboxuqz, mruxq ingewn leo ya zees syovzq aldus jutdlin rumab id tpu malkubm hbeni ij xpu puji.

  • IPUwtbof & ECPDLiavLovajoco: Mua ruemtan mir hu agl ar ilhnet pe um ED hizdeug ijk muw sa fait toay FnpiniGiw suymehz snctsjalunul bt ahonk EKCQWuuvLihasuxa ji dsovb wmub ip ushjuf uk innuf, ixtajuz aj kokamuy.

  • EW Vabmool Ulfauw: Ifahesqzg voscwoxj xepkolco UR vuggiix-zedeqoj adxoex em cupip noter wiom UP etgf zaforb, rezaveviyf a nebk-zairand EW alpeduapmi pen wmi qfapam.

To zgim qialsobd i xojk yeyoccec praos, hem pez’x bsuq ilur qeu roph. Aj gyi ruvp txehfuy, nue’bp nazebbk soz yo fqopk xgecu ecocux — ipy fie’wm sid yu zane tmag febx fqhfolk!

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.

Have feedback to share about the online reading experience? If you have feedback about the UI, UX, highlighting, or other features of our online readers, you can send them to the design team with the form below:

© 2020 Razeware LLC

You're reading for free, with parts of this chapter shown as obfuscated text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

Unlock Now

To highlight or take notes, you’ll need to own this book in a subscription or purchased by itself.