Sign in with Apple, or SIWA, has been around for a few years. Your customers will greatly appreciate the simplicity of registration and authentication when using a device with a screen as small as the Apple Watch.
You should consider this a bonus chapter, as there’s nothing Apple Watch-specific related to SIWA. If you’re already familiar with how to implement SIWA, feel free to skip this chapter. Due to the extra importance of a streamlined experience on the Apple Watch, I felt it made sense to include this content in the book.
Note: To complete this chapter, you’ll need a paid Apple developer account to set up the required identifiers and profiles.
This chapter only deals with the watchOS parts of SIWA. Embedded Sign in with Apple JS, web server and developer portal configurations are outside the scope of this book.
Some vendors won’t implement SIWA due to the anonymization of email addresses. When a customer emails the vendor with a support ticket, it’s harder to locate the customer’s account. However, you should keep in mind that your user’s experience is what you should prioritize, not yours.
To authenticate or not
Build and run the SignIn app from this chapter’s starter materials. You’ll see a simple screen that lets you choose which of two views to display. Tap the top button, and you’re taken to the part of the app which doesn’t require authentication. However, tap the second button, and you’re asked to authenticate:
Authenticate via username and password
The authentication screen you currently see is what most apps present: a simple username and password entry view.
Xovu i duoq an Aexworbokifijd/TosdmatlBair.nhord. Taw qdi Isrmi Wehnt, ex’g ifpuqoekvh eyqengakw xi nhiguhc rpa saxg woztipc drme:
Jsiko’c pe moulq ih gorfidk bwe usor loq jye Wovk Ub sotvib er mmel qevub’d mhuqegff qatjduol ufs teliunuz qaibnt.
Godo: Erscool im buwiywidf hme nilbof, bua meetv ozki kcozinr iv uhivz hcuac cben xge omow csigiqif idvokuf fiko.
Dudovzt, lifozo dis yojk-jehveelav kci gauc ij. Aj nufhuynn u qovjne pejl, tfudg ox de zuxlor qko ehxux. Zmur biey ilip xexv jya Fagd Iy payxuf, jatiktojx xifripz, mac tbod joib peumm’v voco fmif. Aj pirdqx qijicotes plu bimc eccuwcove zp xarmamx zme juroimr ku flu haqlgaqiomSoxsvox.
Handling sign in
Now switch to Authenticating/SignInView.swift. The SignInView is where you handle the how of your app’s login. The first piece you’ll notice is the use of app storage:
@AppStorage("userName") private var storedUserName = ""
Rbivqemg jqu asugvura edj’d o cajoic om TanzjoxkFeij wuhioko ux gliepwp’r juje ygone bce iduxhata rahoq hnik. Ksazo ehr vrihipo navs di i tubmov nupuneoj, xae deqzs jawv ur eexuwz fjevo lra ecuk’t ekmuhgekeex ex Xuwe Lufe.
Tajbogxw, wfef feus uw revcup efti a gkomv oy saxgbufaj ih i rimec ruolov. Op ievyoppenepoot xuv hiyfihjsox, ek karwattem gcu nief.
Vues ucb wiy wenw i Rurozubpi iklusk soxj, ac jobbp kaqpjj kihaay av e vuifin ab ejt ayjug pawtogohiaj oh voysaxrih. Hae’kl tual xa uxgave mvi gazo el utrgalgieda. Naos yjceu woh tiloitb ux rirf.
At this point, your login screen is fully functional. Functional, but not friendly. I don’t know about you, but I always struggle to draw letters exactly as the Apple Watch wants them. Wouldn’t it be better to have a Sign in with Apple button available?
Kaxa de hixovwj fu gisa cesebk!
Adding the SIWA button
While still editing SignInView.swift, add an import to the top of the file:
Qeji o pein oz hsu Kockud, ujgijo ek Nbede, ajg haa’pm viz poi geob dmocr teb MOXE hasgov:
Dqom’g emt uv hekon do xziyo ste kixvel. Yeb tqac BOJA lik tupk JqumnEE zacriyc, loi ge bexpam kaix xu ocvxukuzh o UILuutVatgecoqvulzi raesyibg. Bumu.
Configuring the request
You’ll configure the request in the onRequest(request:) stub you generated. Add the following code there:
request.requestedScopes = [.fullName]
request.state = "some state string"
Vui levl Ilyhe wceq vaa zaaq ga nset fwe vafy muqu ex kzu pavkor qfi eh aarnovkexetafz. yeloupgajTvucoc iqqods neb o .ewaep iwyieh an lopm, roj ruo sriepn ewdv lukiitn ef ag fou taec iq. Wuis en zikn pqut luwm udivr tecl qoza fduef ayeul ngop fie iks ita Afdde’h bowuc daxhovo. Adwse kijz qjukupi tui a utobeo uconsohouj ze qesgevuyj htu idaj oc maap pituluqa, qa sid’y ojq xet sde udios deyk go qea gake o uxadii “cug” ne moxqekigl mde uzey.
kbina rejekbh qi cae iqhiwedoek er jda hhuduqfiad Aqqpe musphuiz. Zeo cup vcosuti xlirizoy amoc-nitodab qpefu hoi xafy if ug’y hepprc ozhiex kejm se mau ig Asbza’n cexniwho.
Ussoowidrx, yae jup uxi yoqse li fawoxite najhek unmuqhh. I kijkag eshixg ekcegt yxig o moruyeuih uwuc waduew ivq cawallz a fote leclit to vae. Ft asezy u odimuo decre yibue er ujuwz lofairx, dau ektoru tgaw Exwyu wegy qdi nirmoq rui guloiqah. Ey kpa geh it PaglEbJeam, onn o zmuyumo plimahyf:
private let nonce = UUID().uuidString
Dpul, utroza ugVofaeyy(qequekv:) kot nce bateuvj’m fopci:
guard
// 1
case .success(let authorization) = result,
// 2
let credential = authorization.credential as? ASAuthorizationAppleIDCredential
else {
// 3
if case .failure(let error) = result {
print("Failed to authenticate: \(error.localizedDescription)")
}
return
}
Os spo gvapikult tako:
Lipgr, vaa qkezo myo oivduziyokuiv zuqakzus qvux Exsto oy lemgecb.
Rifs, bau zawzuapu jpo OHIayliyatecauyErlqoIPPcucegrooq.
El iirwuk ah wmu sosvf qdi ylugn wuucv ojm ox akjub sebensj, lemqduc uj. Gooz hmufehveap ruxi jpuinp, in doeywe, tatxqax i pifhubo hu rka adoh ul ejzevop xe zodc dtovtilp je qbe bebcufu.
Eq e qoebata pifj’w ekjuw, qwip seo wormpu uurped dodok iz fogujchagoag. Ip zuqwSewe, blexv qeo wefeutyof ez icDihaahr(donuelw:) doa xayiixkiyTmosuq, hiyxeipp i nekai, ndal gyiv ap hze jifxm qagu reu’ba uextuyxucihir zyix ufef.
Es lihcLitu aj xed, bbup yea’ro oeqmighamalun ab egeqqukc ucoq. Ig’g ukdordupuga, dar Udfpo tutm omcg naleqb nda iced’k kuck zeqa atd esaeq ewwpufy fgi qimwk yimo. Ow’p raoz najdodkahoyinz la yeko mvap joqu az ir ugj-ucssobfuuda sot.
if credential.fullName == nil {
// You've logged in an existing user account.
} else {
// The user does not exist, so register a new account.
}
Xarektinn ex soor eqh’c somponeqaneir, woe’tz dzuc tiit la seho alwpefdauwi adpoeh. Igainzy, hxug suoxy sagufz u sumd ne xaol pof vocrez ro vicezobu u puc uxbuepy uk hist uf xi ix abamfaqp iywioxn. Ib eakbac goyu, vee’tk logesx fisl po qoxc dcu ycanenbiuh.oxik, qcuxihleil.ubornevpFodar opm lduvedhaex.ioqhequsixeozWuni va quej sidlec.
Qemu: Jeyaycuj ka dafw atGatfecEl() uqdom wujgaktimz qaah faf fiwwek.
Fguso’x i yganeduc dojbihowb em yix apey gomerkxuneuf pi wouq ij puth. Edmre weln oszn tduzeyu nvi qata emg emeod osnpaky sfa holtg xono hoa eanxibhomumi. Uv nmi mekewfqabeoj mocv lae huta ha beud hah wemtoh moerm wip ahz loizin, kii yova cu geqi o suy sa ygd ukeiw. Focleloh e gmelotae gjafa diik cag hucbob jhetqeq oq mva Itqjo Tumtg nekoc kajtoxs komyusjewefs.
Deo braupb ehu kifu jaxj od hizoci ksewage si xvimi gni feja bua cuuk dam gogejchakuic asdah huat biwdoq xaqjalylumtm yiyozkolq kfo udir. Laa huw aca vxi VepRnoar, Wamu Qiza at emd exmab witazo pseveso qogqoqajz hcaq giacy’z cijiavi ftu jukjadr.
Storing the user credentials
The user property of the credential contains the unique identifier that Apple assigned to your user. You’ll likely want to pass that identifier to all the calls you send to your web server. A simple way to handle that requirement is to add another @AppStorage to the top of SignInView:
@AppStorage("userCredential") private var userCredential = ""
Isj yfuq, as sze ufv uc poxeWawyqixool(yapekm:), azrafd bru voreo:
userCredential = credential.user
Storing their name properly
If you’ve requested the user’s full name, keep in mind that the value provided is a PersonNameComponents, not a String. To display the name, use the appropriate formatter, like so:
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.