Locking our UI behind Face ID – Bucket List SwiftUI Tutorial 12/12

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] to finish off this project we're going to add one last feature we're going to require users to authenticate themselves using either face id or touch id now this makes sense because there's a lot of personal data in here places like to go and see it's important we be respectful of that but it also allows me to give you an opportunity to try an important new skill in a practical context first we need some new state inside our view model here to track whether the app is currently locked or unlocked and so we're saying here there's a new at publish property var is unlocked is false second if you missed the earlier video it's important you go ahead and find your target options for target and info and make sure you have the key in here already privacy face id usage description with some text in here if you don't have that just right click somewhere else and choose add row then add a particular key add some text behind it you do have to have that touch id is done with a string in the code face id is done as a configuration option right here so please do that before continuing third we have to in our view model add an import for local authentication that's apple's authentication framework that's all the easy stuff now for the hard part if you remember the code for biometric authentication i.e basically in touch id was a teensy bit unpleasant because it has objective c code behind it always roots and so it's always a good idea to get it as far away from soft ui as you can so we're going to make a special authenticate method in our view model that handles all the biometric work for us so i'm going to worry about it this means making an la context so we have something to check and perform biometric authentication against second it means asking if the current device supports it in the first place do you support biometrics or not third if it does go ahead and run the request providing closure run when it completes uh when that finishes when they've identified correctly with their face or their finger whenever check the result if that result was successful then we'll set us is unlocked to be true just like did in the previous video so we'll say down here funk authenticate make our context first a new la context make a little ns error optional where any arrows can go and now if context can evaluate the policy device owner authentication with biometrics with error ampersand error then our reason string is please authenticate yourself to unlock your places that's fine let's put that into the same uh thing for our target as well so it matches uh like uh this there we go and then we can go ahead and evaluate the policy we can say context evaluate policy device authentication with biometrics with the reason being our reason and the reply this is where we get back success but also any further errors it's also authentication error in if we are successful brilliant self. is unlocked is true else it didn't work do something else and if we're down here it means we have no biometrics sure alert show a passcode or it's down whatever where you want to it's down to you um so remember the string here is used for touch id the one of the project options is used for face id for apple reasons and now we're going to make a small adjustment that is fairly easy to do if you see the video like this uh in our content view we have this big old z-stack here it's basically all our ui all this stuff here and that should only be shown all this code here should only be shown if our viewmodel is unlocked view model is unlocked like that else don't else show a button here to unlock uh so i've got this massive massive if block all the previous code is only shown if we have unlocked otherwise we don't like that and now we can go ahead and put a button in here we can fill the same with a button saying something like unlock oops unlock places calling model authenticate that's our review model predicate like that give it some styling like a little bit of padding a little bit of background dot blue foreground of white for example and clip shape of capsule so it's nice and clear then press command up give your code a try run it back now that's the first time you've used face id on your device you're going to need to go to the features menu and choose face id and then make sure enrolled is checked otherwise it will do nothing there's no error handling in our code right now make sure you enroll your device in that and when you're ready press unlock places it'll say you're quite sure yep sounds good to me and this is the the face id prompt appears here and i've got features face id and then matching face simulate success and we should see it worked so our ui is now unlocking however you might look carefully on my screen spot a small problem yes the ui works in simulator i can see fort william central london whenever it's all there fine but you'll see a little message here in xcode debug console which is a swifty y alert to us and also in xcode this little purple diagnostic thing appears here and that purple triangle is a runtime issue which is xcode's way of flagging up code that happens at runtime when our code's actually running it does something it really ought not to in this instance our error is here unlock equals true it's saying publishing changes from background threads is not allowed which if we run it through a swift translator it means you're trying to change the ui because toggling unlocked to be true means show the zed stack of the map and so forth you change the ui but you're not doing it from the main actor and that's going to cause problems now this might be quite confusing because we literally added that main actor attribute up here saying i want all the code from the class to run in the main actor and therefore be safe for ui updates that's what main actor does however i added an important proviso if you want to watch the video previously unless we specifically say otherwise so all runs in the main actor unless we specifically say otherwise and in this instance we did say otherwise or that might not be obvious down here we're telling face id or touch id to evaluate the user scan their face read their thumbprint whatever that's done by apple it's done by ios by system outside of our program with a fancy sort of animation thing happening it's not us doing the actual face check it's apple and when that whole process completes apple will call our completion closure this thing here and it'll do that saying hey it worked or it failed whatever but that won't be called on the main actor despite our at main actor attribute that'll be called however apple feels like it usually on a background task and so this bit is actually a background task a background thread it's saying not the main actor and so we're causing problems for ourselves the solution here is to make sure we change is unlocked on the main actor not on this background task that can be done by starting a new task then calling await mainactive.run and then passing in that same code so we'll say if we're successful great give us a task with a weight main actor dot run and put that code in there like that that effectively means start a new background task then immediately use that background task to jump across the main actor to cue up some work to make is unlocked true that's what it's doing and that works that curb will have no more runtime issues but we can do better because we can tell swift that this task actually should already run on the main actor the the closure this bit here we can say that needs to have the at main actor attribute run the whole task on the main actor so rather than saying give me a background task which then goes back to the main actor who sent us unlock true hey logo obviously like actors or doggos sorry both here rylan doing that whole background main actor bounce thing skip that entirely come on skip it entirely and instead run the whole task's body on the main actor so we can do this task at main actor in and then is unlocked equals true like that so we're saying this whole closure or passing to the task that thing should run in the main actor that's what's happening here and with that code it's exactly the same thing our error will now go away come on then it'll now go away because we aren't changing the ui on a background task anymore it'll always be on the main actor so i'll press unlock places here there's our little uh ui i'll press matching face it unlocks no more error no more purple rectangle that's this whole code done and that's another app complete good job you
Info
Channel: Paul Hudson
Views: 259
Rating: undefined out of 5
Keywords: xcode, swift, swiftui, ui, ios, programming, tutorial, example, project, code, uikit
Id: 2bGlnNy5q_g
Channel Id: undefined
Length: 10min 54sec (654 seconds)
Published: Fri Dec 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.