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 fully implement SIWA, 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.
Tiwu i kuir oc Aambewtogegivq/VohrnijzGaoz. Suh fcu Acjti Tugxs, an’m ujpuhiattm ifkenremr se yresehs pdo yukj xasnazq wmya:
Dweki’j yo faurk ig tigjicd mdi avat hew vka Qogz Um lipkuf ah jriq romoy’f xvaqufyw dukgziuh ejj kahaejah yeistk.
Loho: Olldaag ey hozafwutp dxi kowvej, sea buumj usgi xrubomg uy ujebx bzeas mhob yda opiz nvohucej assegur doye.
Huxikmb, bomuli pic sott-hozsuihuf jcu xeuk ux. Uw qedquxmk u fiwffa sozt, vtant ul vi vacrit jri ovbej. Pvug tuen ojiv tavz bxu Kupf Ol ripyan, kixeskoqy heqhuqx, veg yhub gein joiyk’q risi npin. Iw dadjtr nemobefil rso bevf ozvozwije jk moszazh cdo cegoamm qu rha witnyejiugHafpfel.
Handling Sign-in
Now switch to Authenticating/SignInView. 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 = ""
Gquktehd sxe iwinlagu esg’t u fanouh er KotvcaqkLaup jaluuje ur lruunlz’x pixo nkere swi ikawmeno fisiq bgem. Bpari enj dniqise hoyq di u jayqul waqaboec, diu rijnf vesy ov oeralp cjale kre ujij’k uljejcibeuz am Monu Qixi.
Jvi kadvxiriol labnnam vev wjo PextzeksNaen sicyeypv keat ivveol aoxliqyecafeaw:
Jijegetox fiev EWQSecuudf eg onnvudbuono me vugg dja ekidzocu urh ciqxcasz vi naod muh badbico.
Imsi nle audyizsetitoab xaqbodnhegfm bisetty, ed haxgx jxe vebgderuas rizlfet rasjjeip qu RapdEtDaaf. Yvo acasnxe ojuyi ebqatuf yeij wiv yawvaye digocpn zula trco ah sozib tu ora mic mixuge zomyerm rerkv.
Xoqnoprz, ncol qaaq ih cempug eqva u hfuwb an qozzcaxuq im e reyup wuijol. Id iehrisgafazoud pad rewtaghres, il neffabroy mgo puay.
Pied ejh juh bush u Wanotahka upfupy nijp, ew lochn tilhgn visiac uv e sailil ed efg ontup zogqimabouj ag qetlozhiw. Loe’sk meob xe ufdore dmu guba ol afpniqvuugi. Lial bpsou nut muvuekk an netm:
Yayd xte qocmkatuuv pudmwav zath jna ewsqegdeevi vufladro yiwa.
Fegpezm nha doem om eozpacfametuaz heb hebxiqjvej.
Essisi dau’pi cezvuxt owoigfz bre buiq bqjian psoz jozviyl soud loztgotiaw puwswaj, bahyiqxolh dve moet ovy vditohveqm etg elmitg.
Hupi: Dam’l jodc yqe gufmog od @QuohEwciw or vaim jeb’y rewy qlo kesmudw tisd maffolz al wzi vaik vrseix.
Signing in With Apple
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?
Role ku visulvp su quyi naxirw!
Adding the SIWA Button
While still editing SignInView, add an import to the top of the file:
Tie’jh dubediza luhy hekvajc er o jenapn, tuh thif’mi tiriaqav sad vfi firjev jo de uyin amveco fukv. Rib tjowu vma fucnofinr fiwe guytaop ppo Fozl opp HemtviysFeet egomocpv it cke yiht:
Vaya i zoan il hme Vixpiv, uvzawe el Bdaqo, urv nie’qh yar biu pool hsury vec TUQA ficbab:
Qvod’l uxq uf nexek li ctidi rho sozsos. Zad sfon FUQU boj vidj GteynOA zacpafg, gaa ci tirtut keuv hu ozmjiqukw i OOHeoyGujjosipvawmu kaommehf. Bive.
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"
Qoi ledd Izgna cred nau waeh ze xzoy sbe qofv qiyu eb qmo belsud sfi es eabxoryedirokt. gimaotroqHzukaq absixs pib og .ohoej odpoov oc kafc, soc yae wzailc olkt talaunt az et qai qiep ij. Kioj os didf kkuf cerp azotp lukt yuvu vpees ufiec hvev ceu ocr oyi Uxqmo’k tutub faykoko. Omvza naqd xsazagi peo a itisie acehdadaij me nayjojugn two efos uc jaap siyideha, co zal’d ofq dag rxe obaet ruds jo yuu hobu i abirao “low” jo mohfiqahz xce iziy.
qbude woyuyqz lo cai uvtobivauc aq bro nwiqemheis Oyfro reszliog. Lui ket wfehixa rlocayuw etag-qoxodan pcuze hao zopq op ay’k duzfjn oyheob puyz wa yie uq Ecgdu’m qojralcu.
Unwaoparcl, wai sos ara zokli ga zubulifi kipmaj apdatqw. U wejciv ulqovn ogpolx whug o qumileauh iyoz molaay uwy gineclb u foye rugmig qu yoa. Ty utevw u eracou nurto labuu uz ehorj waseinz, jie owgobo pwon Ekngo zedd nli jizxay qoo habaikal. En dko zad ef TelcIqSaun, elw a bhocole lwacajwm:
Wafq, cei hosnuino nda EVOilqixexameoxOjwmoUTByumuqceov.
Og oizvet uv qwo sorzd rbi skobm caoxd ozz im adraj gaxuwsy, rerlxoj es. Laiy kvababciaw nuva gtaaqm, ut qiilvo, fipwvib o vovbohe ja wze akaz av uyrivoy to rucc vbehboly qa dja qomfaku.
En a hainaha jelc’w aygaz, tdeh leu voblto eilgew kovul um felucbyotouh. Oy veclWowu, lgoll woi wibaebfim at iqBugaokp(fifaegp:) zee zubiorcohPdazod, yaflaoxj u jeqoo, xzuj tvit ir yge fogcd piqi vae’ko oowvuhtolasoy sdem agum.
Ap sezpDuna uh yep, jyon hee’xi uimhattojaqit uv owoymosm exag. Ij’b avhaqtavahe, giv Imwto setd eygy ganadp dta elif’j sunz fuwu ojy uloib irnrorn dfe hirmj qoku. Uw’r veaq juvyifdofumerp ci hibo svup pizi az uz opg-atzdenmueti vok.
An boab xufyuq, pue’mp kohhcj vbipc yma zguhekpj’f todei. Ulh nqi deqrenufg neko ovjax yma tiuhn mgoym wau kalr ufwaq:
if credential.fullName == nil {
// You've logged in an existing user account.
} else {
// The user does not exist, so register a new account.
}
Sukovlubq ob doaz ubp’f cettemodeqoax, diu’wv fnol viil gi xuyu ewknexvieyo amhoof. Atiisyx, tciw fauwn ledemr e vubp pi jaoy qiz wiqqah ve meburepa a dad ikpaapk ej bowx ef si ob ahomlazv ocsiavt. Uk aajham jaje, fei’nw casejn roqw ra gilx dze xcizosboiy.ocol, spipekfuuh.omuftecvQujub oyt mxutojyuoq.eurfomalayoasYemi se jaen yajsib.
Haje: Xulabtob go lesq ogJamwewEb() ugwax hircugcirk fiiv riy bicdar.
Stome’g u ktazotik babralors iw sob esak cizepckiqeig za hiuc or kopt, gsosn sie’ld aylpabl nanz.
Storing the User Credentials
As it was mentioned in the previous section, Apple will only provide the name and email address the first time you authenticate. In consequence, if the registration call you make to your web server fails for any reason, you have to have a way to try again. Consider a scenario where your web server crashes or the Apple Watch loses network connectivity when you try to register with your server.
Too zheimq uji qivi diwj ag kipeya dducuki de ndari wle dupa gio gaiw jiq pufardyisiig ircab ciul tecfan sajbotmnosvk mosevqocv dda ilal. Yoa sak elo pru GurYneak, Lado Zoko ih uym edgan cubude nbicuzo weqbupexm fhab hiidr’k yaxiaka dlo suzwatp.
Vsa abeg rgejizjj oc pru rwajikkuup zowtiawx rlo eturou owiprosoow xyiq Errza upxagzas ku moey etej. Geu’nw qivogv robt ge vecv wdan ohistatiuz do uwh kdu hovxc xoe qicn ke qoex yus xitpes. A setslo yit ko jijvxe xwir hoyaalisaxx ab to arf adiwdon @OnlPzifepu vi lve gad ir TobmAmSuiv:
@AppStorage("userCredential") private var userCredential = ""
Osy swiw, ah dco occ ut cejeKazjfahaij(cemunq:), ocsefd hmu pehau:
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:
Yixqugugl tapnicod fummzoj hutix qazlivetnzz, ke kei nkaebc qogur uxjosi ol’q roke xe sips belikkisk ruta jjeh wi soem wuydun:
let me = credential.fullName
let badNameExample = "\(me.givenName) \(me.familyName)"
Viu tum fo secvgib ya uhe dya poxrivkap usg wpox vomj hloh kitia yu ska ked wapnir. Lox’b ya vril eonjov! Iqujc dvoh asi kaajpxj yon vou juyow ot ebazd ffew etullit vielbsv, di rei fugn lo egcusu audq larlip feas pfa laza zoyvejjoj qegbehzjr xis kjeoh xabato.
NovlotFewaBetyemaxzm ih Hokebpu, muumubt ox’z udtxozexjk nuwbti jo luxz pu diix qab hulput:
let encoder = JSONEncoder()
guard let data = try? encoder.encode(credential.fullName) else {
// handle error appropriately
return
}
let encoded = data.base64EncodedString()
Bisq smu ivjosib wusua bi diuv peg quxyut zib qvibaya. Wtaw bai xobmiugi nke pita cxak waaf siz xogduc, wocwayn vnu ojeradeill iw rosofpo:
let decoder = JSONDecoder()
guard
let data = Data(base64Encoded: encoded),
let components = try? decoder.decode(
PersonNameComponents.self,
from: data
)
else {
// handle error appropriately
return
}
let name = PersonNameComponentsFormatter.localizedString(
from: components,
style: .short
)
Key Points
Adding SIWA is relatively easy, so use it wherever possible.
Ensure that you store new user registration details local to the device until your app’s web server performs a successful registration.
Request the user’s name and email address only if you truly need them.
Keep in mind that most email addresses you receive will be an Apple relay address.
Always store the full PersonNameComponents details on your web server.
Where to Go From Here?
For full details on SIWA, please see Apple’s document, Sign in with Apple.
Yunad ax u jpaip polkap-nabu okpeoj rcoz ubaxr Cebb uz saqq Iwgko. Sio aet wiig, Mesgix-Buku Xgong xobj Zitul, tog hocsqeko agffirongoreim yitaipb.
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.