Today we add the primary user interface, and add the CoreML model we created yesterday into the project. As we have learned in past projects with SwiftUI, there needs to be some @State
properties added to store the corresponding controls’ information. We are adding three out of the six needed, one for the date: the amount of sleep the user wants to get and the amount of coffee they had that day.
For my selfish benefit, I defaulted the values to my average for the day.
Then we add in the date picker and the two-steppers while using the %g
string specifier that no matter what the provided value, it will remove all nonessential zeros. We also added to the NavigationView
the app title and a button to calculate the result with the Machine learning model and display the product with an activity alert.
After adding the .mlmodel
file to the project we set up it with our project, first by letting SwfitUI know we have used a CoreML model by:
After that we would then pass the date components into the model to get the output result. this is done in a do, catch block:
This code also enables us to change the alertTitle, alertMessage, and showing alert properties that are yet to be defined. Let us work on that now, adding these to just below the first three:
Today is the wrap-up for project 4, and It has been fun to get my feet wet with CoreML and using some new interface items. The focus of today’s tasks is to clean up the interface on BetterSleep, and do the end-of-project Quiz. Currently, the layout is, as Paul put it, “Substandard.” So to resolve this, we are going to embed the current layout in a Form
and change the current Text
items to be Section
header text. After completing this part of the exercise, Xcode has decided that I no longer need to be working on this project as it has now made my project not open with the current version of Xcode. Unfortunately, that does mean that I cannot complete the other two challenges without repeating all of the work from the past two days. With the sadness of a corrupted project, I took the end-of-project assessment and got an 81% on the test. I look forward to the start of the next project.
Paul shares that this will be the final “easy” project of the course, I look forward to the challenge. Today we are working on learning how these three items work: List
, Bundle
, and UITextChecker
.
Starting off with List
, a list’s UIKit equivalent would be UITableView
. It is incredibly simple to create a list with SwiftUI you could add dynamic data and static data all in the same list block, just like this:
This can power some incredibly complex and creative uses. The next thing in the lesson for today is loading resources from your app bundle. It sounds complex, but it is not. Loading files from the bundle using URLs. Using this code:
Keep in mind that this does not apply to any file type that Xcode and swift will manage for you (Like images)… Now, what if, for some reason, the app can’t find the file in question? Or the app can’t read the file?
This code checks the bundle for the file in question, and if it can’t find it sets a basic root word and give the fatal error listed. As Paul shared, it could be the best experience for the end-user to have the app crash, then function poorly with missing functionality.
Today we will implement some important features within the app, such as adding the supplied project file and checking the user’s word. Additionally, we go over how to use UITextChecker
.
UITextChecker
lives under UIKit, and is Objective-C based. So there is a little more leg work to get it working in SwiftUI. First, we create an instance of UITextChecker
, that is responsible for parsing the user’s word. Then we need to create an NSRange
, to read the entire length of the string. so the code will look a little something like this:
We also add some error checking if a word already exists in the list and a valid word in the English dictionary.
Here is the final day of the project! I took the post-project wrap up quiz and scored a respectable 83%. This work makes sense to me, and there were some important topics touched on in this project, like fatalError
. Listed are the Challenges for taking the learning further:
isReal()
that returns false if the word length is under three letters. For the second part, compare the start word against their input word and return false if they are the same.startGame()
, so users can restart with a new word whenever they want to.Embarking on the first challenge, Paul recommends adding a check into the isReal()
function. This can be accomplished by using this code:
The second challenge is to add a bar button that calls the startGame()
function. This is a rudimentary task that can be accomplished by adding this right after the .navigationBarTitle
:
The final challenge is to add score under the list
and update every time a user successfully adds a word to the list. This can be done multiple ways. You can add a @State
object and then use Text
to display the score. Additionally, to manage the score you can add to the startGame()
code to reset the counter back to zero, then in the isReal()
write logic to increase the counter by one.
We have come so far in the past three weeks; time flies when you are having fun! I have developed a good routine as I try and get at least an hour of coding and writing in each morning before work. Then on my lunch, I will try and eat as fast as I can to then self-edit my writing from the morning or work out the challenges at the end of the project. I also try and get at least one Apple Fitness+ class in. By the end of my day, I am exhausted, but I’m doing meaningful work to help me become a better developer and feel better.