As a fan of “Back to the Future”, I really appreciate the dramatic storyline setup for this course. It takes a while to get to the first “Great Scott!”, but they get there eventually.
As for the first lesson on the UserDefaults.standard singleton goes, I have no complaints other than the usual about how the video is using an old version of Swift and the text updates under the video give away everything about how to do the exercise, rather than just say “change all NSUserDefaults.standardUserDefaults to UserDefaults.standard”, etc.
Wow, that took quite a while. To be fair, I was away on vacation for two weeks, but it has been a whole month since my last post and I only just now finished the “On the Map” app.
I cannot yet say whether having access to the complete documentation for the project would have made a big difference in how long I spent on the app. I suspect not. There were a great many unexpected twists and turns, and I did opt to implement the Facebook login as well. The Facebook Swift API is not exactly something you can just drop into, get what you need, and get out quickly.
On to “iOS Persistence and Core Data”!
After a little further exploration, I discovered that the requirements for the “On the Map” app are indeed public (but not publicized). You can read them here. Be certain to follow the link to the rubric if you plan on pursuing the Nanodegree. Those documents do not include the API for Udacity user authentication, but a little poking around in GitHub will probably reward you with the information you seek by way of the repositories of prior students’ projects.
Apparently, the “On the Map” app is a Nanodegree-only exercise. That is very disappointing, as I would like to accomplish as much as possible of the Nanodegree prior to signing up for the Nanodegree program (because you are charged monthly for the Nanodegree program until the work is completed). This is a blatant money-grab by Udacity. There is no reason the “On the Map” resources and requirements could not be made available publicly.
Perhaps the Udacity API is not public, but then why expose it to the Nanodegree participants?
At first it appears that the authentication flow has been significantly changed away from the flow presented in Lesson 5: Authentication Requests, because basically it has. Instead of entering in your TMDb credentials (username and password) into the app (where presumably the app could surreptitiously co-opt them), TMDb wants app developers to let TMDb authenticate users directly through their (TMDb’s) website. You can do this using a segue to an authentication view controller with a web view and a web view delegate, but that is not as spiffy as handling login in your own login view.
But while implementing this new flow, I stumbled across the following URL request:
It is listed as strongly discouraged, but by golly that is the request that this course is looking to use in the loginWithToken() method, and it still works! I might go back and finish the new authentication flow, since I actually have it fully implemented, but for now I’m sticking with old school. If you want to go old school too, here is the link to the appropriate documentation: https://developers.themoviedb.org/3/authentication/validate-request-token
Also, the instructor’s notes in step 18 of Lesson 5 include example code on how to use validate-request-token.
If you are attempting the quiz “Which Methods to Use?” in “Lesson 5: Authenticating Requests” (aka “Lesson 3”), don’t bother. The API has changed since the quiz was written and finding the old API is darn near impossible. I eventually had to get on “The Movie Database Support” website (after a long, round-about search of the internet) and find a support request that just happened to mention the genres method. For completists, here are the methods old and new:
Old (Quiz Answers)
New (For Actual Use)
In “Lesson 4: Chaining Asynchronous Requests” (or “Lesson 2” in the video; now our count is off by two!), there is a ridiculous claim that you cannot retrieve any photos beyond 4000 (or possibly less). That is pure nonsense!
Here is what the Flickr API is trying to tell you. Flickr is only going to return one page of results. If you do not ask for a particular page, you are going to get the default page (which is Page 1).
That page is going to have between zero and (the current maximum of) 500 results. (See `per_page` in the Flickr API documentation.) I believe at one time you could request up to 4000 results per page (hence the warning “Please note that Flickr will return at most the first 4,000 results for any given search query”), but that has since been reduced to 500. This does not limit you to only the first 500 (or even 4000) results though!
You can certainly request page 41 and receive valid results that are beyond the first 40 pages of 100 results each. I know this to be true, because my FlickrFinder app can and has done just that.
Is this because asking for a specific page is “a more specific query”? Yes, it is.
Maybe Flickr’s API was broken when the video for this lesson was made, but now it isn’t, so all of the discussion about 4000 and the limitations of retrieving photos is now obsolete. This line of code:
let pageLimit = min(totalPages, 40)
is completely unnecessary. Just use totalPages as the pageLimit.
These are good exercises, worth doing, with the following caveats.
For the Animals Exercise, I found it completely unnecessary to write any code. I just looked at the raw JSON file and answered the questions using that. Thankfully, the next exercise data set was both large enough and complicated enough that writing code appears to be the quicker solution.
For the Hearthstone Exercise, I could not successfully get the hearthstone.playground (or the hearthstone-solution.playground for that matter) to execute more than once. Any changes to the code would send Xcode off into NeverNeverLand until I completely quit Xcode and restarted the playground. (This is Xcode version 8.3.2, by the way.)
My solution to the problem was two-fold, but perhaps only one of these is necessary:
- Set the playground to “Manually Run”. By default, the playground will automatically run. To change it to only run when you want it to run, long-click the square (if the playground is currently running) or the right-facing “play” triangle (if the playground is paused or “Ready”) at the bottom-left of the Editor area and select “Manually Run”. Now, when you want the playground to run, click the right-facing “play” triangle.
- Rebuild the playground from scratch. In particular, I removed all forced unwrapping (‘!’) and references to
NSDictionary. Furthermore, there is no need to pass the
parsedHearthstoneJSON variable into the
parseJSONAsDictionary() function. (You will note that the argument
dictionary is never referenced anywhere inside the function.) Although putting the parsing into a function is a good idea for app code, it is unnecessary here in this playground.
First off, I wouldn’t mind the course designer getting cute and starting with Lesson 0 instead of Lesson 1 if the Udacity system supported it. Unfortunately, Udacity does not. Therefore, Lesson 0 is listed as “Lesson 1” in the Udacity menu system, and each Lesson n is listed as Lesson n+1. Although not very confusing, it is still pointlessly confusing.
Secondly, unlike the previous course, the menu system only lists one lesson at a time. This would not be quite so annoying if I had not already experienced the benefits of being able to look back and look ahead without jumping all the way back to the course roadmap.
I like the presenters and, for the most part, the way the material is presented. In Lesson 1: Using Web Services and APIs (I am using their lesson numbers, not Udacity’s), there is still way too much of “Here, look at this code, copy it into your project, and then run it.”
Lesson 0: Making a Network Request was entertaining and informative enough. As it has been some time since I viewed the lesson and there was not much new to me within it, that analysis will have to suffice. On to Lesson 1.
I both like and dislike the use of Flikr for this app. I like that we are using a real, honest-to-goodness commercial API that we might want to actually use for some future app. I dislike the confusion of “photo-this” and “photo-that” though, and the presenter even acknowledges the problem. They chose fairly well however because that API, and particularly the JSON data it returns, show considerable depth and expose a variety of JSON object types.
Please note that even the new code in this lesson is slightly out-of-date. Nothing too difficult to handle though. Xcode’s auto-fix will generally guide you in the right direction.
This post probably concludes my look at the UIKit Fundamentals course. I am still finishing up MemeMe 2.0, but I doubt I will have anything to add after completing it. There were two additional bits and pieces I wanted to address though.
The first is a line of code that you may or may not encounter in step6.1-bondVillains-noTabs. In that code is a left-over call (from an Xcode 6 template, I believe) to registerClass(_, forCellWithReuseIdentifier:). If you fail to delete that line of code, any attempt at creating a cell in the storyboard will be for naught. The line has been deleted from subsequent iterations of the Bond Villains app (steps 6.2 through 6.4), so it will only cause you grief if you try to add a cell in the storyboard in step 6.1 (as I did).
The second issue is the complete lack of a textual rubric or outline or list of requirements or checklist for the MemeMe 2.0 project near the end of this lesson. There were checklists for other, less challenging apps in this course; why not for the biggest, most complex app? Instead, I have to go back through the videos and try and find every last little requirement and make my own checklist. That may be an important skill to have, but I know this omission was not an intentional teaching device. I just can’t understand this oversight.