SwiftUI Tutorial: Build an iBeacon detector with object binding and custom modifiers

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] this is another tutorial for Swift UI again building a complete that from scratch in about 20 minutes so you can see exactly how it works this time we're going to build an app that scans from nearby ibeacons and on the way you'll get more experience with bindable objects using pass through subject from combine and also see how it can build custom view modifiers to save as repeating code anyway we've got lots to do let's go straight to Xcode in Xcode go ahead and choose create new Xcode project choose iOS then single view app press next call this thing beacon detector and make sure the use swift UI box is checked otherwise the rest of this tutorial will be very confusing indeed and press next and create on your desktop so it's not basic Swift UI project our press resumed so it starts building this default code which the text had a world like usual you okay there's not a fault lay out saying hello world in this program we're going to show one of four pieces of text why they want to say a beacon is right next to us right here it's near to us it's far from us or it's unknown so there's one of four cases to work with for now we'll just show the text unknown in this text view here now we don't want this sort of small black text here we want a much bigger thing feeling much more space so below this text I'm going to say I want the font using font dot system this style choose size 72 and design dot rounded that's a new SF rounded font like that I won't do this thing that nice background color so I'll say it's got a dot background of color gray we don't know where it is want this thing to fill all available space so I think at the whole screen I'll say dot frame and say there's a min width of zero a max width of dot infinity a min height of zero and a max height of dot infinity which a quest takes up all level space basically now you can see that a slight issue here in terms of my friend background color so what's happening is I've said background first and then change the frame here let's change frame here and that is different from setting the frame and then giving a background color the order really really matters inside Swift UI so I'm going to copy this frame line here by pasteboard and put it before the background and with that change boom you can see it now cue PI's the full space of my screen - the safe area where the sensor housing is the knotch of course we really want the thing take up all the space so I'll say after that background dot edges ignoring safe area AB say dot or fill up all available space including that top safe area so this let's actually want to return when we are unknown gray text nice and big ignoring a safe area that's what want to do but we also want to show it was mere or it's far or it's right here using very similar styling welcome back to that soon enough first though let's look at how we detect beacons so we'll make a new class outside our content view called a beacon detector and yes it does have to be a class is going to be a bindable object and the delegate for a CL location manager is a colocation thing so our class B detector here will inherit from nsobject again that is a requirement if you want to work with delegates on iOS and UI kaitland so this thing is going to monitor beacons for us and notify our content view when something changed to do that we've got to add two new imports first I'm going to import the combined Framework little say it'll allow us to say sorry when our data has changed using a pass through subject I'll also import core location which letter the tech beacons and do other things too so we've got combined and have got score location and if those two in place I can say actually that our beginners Hector is a bindable object that conforms to CL location manager delegate now a bindable object is very similar to state in swift UI except it's designed for external stuff reference types like our beating detector here are best done i supply enable objects so we've got our new class here in harris minute object will be a bindable object and we'll get feedback from core location when something interesting happens to conform the bundle object we only have to have one property inside our class which is some sort of did change publisher I'm gonna use a pass through subject which comes from combine sending nothing and we'll never error like that we were supposed track to other properties one's going to be our location manager when I create this thing when I think is made in the first place and keep it alive for the entirety of our app so I'll say var location manager is an optional CL location manager you things going to be the last distance we had tracked was it nearby was unknown was it far who knows so we'll save our last distance equals CL proximity dot unknown if I just go to Seattle for eternity and press dot you'll see the other options far immediate mere and unknown so I'll do unknown to self with okay when this thing is made overriding it when it's made we want to immediately call super dine it which is the NS object initializer will then create an instance of our location manager location manager equals a new CL location manager will assign ourselves to be its delegate so we're told but something happens and will immediately say location manager question mark dot request when in use authorization you want to ask the user when the app is being run please allow us to use your location of course that's required in order to get beacon detecting working next up we're going to say when we have some sort of authorizations that has changed for core location do something because we're gonna ask the user here in line 23 please allow us to use location and when to make a choice on that you know allow or disallow a new method will be called in our delegate which is us called did change authorization and it's down to us decide if that's good enough we can say if the new status is equal to dot authorized when in use with what we asked for then awesome but first does our stair location manager support monitoring for CL beacon region dot self that is can this thing actually scan for beacons or not and if so does our CL location manager support ranging of beacons as it else tell how far away a beacon actually is and if so then here we are good to go so what that means we've been authorized user location monitoring available through our device and rain use available for our device so we are good to start looking for a particular beacon when that's happened we'll call a new method called start scanning which to configure a beacon to look for and start looking for it and start arranging for it as well we'll say func start scanning and here's the tricky part we have to enter a precise beacon identify as a UUID these are long numbers and there has to be exactly right otherwise your code simply won't work you'll have no detecting whatsoever so I'm gonna say let u u ID equals UUID with UUID string again it's a precise number it's like this exactly I'm using is one of Apple's test numbers we want to say 5a for bc f c/e - 174 e - for BAC - a 8 1 4 - 0 9 - e 77 f6 b7 e5 I'm going to actually force and wrap that so I know it's safe I've hand typed that UUID it exactly right next we'll wrap that inside a CL beacon identity constraint which sir new type introduced in iOS 13 to handle detecting beacons I'll say let constraint equals CL beacon identity constraint passing in the UUID major and minor values the your ideal beads the you idea is made the major number is some sort of identifying number for this beacon so you your ideal say all stores of my awesome shoe store that's your UID the major number might be different kinds of store here's the London store here's the Edinburgh store here's the Cardiff store and so forth so I'll say majors 1 2 3 and minor subdivides the major value this might be floor numbers inside a store so 1 2 3 might be a London store minor 4 5 6 might be eight or the shoe department or who knows what so I'll say minor four five six this major minor and UUID must match in whatever app or device you're using to transmit beacons with anyway that's our constraint I'll then wrap that in a beacon region by doing let beacon region equals a CL beacon region with the beacon identity constraint our constraint identify string my beacon this is just as friendly reference for you so that defines our beacon now the important part will say location manager question mark dot start monitoring for that beacon region and location manager question mark dot start ranging beacons satisfying that constraint so start looking for the beacon at all and start telling us how far away it is so that will handle beating scanning the next step is to decide what happens when we find a beacon when our case we'll make a method called update that takes some sort of distance which says CL proximity how far away the beacon was and all we're going to do is store that in our last distance property by doing last distance equals distance and immediately call our did change publisher that tell any of you observing us that we have a new value and it should have X itself so this did change let's send open open closed closed parens so tell the views we've changed so that's what we want to do when the beacons been ranged willing we know when the beacons been ranged because we get a special callback did range of beacons satisfying beacon constraint and all we're going to do here is pull out the first beacon that was matched because potentially there are many beatings of them got matched nearby so I'll say if let beacon Egan equals beacons dot first then we'll call our update method with the distance of that beacon its proximity value otherwise I'll use update with a distance of dot unknown we couldn't read any beacons nearby and that finishes our beacon scanning code so again we have permission here give me pleasure to scan for beacons please if that worked and we can monitor and we can range we're good to go we can just call start scanning here the start scanning tells the beacon to look for 5a for BC FCE glitter they're there with major one two three minor four five six then says start monitoring for that and start ranging it start telling me how far away I am from it eventually we'll get a call back saying yet we've ranged a beacon here's how far away it is so we try and read the first beacon pass that on to our update method which it's proximity and that will then store that new value in its property and update the calling view if that fails will the update of unknown so what happen is did change dot send will tell any observing views it's time to reload their body so we can then inside the view the body said okay what is the last distance property of the ranging class was it near far unknown or something else so let's write that now in our content view I'll make an object binding for our detector which is a type of power beacon detector like that so start watching this class for changes and now inside the body here we want to add different kinds of Tech one for right here or near one for far ones unknown but there's gonna mean lots of copying and pasting of code look at this a frame line here or this font line here that's not changing the background color fine that is changing and sadly this has to remain where it is for swifty wise reasons but these other two here this can go away we want to put those into a reusable modifier we can use anywhere else so I'm going to take out the whole dot font and dot frame think and go outside our content view and say there is a new struct called big text which is a view modifier a custom view modifier this has one thing I've got to do which is a method called body would accept some sort of content and returns a view that's been modified and will say this thing take its content with a lowercase C and applies those two modifies to it modify the font and modify the frame as a result down here in our body for our content view we can now say text unknown dot modifier big text apply that shared styling to that text field so I'm going to copy and paste that starting again again again we define it once and reuse it many times and now for the interesting part inside the view we want to read the last distance of our detector return one of the correct text fields so I'll say if detector dot last distance equals dot immediate then and I'll copy and paste this text area here else if detector dot last distance is equal to dot near else--if opening brace else if protector dot last distance is equal to dot far and for everything else ie unknown that goes in I used in text but I put the same thing into the other cases there there and there I can now write different text and format them slightly differently so we have text unknown I'll do text right here and then background color I'll do red Fournier I'll say it's near and we're going to use orange for far I'll say it's far and use the color blue let's see if that all compiles almost you can see it's a little bit unhappy with our calls down here with the EDS ignoring safe area but that's not really the problem the problem is that we have logic inside our compute property and when you start having complex properties like this you could no longer just use text you've got to actually specify return before these things make it really clear that's what you mean I'll paste it in here and here and here so we really do mean return those texts from each thing let's build again I hope this whole thing should work okay so I'm gonna give it a try it won't quite work but you'll see why very quickly and helpfully um it'll tell us exactly what went wrong so I'm gonna change to my simulator using iPhone 10s Mac's then press command R to build and run my code in the simulator and hopefully boom there we go so you can see unknown text appearing quite nicely but down here you'll see an important warning this app has tried to read privacy sensitive data without a usage description we have to add this key here NS location when in use usage description to our P list so I'm gonna copy this whole key to my pasteboard go to my info plist file I'll make some space and then right-click in this gap here and choose add row then paste in that exact key and give the value we want to scan beacon like that and now iOS knows how to prompt users for permission to scan beacons but again I press command ah now appears correctly do you want to grab mission I say yes allow while using the app so now it's working correctly it's still showing unknown but if the simulator we can't actually scan for beacons we've got to use of real iOS device for that now currently screen recording from iOS 13 later does not work terribly well so how to record a little movie on my phone and then splice it in later on why don't look at what's happening so here I'm in the app as you can see it's a gray screen saying unknown on my iPad to have nearby I've installed a beacon transmitting app that will transmit that Apple beacon pre-configure with major and my number one two three four five six so records advertised now on my iPad it'll transit the beacon and boom right away you can see it saying right here on my phone it's found the beacon successfully if I hide my iPad I put it way under my desk for example while holding my phone up it'll weaken the strength of the beacon and out says it's just near now keep in mind that I begin to have a fairly weak signal doesn't take much to get between a reader and a transmitter this is why I often see my beacons on the ceilings in rooms they can transmit from there without sort of being hit by human bodies and in the way anyway as you can see it's my name i beeping quite nicely expect them right here again if I had really really long arms you'd see sort of far and when I finally press stop appetizing on my iPad it'll go back to being unknown on my phone that's another swift you program built again only about 90 lines of code it's remarkable how small these programs can be anyway if you enjoyed this video please press the like button tell your friends and don't forget to subscribe to my channel I make lots more videos like this one to help you improve your skills as a swift developer you
Info
Channel: Paul Hudson
Views: 18,910
Rating: undefined out of 5
Keywords: xcode, ios, swift, swiftui, swift ui, uikit, programming, tutorial, example, code, project, coding, program, list, table view, state, objectbinding, bindableobject, ibeacon, combine
Id: lCNpEaZiKqU
Channel Id: undefined
Length: 21min 18sec (1278 seconds)
Published: Thu Jun 13 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.