Reflections on Day 82
Thanks to another member of the 100 Days community I was able to dive a bit more into this last Sundays’ streaming project on ARKit and on why it was not working. In the end we didn’t find the reason but somehow, in my project, the nodes don’t get created, while in Paul project, downloaded from GitHub, they are. I asked Paul and he said he has no idea why I see only the flag and not the text when all the code is exactly the same. This will probably stay a mystery until I am adult enough to dig deeper into the thing.
But today is challenge day and even if I came back completely demolished (morally and physically) from yesterday’s Taiji Quan lesson I hope I will keep up with my resolve.
Hacking with Swift – Review for Project 22
Once more we are given a hint on all the possibilities we have with the techniques we have learnt (?), that it took only 30 minutes to create that app… Sure, all this is very nice, and I am sure Paul has to say that for marketing reasons, after all no one wants to do more than moving a inch more than absolutely necessary so a XXI century teacher needs to constantly cheat and tell people how easy everything is.
As a teacher myself I cannot count myself into that set of teachers. I always tell people how hard a thing is and that they should work really hard to achieve that, that there is no learning without struggle, that said activity will take that amount of time to master and so on…
I just gave a look at the challenges and yes, it seems we know how to do them but they are once more so much longer than an hour to complete. I will let you know at the end of this article how much time it took for me to complete.
I have begun learning Swift much before the beginning of this initiative but it has never been serious nor constant, so I guess it still qualifies me as a beginner, maximum an advanced beginner, no more. So, knowing how much I took to complete this will give you a rough idea of how much a real person should work on these challenges before hitting the mark, and it will certainly not be one hour!
So here is what we learned in this project:
- The user can change their location permission preference at any point. This option is available inside Settings for each app that has requested location tracking.
- We must ask permission to read the user’s location. Location data is highly sensitive, so ask for it only if you need it.
- If we request Always location permission iOS will still offer users the chance to choose When In Use. This is one of the many security precautions Apple enforces on behalf of users.
- iBeacon detection is powered by the
Core Locationcan also tell us the user’s precise location and more.
@unknown defaultcases let us catch values that were created after we wrote our code. This helps our code behave sensibly even if iOS changes after we ship an app.
- iOS devices are capable of acting as iBeacons. Using an iOS app is an easy way to test detection and ranging.
CLLocationManageris responsible for telling us when beacons are detected. We need to assign an object as its delegate, then wait for callbacks when something happens.
- “plist” is short for “property list”. Property lists can contain strings, integers, Booleans, dates, Data instances, plus arrays and dictionaries of each of those.
- The signal of iBeacons is relatively weak, and can be interrupted even by turning your back away from the beacon. As a result of this they are usually best placed on ceilings so they don’t get blocked by people.
- iBeacons have major and minor numbers that help us differentiate one beacon from another. These are used to subdivide your beacon’s UUID.
- All modern iPhones and iPads support iBeacons. iBeacons were first introduced way back with the iPhone 4S.
- iBeacons operate over Bluetooth. Bluetooth is the low-power networking protocol that lets iBeacons work for years on a tiny battery.
That’s it, let’s move on to the challenges.
Hacking with Swift — Challenge 22
Challenge 1: write code that shows a
UIAlertController when your beacon is first detected. Make sure you set a Boolean to say the alert has been shown, so it doesn’t keep appearing.
The first thing I did was to set some comments above the various methods so that we know at a glance what our code does. This is something Paul doesn’t need of course because he is so advanced, but for us mere mortals it is a game changer.
didChangeAuthorization method was labeled with “Ask for the user’s permission to track her location”, the
startScanning one with “Look for beacons”, the
update one with “update the view depending on the distance from the beacon” and the
didRangeBeacons with “do something if a beacon is found”.
This immediately tells me that this last method is the one we need to edit to complete this challenge.
I created a global Boolean property called
isAlertShown and set it to false.
Then, inside the
didRangeBeacons method, inside the
if let beacon = beacons.first statement, I added an extra control flow statement so that if
isAlertShown is false an alert controller with a title of “Beacon detected!” would be shown with an OK action (with no handler!).
After this and before presenting the alert I would toggle the value of the Boolean, so that, on the next launch it would not reappear again and again. Keep in mind that if the Boolean toggle would have been inserted in the alert action the console would have been plagued with messages saying that it was trying to show an alert controller that was already showing again and again! Something that the user would have never noticed but that was annoying enough!
Challenge 2: go through two or three other iBeacons in the Detect Beacon app and add their UUIDs to your app, then register all of them with iOS. Now add a second label to the app that shows new text depending on which beacon was located.
Fine, I did something, but it is not working as well as it should … I also tried other people’s solutions but they do not show any significant difference from my code.
I will not write here what I did because it is completely pointless, both for you reading and for me to write.
Frustration is once more ramping up to unbelievable levels and I really feel I do not deserve this. I do not deserve this! I am really doing my best, reading documentation, changing code, trying everything in my power and even outside of it … but still … I get the alert showing again and again even when the beacon is not being detected anymore …
Screw this challenge…!
The main questions are: how do I get the text to go back to “No beacon found”? How do I stop the alert from showing over and over again?
Challenge 3: add a circle to your view, then use animation to scale it up and down depending on the distance from the beacon — try 0.001 for unknown, 0.25 for far, 0.5 for near and 1.0 for immediate. You can make the circle by adding an image or by creating a view that’s 256 wide by 256 high then setting its
layer.cornerRadius to 128 so that it’s round.
I managed to do this but the result is between the ridiculous and the ugly … but I am really too demotivated now to try to do better. I did it like this:
- moved the text label to the top of the screen so that the circle would not cover it (I could have made it grow behind it but … ouff … I have only one life to waste).
- declared and instantiated an
viewDidLoadI set its
CGSize(width: 256, height: 256)(I know, I could have not hardcoded it …), set its
.layer.cornerRadius = 128, its
.backgroundColor = .darkGray, its center the the view’s center and, finally, added the subview to the view. I also changed the
view.backgroundColor = .lightGraynot to interfere with the circle’s one.
- at the bottom of the class I created an
animateCircle(scale:)method with a call to
UIView.animatecompletely similar to the one we used in Project 15 (after all… we have not been taught anything else, right?) and then, inside the first closure (the
animations:one), I set
self.circle.transform = CGAffineTransform(scaleX: scale, y: scale).
- finally, for each of the switch case in the
updatemethod, I called
self-animateCircle(scale:)method with a sensible value … well, no … with the values provided by Paul.
That’s it… nothing more… well, of course I could have done more but it is 9pm, I have coded almost 3 hours today for these f****** challenges… and I really feel I have learned absolutely nothing from them apart how to hate this thing… I really want to learn animations but I want a proper course, not some apéritif…
Anyway … if you are interested, the code is here.
I really feel that Paul left us a bit in the middle of the swamp with this project but, regardless, please don’t forget to drop a hello and a thanks to him for all his great work (you can find him on Twitter) and be sure to visit the 100 Days Of Swift initiative page. We are learning so much thanks to him and he deserves to know our gratitude.
He has about 20 great books on Swift, all of which you can check about here.
The 100 Days of Swift initiative is based on the Hacking with Swift book, which you should definitely check out.
If you like what I’m doing here please consider liking this article and sharing it with some of your peers. If you are feeling like being really awesome, please consider making a small donation to support my studies and my writing (please appreciate that I am not using advertisement on my articles).
If you are interested in my music engraving and my publications don’t forget visit my Facebook page and the pages where I publish my scores (Gumroad, SheetMusicPlus, ScoreExchange and on Apple Books).
You can also support me by buying Paul Hudson’s books from this Affiliate Link.
Anyways, thank you so much for reading!
Till the next one!