Proving once again that I have a difficult time sticking with a side project I’m going to focus my attention on a flash card app. I’m not abandoning the quiz app. The simple question and answer infrastructure as well as the ideas for fill in the blank, matching, and ordering questions will find their place in future projects whether specifically a quiz app? I’m not sure.

The reason for a flash card app is a renewed interest in memorizing Luther’s Small Catechism brought on by the work at Lutheran Catechism. I figure I can help myself and help others by building this app.

Additionally, I’m going to do a better job of blogging about the development of the app. I would like to see a bigger ecosystem of Lutheran apps and I hope that blogging about it will inspire someone to learn and create their own or push someone to say, “heck I can do that” and build something better.

Non-Standard to Standard

It’s probably too early to worry about the look of the app, but I want the header to look like the Brainscape iOS app above. My initial attempt, after throwing out the default UIViewController, was to take a create a view that contained a navigation bar and a table view. With these in place I set out to make the status bar and navigation bar both dark and translucent so they would look like one unit and have the effect of allowing items to scroll underneath them.

After about 45 minutes of digging through StackOverflow and using trial and error. I chucked this attempt to roll my own. I dragged out a navigation controller and got what I was looking for. I hadn’t thought that this default would give me the control or look I wanted but looks like it is good, at least for now.

When starting a new project in Xcode the first decision you make is the type of application you are going to create. Master-Detail, Page-Based, Single View, Tabbed? My vision for the app is close to Master-Detail but doesn’t fit exactly so I decided on the Single View Application figuring that I would throw out the default UIViewController.

When I first started iOS development (think it was iPhone OS development) Interface Builder (IB) was pretty clunky and since I was used to creating Java Swing applications, it was no big deal to create the UI in code. It was also simple because there was only one screen size so you could hardcode coordinates and sizes with impunity. As IB has become more robust and has incorporated Auto Layout I do most UI layout in IB.

Now with this mixing of SpriteKit and UIKit I needed to once again place elements programmatically. The things is that SpriteKit and UIKit have their own coordinate system orientations (which I knew) and their own coordinate bounds as well (which I didn’t know). In my initial UIViewController I was centering a UIButton based on half the view’s width. And in my SpriteKit SKScene I was setting a UITextView based on half the view’s width. However, in the UIViewController the UIButton was centered as expected, but the UITextView would never line up right.

After playing with various iPhone Simulator hardware and experimenting with the code, I found that the SKScene bounding box was always 1024x768 and that the bounding box of the UIViewController was the device screen size (e.g. 1136x640 on an iPhone 5s). To get things to work as I expected, I had to get the SKScene as a UIView and then the bounds would be the device bounds. I could now manipulated UIViews in my SKScene but I would have to be aware of the specific device size.

This didn’t seem like a great path to follow. Apple’s whole trajectory is to move away from coding to specific device sizes. I vaguely remembered overhearing that there was a way to do Auto Layout programmatically. After a Google search or two I found some Swift examples of programatic Auto Layout. I was able to put together this code to get the effect I wanted in a non-device specific way:

let viewDictionary = ["textView": textView]
let textViewConstraintV = NSLayoutConstraint.constraintsWithVisualFormat("V:|-2 0-[textView(100)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewDictionary)
let textViewConstraintH = NSLayoutConstraint.constraintsWithVisualFormat("H:|-50-[textView]-50-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: viewDictionary)
view.addConstraints(textViewConstraintV)
view.addConstraints(textViewConstraintH)

I chose to use the “Visual Format Language” in this case. I’m not sure if I’ll stick with this or move to the object-based way of creating constraints. Either way, I’m glad I learned a couple of things even though I found a better way to accomplish the desired effect.

I knew I would eventually run into a decision regarding how to write something based on whether or not it was testable, and I’m actually not that surprised that it came early in the project. Xcode UI Testing leverages iOS’s accessibility functionality. That works great for standard UI elements, but Table Talk Quiz is SpriteKit based, and while most of the UI elements will be text labels or fields and buttons I imagined using SpriteKit to do the animations and any special effects.

Sticking with SpriteKit

My first decision was that I’m going to stick with SpriteKit. I want the option to use the effects and animations that SpriteKit provides. I can see using them for “win” and “loss” fanfare and background effects. The problem is that SpriteKit nodes aren’t testable (at least I didn’t find a way) so I wouldn’t be able to use BDD. Of course I already had a test for the start button which is an instance of UIButton which is testable. The mixing of UIKit classes and SpriteKit classes is fully supported, but I found that I have to do a little more management of the UI elements. Also, there will be a mix of UIAnimation and SpriteKit animation code which was what I was hoping to avoid, but software development is always about compromise and in this case I will sacrifice the cleanliness of a single animation type for the ability to continue my attempt at BDD.