Apple’s 40th

I’m feeling more emotional today than I thought I would. Today is Apple’s 40th birthday and I sit here reflecting on what that means to me on the bus heading in to work.

I feel an immense sense of gratitude and appreciation for this company. This affection and admiration started when I was a teenager and has only continued since. Apple is a company that still fundamentally believes in their mission to make the world a better place. This has been shown to be even more true once I joined the company and am on the inside.

I used to be afraid of corporations leading the world and taking on a bigger role than they should. I still am, I suppose. But Apple has shown me that this fear can sometimes be relaxed. That some can have grander goals that coexist with the traditional ones of being a large business. Their work on the environment, their unwavering defense of civil liberties, and desire to mesh technology and art are noble goals that make me want to work even harder to help continue this company’s mission.

I’m proud to work at Apple and hope to make some small difference in the work we do here.

Here’s to the next 40 years.

Secret Santa Sort

I finally got around to working on Brent Simmons’s challenge (or, rather, his pointer to a challenge) for implementing a Secret Santa sort. His original post is here and my Gist implementation is here. I like this solution as it effectively treats an array as a circularly linked-list in order to find a valid Santa assignment. This is meant to be run from the command line with the command cat secret_santa.txt | swift santa_sort.swift on a file like this:

Let me know if you have any suggestions or spot any errors!

Swift 2.0 and ReactiveCocoa 4

When I set out to learn ReactiveCocoa I couldn’t find any guides that quickly got me setup and working with the latest version and Swift 2.0. So, after a bit of experimentation and trial and error, I’ve found a way to get things working with the 4.0 alpha 1 version of ReactiveCocoa and Swift 2.0 with Xcode 7. This has been cobbled together with my poking around in the source of ReactiveCocoa (v4 is available here) and going through their examples. If you’ve played with the RAC examples before then this should look somewhat familiar. All this app does is create a SignalProducer on a text field and make a network request to a server to pull down what was typed into the field and display this on the screen. It’s not meant to be a complete “best practices” guide about ReactiveCocoa but rather simple environment setup instructions. My code is available on GitHub but this guide should provide the nuts and bolts of what an average user needs to get started. Here we go.

First, create a new Single Page iOS application in Xcode 7. Once this has been created, add a Cartfile to the root directory that contains just the single line:

Now, ensure that you’re using the Swift 2.0 version of ‘swiftc’ as the 2.1 version can cause problems. To change it follow this explanation. Once you’ve done this run the Carthage update command as follows:

This should now build your appropriate Framework files. Head into the Finder and drag the Frameworks into your Xcode project. Be sure to add them to the Embedded Binaries portion of the app configuration. It should look like so:

Screen Shot 2015-10-01 at 6.51.09 AM

With iOS 9 it now disallows all communications to any insecure (ie HTTP) endpoints unless explicitly told to whitelist some or all sites. This is easy enough to fix with the NSAppTransportSecurity  key in Info.plist. Add this key as a dictionary then add the key NSAllowsArbitraryLoads  to this dictionary as a boolean set to YES.

Next, place a UITextField  and UILabel  on the main screen in Storyboard and wire them to the textField  and nameLabel  properties in the ViewController.swift file. Test by compiling and fix any AutoLayout or compiler errors.

Finally, since this app is hitting the network looking for a JSON response we need a server to do that. I quickly made a Node.js server that will work for our needs. To use this make sure you have Node.js installed and save the following source in a file named server.js . Using a terminal, navigate to where you saved it and run npm install express  (express is the only node module dependency). Finally, ensure nothing else is using port 8001 and start the server with node server.js . Here’s the code:

Once the server is up and running your iOS app should be able to communicate with it! This is a very simple example of using ReactiveCocoa but there were enough pitfalls when trying to use the latest version that I thought I’d write this up. Again, all iOS source is available on my GitHub account. Please send any questions in!

Working with UIScrollView and Autolayout

Over the last few days I’ve read many, many posts on how to work with UIScrollView and Autolayout. Everything (including Apple’s documentation) is nothing but a convoluted mess. This article aims to provide the definitive source on using UIScrollViews within the Autolayout world. You can check out the source code to this demo application here.

Note that this article does assume some prior familiarity with the Autolayout system.

Embedding a view’s content within a UIScrollView is Apple’s recommended way for adjusting a view to compensate for the onscreen keyboard. Traditionally, this adjustment has been done with the use of frames. The introduction of Autolayout meant abandoning most use of frames but the need still exists to move content around on the screen with a UIScrollView and Autolayout. Here, I describe the steps involved to use these two technologies together.

To begin, there’s two ways to do it (well, really only one correct way to do it) but I’ll only be documenting one of them. The first method relies on adding subviews directly to the UIScrollView with no Container View. This is a pain because you must rely on tricks with the superview to make sure things align properly. It’s not fun.

However, the proper way to do it is easy and makes sense — once you understand it, of course!. Let’s dive right in.

1) Begin by creating a new ViewController in your project and add a UIScrollView to it.

step_1_2048x1305

2) Now, create constraints by CTRL-dragging from the UIScrollView to the View. You’ll want to create 4 constraints (hold the SHIFT key to select multiple): Leading, Trailing, Top, and Bottom constraints. Important: hold the OPTION key while doing this to align the UIScrollView to the Container (not the Container Margin).

3) Add a UIView to the UIScrollView and set up the same constraints as before: Leading, Trailing, Top, and Bottom. Notice that these constraints will already default to the Container (not the Container Margin). It’s handy to rename this newly added UIView to Content View for easier referencing later.

4) Now we’re going to add a few temporary constraints to make Interface Builder happy and for ease of understanding on our end. Add a constraint to the Content View for width and height and check the property Remove at build time:

step_4

 

This Remove at build time property will allow Interface Builder to fully compute our layout but the app will remove the constraints at runtime as they will be generated dynamically.

5) Finally, we can get to adding some content to our views. Drag a UIImageView out onto the Content View and make it 250pts wide and 250pts high, 20pts from the top, and centered along the Content View’s X axis. Additionally, make sure to add a sample image to the project so we can see something onscreen:

step_5_6_2048x1305

 

6) With this now setup add a UILabel centered on the image and spaced 500pts below it. Now, very carefully add one of the most important constraints: from the label to the Content View’s bottom. When you do this you can either set the Constant value to 0 or to Standard, whichever makes the most sense for your app. Adding these constraints should look something like this:

step_7_2048x1281

 

7) Next, add an Outlet from the Content View to a property within the ViewController class that is backing the Storyboard. I’ve named my property contentView. Like so:

step_8_2048x1281

 

8) Finally, you’ll add the following code to the viewDidLoad method of the ViewController class. This code binds the Content View’s Leading and Trailing edges to the root UIView’s edges. This allows the UIScrollView to implicitly calculate it’s contentSize and render the view appropriately. Run the app and you should have a label below your image and scrolling working as expected!

Following these steps should result in a functioning UIScrollView with Autolayout. I won’t cover the steps involved to show and hide the keyboard but that’s all covered in the aforementioned article by Apple.

Xcode Server Slack Integration

After spending a day last week struggling to get a working integration of Xcode Server and Slack (the popular messaging platform) I finally have arrived upon a reliable solution. What started out as a long bash script (and sed, and cut, and tr) that eventually called a Python program, is now just a Python program run by the Xcode ‘Trigger Script’ functionality. Read on for how I did it.

Working with a client on an iOS app we wanted to keep everyone aware of the project’s progress and the current state of all tests, both server and iOS. So, our team added the client as a Slack single-channel guest and got to work integrating our server-side Strider Continuous Integration server and Xcode Server.

Not knowing any better I dove into the output of the Xcode Build located in /Library/Developer/XcodeServer/IntegrationAssets and poked around. I found the file buildService.log which contained build output detailing everything I needed to know about the build, looking like this:

Which, I immediately thought, “I know, I’ll tackle it with bash and sed!”. So I got to work writing a script to parse these entries and ultimately distribute them out to our Slack channel so everyone can see progress as we go along. Here’s the bash script I wrote:

This seemed to work! But, however, proved problematic as I discovered (only after I’d written the script!) that there lies a chicken-and-egg problem with when Xcode will execute a script versus when it’s all done packaging up the buildService.log files. The pattern that Xcode follows is: run the project tests, run the post-process script, then build the buildService.log files. So, the script above was running on a previous build, not the most current one.

I poked around a bit more but ultimately couldn’t come up with a solution of how to solve this. So, I searched around on Twitter and found @mjmoriarity, a wonderfully helpful Apple engineer who pointed me towards my ultimate solution of using Xcode’s set environment variables. Using these, my script was now reduced to a handful of lines and is wonderfully reliable:

UIImage File Extension

The UIImage class is a bit tricky to use when instantiating images from the Assets Catalog in Xcode. The tricky part is specified in the imageNamed class method of the UIImage class (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/Reference/Reference.html#jumpTo_19):

On iOS 4 and later, if the file is in PNG format, it is not necessary to specify the .PNG filename extension. Prior to iOS 4, you must specify the filename extension.

So, you may see sample code that does not specify the extension when creating new images. This shortcut is only valid for PNG files so all other extension types need to specify. What makes it tricky is that the class method will return nil if the image is not found and the UIImageView.image property will accept this nil without complaining making it seem like everything is working.

UIFont Families

For my own future reference, here’s a list of all available UIFont Family names in iOS 8:

Academy Engraved LET

Al Nile

American Typewriter

Apple Color Emoji

Apple SD Gothic Neo

Arial

Arial Hebrew

Arial Rounded MT Bold

Avenir

Avenir Next

Avenir Next Condensed

Bangla Sangam MN

Baskerville

Bodoni 72

Bodoni 72 Oldstyle

Bodoni 72 Smallcaps

Bodoni Ornaments

Bradley Hand

Chalkboard SE

Chalkduster

Cochin

Copperplate

Courier

Courier New

DIN Alternate

DIN Condensed

Damascus

Devanagari Sangam MN

Didot

Euphemia UCAS

Farah

Futura

Geeza Pro

Georgia

Gill Sans

Gujarati Sangam MN

Gurmukhi MN

Heiti SC

Heiti TC

Helvetica

Helvetica Neue

Hiragino Kaku Gothic ProN

Hiragino Mincho ProN

Hoefler Text

Iowan Old Style

Kailasa

Kannada Sangam MN

Khmer Sangam MN

Kohinoor Devanagari

Lao Sangam MN

Malayalam Sangam MN

Marion

Marker Felt

Menlo

Mishafi

Noteworthy

Optima

Oriya Sangam MN

Palatino

Papyrus

Party LET

Savoye LET

Sinhala Sangam MN

Snell Roundhand

Superclarendon

Symbol

Tamil Sangam MN

Telugu Sangam MN

Thonburi

Times New Roman

Trebuchet MS

Verdana

Zapf Dingbats

Zapfino

Javascript Library Includes

While this may be extremely obvious to most people I’ve seen enough questions on StackOverflow and the like to warrant a mention:

When you’re using a Javascript library that depends on JQuery (or any other library for that matter), include the JQuery library before all others

Now, most people who get stuck with this problem may be coming from an IDE background where we have fancy tools to help negotiate dependencies. Most of time time, the browser can be smart about how it does resource-gathering but in this case Javascript doesn’t work like that. You’ll get strange errors that seemingly have nothing to do with your code.

So, for reference, include your depended-upon libraries first:

Peripheral Intimidation

Driving from Seattle to Portland with some regularity gives me a chance to stop (and go, and stop) and think for a bit. As with every car drive I begin to mull over what’s been on my mind recently – usually development-related issues. The last drive I stumbled across a comparison that helps explain a distraction I’d been experiencing recently in my work. The analogy? Software and semi’s.

Being a part of any development community means being exposed every day to amazing work done by amazing people. Continuously seeing all the cool things people are doing it’s hard not to draw comparisons to your own work. The feelings of inadequacy and Impostor Syndrome, unless carefully monitored and controlled, are inevitable and intense. Because the names of the people creating these apps all seem to blend together after a while, it feels like one single, impressive, superhuman coding all these apps, sites, and documenting every step of the way. Someone more talented, thoughtful, creative, and with more perseverance than you could ever dream of. In essence, a hulking semi of app-creating power rocketing down the information superhighway (see what I did there).

It’s natural to feel small compared to these semi’s. In fact, it’s probably healthy as it pushes us to continue to sharpen our saws and elevate our skills.

But it’s so critical to remember that each cool thing being churned out of this great internet machine was created by regular people. People who found a niche, pounded hard at it, and after many failures and false starts arrived at something close to the final product.

Mike Lee, a developer I’ve long respected for his talent and design skills, was recently interviewed and outed that he’s a just regular guy, not superhuman. If you haven’t yet seen it (or listened to the MP3) it’s well worth your time. One of the smartest guys running in Mac/iOS development circles is an ordinary dude. It doesn’t get much more inspiring than that.

So, just as you continue to suck it up and drive down freeways past the hulking semis, development should continue as well.