Sunday, November 19, 2017

Implement Navigation

Back | Forward



Chapter 7 of 10 at Apple Developer > Jump Right In is Implement Navigation.

Download the answer at the end of the chapter when you like.



One click for you, not two


Double-clicking the Navigation Item of the Meal Table View Controller never did work for me, despite all Apple says.

I had to click it once to select it in the Outline View, then visit the Attributes Inspector, then type out Your Meals as its Title.

<= Learning Objectives
<= Add a Segue to Navigate Forward
<= Configure the Navigation Bar for the Scenes



Far enough below, you must know


Apple says "below the else statement" to mean below the "else" and below the "return" and below the "}" that the guard-let-else statement ends with.

        guard let button = sender as? UIBarButtonItem, button === saveButton else {
            os_log("The save button was not pressed, cancelling", log: OSLog.default, type: .debug)
            return
        }

        // <= "BELOW THE ELSE" MEANS HERE


        let name = nameTextField.text ?? ""

<= Store New Meals in the Meal List
<= Create an Unwind Segue





Talk like a lawyer or not


Impress your friends! Learn to name a thing the "nil coalescing operator"!

Or spend your time more usefully.

Up to you. Apple is trying to talk about the idea of "or else a default value". If you've supplied a Nil value, then the ?? "" is a syntax meaning take an Empty String instead.

If you think you shouldn't have to learn the difference between Nil and an Empty String, you're right, but you won't get out of learning such a thing, not in our day and time. You will get out of remembering what a "nil coalescing operator" is, if you just try.

<= Create an Unwind Segue



Trust the FixIt when you should


Apple tells me their source should work, but it doesn't. I'd guess they made a copy-paste error of some kind.

So long as I understand enough of why the FixIt's inside Xcode make the decisions they make, then I can judge when to accept their changes or not, and then I end up with code that works, such as:

    @IBAction func unwindToMealList(sender: UIStoryboardSegue) {

        if let sourceViewController = sender.source as? MealViewController, let meal = sourceViewController.meal {

<= Create an Unwind Segue


Ouch so many buttons


Refusing to let Save button take the text until after you press Done? That makes no sense.

Insisting on text but not insisting on a rating or a photo? That makes little sense.

Happily, these illogical inconsistencies don't have to stop you from learning. You can just move on, or figure out how to fix them and tell us.

<= Disable Saving When the User Doesn't Enter an Item Name

<= Cancel a New Meal Addition



Some stars more equal than others


As I practice these exercises, I find I frequently did long ago forget to tell the Attributes Inspector of the Content View of the MealTableViewCell to turn off User Interaction Enabled.

If clicking on the stars changes the rating, that's why, and that's how to fix it.

<= Wrapping Up



Download and compare and commit


The download is 07_ImplementNavigation. Your Commit Message can be "Implement Navigation". 

<= Wrapping Up


Back | Forward | Source: Apple Developer > Implement Navigation


Create a Table View

Back | Forward



Chapter 6 of 10 at Apple Developer > Jump Right In is Create a Table View.

Download the answer at the end of the chapter when you like.

You know enough now that you might win through quickly without our advice, you can just try the chapter.



Squaring the star


The stars didn't come out square for me.

I like small phones, because small, so I target the iPhone 5s in simulation.

On such a small screen, to get the stars to come out with the same horizontal-vertical that I put in, I had calculate what Utilities > Size Inspector I wanted.

Working with 5 of the 44x44 buttons at a Spacing of 1 made for a Width of 224 == ((5 * 44) + (4 * 1)).

<= Learning Objectives
<= Create the Meal List
<= Design Custom Table Cells




Yea they left it nameless


Why do they name an "override func" with the noun "tableView" rather that a verb to say what it does?

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return meals.count


    }

I have no idea.

I imagine that decision won't make much sense until after you and I learn some more abou the Swift programming language, and even then we might find this to be sloppy work. Somehow it made sense to them to start out with the excessively abbreviated "override func tableView".

&lt;= Add Images to Your Project
<= Connect the Table Cell UI to Code
<= Load Initial Data
<= Display the Data



Download and compare and commit


The download is 06_CreateATableView. Your Commit Message can be "Create a Table View". 

<= Wrapping Up


Back | Forward | Source: Apple Developer > Create a Table View

Thursday, November 9, 2017

Define Your Data Model

Back | Forward



Chapter 5 of 10 at Apple Developer > Jump Right In is Define Your Data Model.

Download the answer at the end of this chapter whenever you like.



No you don't need to be them any time soon


Yea, they really do tell you to read and understand all of the voluminous "FoodTrackerTests.swift" file, even though they then tell you to delete most of what you just deciphered.

So you might rather delete what you're going to delete, then go back and understand just what remains.

<= Learning Objectives
<= 
Create a Data Model

<= Test Your Data


Always the pieces, sometimes the whole


Yea there's a glaring tupo of an entire example missing at <<< Your unit test class should look like this: >>>. In place of the example, they give you only its first line. Oh well. What they meant to say is, in order to demo your first test failure, your code should look like this:
import XCTest
@testable import FoodTracker

class FoodTrackerTests: XCTestCase {
    
    //MARK: Meal Class Tests
    
    func testMealInitializationSucceeds() {
        
        let zeroRatingMeal = Meal.init(name: "Zero", photo: nil, rating: 0)
        XCTAssertNotNil(zeroRatingMeal)
        
        let positiveRatingMeal = Meal.init(name: "Positive", photo: nil, rating: 5)
        XCTAssertNotNil(positiveRatingMeal)
    }
    
    func testMealInitializationFails() {
        
        let negativeRatingMeal = Meal.init(name: "Negative", photo: nil, rating: -1)
        XCTAssertNil(negativeRatingMeal)
        
        let largeRatingMeal = Meal.init(name: "Large", photo: nil, rating: 6)
        XCTAssertNil(largeRatingMeal)
        
        let emptyStringMeal = Meal.init(name: "", photo: nil, rating: 0)
        XCTAssertNil(emptyStringMeal)
    }
}
<= Test Your Data


Simulate an iPhone to fail your first test


Yes, testing your code as they suggest will trigger Xcode to open up a simulated iPhone, if you have quit Xcode and relaunched it since you last needed to run a simulated iPhone.


This launch will be as slow as it always is, first negotiating your admin privilege to do such a thing, and then taking time for the simulated iPhone to boot. But they will eventually get around to testing the code of your Data Model.


<= Test Your Data


Download and compare and commit


The download is 05_DefineYourDataModel. Your Commit Message can be "Define Your Data Model". 



<= Wrapping Up



Back | Forward | Source: Apple Developer > Define Your Data Model

Sunday, November 5, 2017

Implement a Custom Control

Back | Forward



Chapter 4 of 10 at Apple Developer > Jump Right In is Implement a Custom Control.


This is another chapter that never tells you, just expects, that you will start by jumping to the end of it and downloading a folder with an Images folder inside of it, so you can borrow those Png images when you need them.


The Fix-It buttons help


The newer versions of Xcode get more right by default. Don't expect Apple's guess of how much you need to fix to be correct. Just focus on taking the coding suggestions from Xcode.


<= Learning Objectives
<= Create a Custom View


Watch the Outline View closely


Apple means to ask you to land your Horizontal Stack View that becomes Rating Control at the bottom inside the UIStackView that vertically stacks your Meal Name Label, Name Text Field, and Photo Image View.

They never quite get around to asking for this out loud. Your results will match theirs much more closely if you pick up on this point. 

<= Display the Custom View


Match dimensions


Your Storyboard and App will look more like Apple's if you tell Utilities > Size Inspector to make your Horizontal Stack view have Width = 252 and Height = 44. That's because they're working with 5 of the 44x44 buttons at a Spacing of 8, and 252 == ((5 * 44) + (4 * 8)).

<= Add Buttons to the View


Help Interface Builder sketch your app


Do work thru adding support for Interface Builder, even though all that's wrong before you do is an inaccurate Storyboard, none of the errors and warnings that Apple explains used to haunt us.

<= Add Support for Interface Builder
<= Add Star Images to the Buttons


Keep the prints


You can keep the print statements, they trace what happens, they do no harm.

You'll have to keep the "@objc" fix-it for "func ratingButtonTapped", the code won't build otherwise.

The call to "updateButtonSelectionStates" from "setupButtons" isn't needed and does no harm.

<= Implement the Button Action


Try a real phone


The iPhone Simulator doesn't demo Settings > General > Accessibility > VoiceOver. You need a real phone for that, until we can get Apple to make more of a commitment to Accessibility.

To try a real phone, you need a friend with an Apple Developer subscription. US$100 per year plus tax was the cost to your friend, as of 2017.

<= Add Accessibility Information


Cooperate



Apple throws some more chores in here at random for you, not yet needed, but useful later. You may as well go along.

<= Connect the Rating Control to the View Controller
<= Clean Up the Project



Don't test Landscape View now


Apple doesn't mention that you've made only the portrait view work. You've broken the landscape view for devices smaller than an iPad.

Don't worry about it. You'll fix it soon enough.

<= Wrapping Up

 

Download and compare and commit



The download is 04_ImplementACustomControl. Your Commit Message can be "Implement a Custom Control". 

<= Wrapping Up



Back | Forward | Source: Apple Developer >
 Implement a Custom Control

Work with View Controllers

Back | Forward



Chapter 3 of 10 at Apple Developer > Jump Right In is Work with View Controllers.


As you learn more and more, you shrink the great yawning gap: you begin to know more and more of what Apple imagines they told you to know, and actually forgot to mention.


Diagrams help


Apple's 
diagrams do help explain Xcode. Talk with us if they don't make sense.

<= Learning Objectives
<= Understand the View Controller Lifecycle


Race ahead as needed


Apple wants you to jump to the end and download their work, so that you can borrow their "03_WorkWithViewControllers/Images/defaultPhoto.png". Somehow, they can't bring themselves to tell you that plainly.

Apple wants you give your UIImage the size of 320x320 size, so that it fits the Png you're borrowing.

Apple wants you to notice the nearly buried trailing note that suggests you choose Attributes > User Interaction Enabled = Yes. Somehow, they can't bring themselves to mention that later, when it becomes a crucial detail that stops you dead if you never got it right.

<= Add a Meal Photo
<= Display a Default Photo



PQ is often and not always a part of P


iOS really has pushed you to write one Func named "imagePickerController" and second Func named "imagePickerControllerDidCancel" without the shared name meaning much.

Both names begin with "imagePickerController", but the "imagePickerController" Func is not the whole of which "DidCancel" Func is a piece. Rather, both of these Func's are pieces: they are peers, not whole and part.

<= Connect the Image View to Code
<= Create a Gesture Recognizer



Learn the Info PList later


Apple says your app "terminates with a SIGABRT signal" till you learn the Info PList.

This isn't true.

Just keep moving.


<= Create an Image Picker to Respond to User Taps




Add the meal photos later




Apple says your need to import meal photos into your iPhone Simulator to demo your app convincingly.

This isn't true.

Just keep moving.

<= Create an Image Picker to Respond to User Taps


Download and compare and commit


By now you know the drill. This time the download is 03_WorkWithViewControllers. This time your Commit Message can be "Work with View Controllers". 



Back | Forward | Source: Apple Developer >
 Work with View Controllers

Connect the UI to Code

Back | Forward



Chapter 2 of 10 at Apple Developer > Jump Right In is Connect the UI to Code.



Don't need much vocabulary


Apple pushes hard for you to struggle to learn what all their words mean.

This is silly. They're flooding you with words you don't need. Xcode itself is tightly limiting your options. You can work all the way thru to the end and push out a well-running app without ever having made time to understand what a "superview" is, or "an implicitly unwrapped optional variable", and so on and on.

You really can focus on what they tell you to do, and learn what it means by watching what happens. Their diagrams do help. Their explanations in words aren't worth much. I'm here to argue most of their explanations in words aren't even worth reading, much less deciphering.

Apple mentions many technical terms you will learn someday, as if you need them now




Model, view, and controller


Xcode divides your app into three parts. Apple runs you on in without quite pausing to tell you this. The picture their authors have in mind as they speak is something like Wikipedia Model view controller.

Apple gives no definition for the few technical terms you do need now


<= Learning Objectives
<= Connect the UI to Source Code




Editor and Assistant Editor


Apple is trying to say that you often want to edit two things at a time, instead of just one.

That's it, that's all they mean, even though they go on and on.

For instance, all at once, you want to look at a Storyboard and also the Swift code running inside it. Well sure, you do. When they say "The Editor", they mean where you mess with the first thing you opened. When they say "The Assistant Editor", they mean where you mess with the second thing you opened.

You find the correct X to close the Assistant Editor.

You find the Pair of Overlapping Hoops to open the Assistant Editor, and notice they turn blue while it's open, and notice that opening the Assistant Editor gives you a second Pair of Overlapping Hoops just above whatever you're editing inside the Assistant Editor.

It's that second Pair in grey that sit next to some Triple Dots "..." in grey. It's those Triple Dots of that second Pair that give you an "Automatic" choice telling you what they guess the second thing should be to edit inside the Assistant Editor, after you select some first thing to edit inside the Editor.

Apple has forgotten the courtesy of drawing a new icon for each new thing


<= Create Outlets for UI Elements




Marks in the code


Apple tells you out loud that they want you to learn to make Marks before they show you what good they are.

Wow. Well, me, I find people giving mystic orders difficult to accept. If you like, go ahead and make three marks in the same file, so you can see how they work.

Before now, you've already found your grey Pair of Overlapping Hoops, and the Triple Dots just to the right of those. Now you can look out to the right end of that chain where you're told what Class you have selected inside the Assistant Editor. Click there to see all the Marks you have made inside that Class, and then click on a Mark to warp to it.

Apple has lost the discipline of introducing the new thing no sooner than it matters

<= Create Outlets for UI Elements



Drag it from where you can find it


Apple talks as if people always only Ctrl+Drag from the Storyboard into Swift.

Yea maybe. The thing is, you can look at two places on screen to see what you select inside the Storyboard. You can look at the Storyboard itself, your mock-up of an iPhone. But you can also look at the Document Outline on the left that shows all its pieces as a list of lists of lists of things, unless you've accidentally hit the Hide/Show Document Outline button to hide it.

And once you've learned to select things inside the Document Outline, you'll often find that easiest to hit with the mouse, select, and Ctrl+Drag from.

Apple introduces two in tandem by talking about one and ignoring the other

<= Create Outlets for UI Elements


One word and two


Apple pushes you to define a "mealNameLabel" and a "nameTextField".

They neglect to disclose the deeper structure of those choices. The structure is obvious only after you learn, and then still rudely hard for a new person to remember because of the choices they made.

The "mealNameLabel" is a first name of two words and a last name of one word: it is a "Label" that presents the "mealName".

The "nameTextField" is a first name of one word and a last name of two words: it is a "TextField" that presents the "name" of the meal. Indeed, one might say it is a "mealNameTextField", if giving your students all the consistency you can were a priority.

Apple has chosen example names so poorly as to trip up new people

<= Create Outlets for UI Elements




Don't trust every kind of undo


This is the place in the tutorial where learning to undo well really begins to matter. For example, near here, you may need Source Control > Discard All Changes, which should just send you back to the start of this chapter, if you ended the last chapter with a Source Control > Commit that worked.

Here now, if you misunderstand just enough to move ever so slightly off the one true path, like you accidentally make an IBOutlet where you wanted an IBAction, well, that's crazy hard to undo. You can undo everything you can see, without it really being undone inside, in the details that only "git diff" shows.

And while it's not really undone, your app will crash, yammering on about some mystic wound such as "NSInvalidArgumentException" "unrecognized selector sent to instance".

You can quickly back out, start over, and get it right.

Apple has forgotten to make your every likely error visible

<= Define an Action to Perform
<= Process User Input




Download and compare and commit


Apple ends this chapter, its chapter 2 of 10, with a download named "02_ConnectTheUIToTheCode". They're just meaninglessly sloppy, inserting an extra "the" into that name that's missing from this chapter's title.

Apple mentions the download & forgets to recommend compare at the end of each chapter.

As soon as you're sure you're finished with this chapter, you can capture your progress. Click back on thru Xcode > Source Control > Commit. Give it a Commit Message such as "Connect the UI to Code". Click to Commit Files. Be happy.

<= Wrapping Up


Back | Forward | Source: Apple Developer > Connect the UI to Code