Next Tuesday, Tampa iOS Meetup — Tampa’s gathering for people who are new to programming or new to iOS development — will walk through the development of building a guided meditation audio app. Think of it as the 21st century answer to the relaxation tape, CD, or MP3 (depending on what generation you’re in), where a narrator with a soothing voice guides the listener through exercises designed to bring about mindfulness, ease tension, and remove stress.
As we build the app, we’ll cover a couple of key topics in iOS development with the Swift programming language:
Error handling in Swift: responding to errors gracefully rather than having the app come to a crashing halt and annoying the user.
Playing sounds: Playing both short sound cues and effects, as well as longer recordings.
Auto layout: Building user interfaces that adjust themselves to the screen size, from the tine iPhone 4S all the way to the large iPad Pro
Join us, next Tuesday, March 28th at 6:30 p.m. at the Wolters Kluwer office (1410 N Westshore Blvd, Tampa) in Westshore for Tampa iOS Meetup’s session on building a guided meditation audio app! We’ll provide food and drink — bring your Mac laptop, and be ready to code!
As I mentioned earlier, Tampa iOS Meetup is the Tampa Bay area’s meetup for beginning programmers and developers new to iOS development. Each meetup has two parts:
The presentation, where we’ll cover the concepts you’ll need to write the app of the day, followed by
The workshop, where we’ll actually code the app together.
The meetup works best if you bring a Mac laptop with the current version of Xcode (the tool we’ll use to develop iOS apps) installed. If you don’t have one, don’t worry; you don’t need one for the presentation part, and we can form teams for the workshop.
We use the presentation-followed-by-workshop approach because it’s our answer to a question that I’ve been asked again and again, and it goes something like this:
“I’ve been studying iOS development for some time, and I’m still having a problem writing apps. I know how to program specific features in iOS, but I don’t know how to turn a bunch of features into an app.”
It’s one thing to go through tutorials that show you how to program a specific feature. It’s a completely different thing to take the knowledge from those tutorials and then write an app. My goal for Tampa iOS Meetup in 2017 is to show you how to make that leap by walking you through the process of making apps.
Special thanks to our sponsor
Tampa iOS Meetup wouldn’t be possible without the generosity of Wolters Kluwer. They provide both the space in which to hold the meetup, as well as the food and drinks! Special thanks to John Wang, my go-to guy at Wolters Kluwer, and source of valuable feedback for my presentations.
Craig Clayton is one of the heroes in the Tampa tech scene. He organized and ran the Suncoast iOS Meetup here in Tampa as well as intensive iOS coding academies, and he makes a living writing mobile apps. If you’re a Patriots fan with an iPhone, chances are you’ve used his app. He’s been quite busy for the past little while, and if you’re interested in iOS development, you might be interested in what he’s up to…
On Saturday, April 1, Craig will be leading Swift 101: Getting Started, a full-day live online class where he’ll guide you through the process of building a Square Case-like iOS app, using iOS features such as Contacts, SiriKit, and TouchID. By the end of the session, you’ll have a better understanding of how to create apps for the latest version of iOS.
You won’t have to go anywhere to attend — it’ll be an online class taking place on Saturday, April 1, 2017, from 10:00 a.m. through 5:00 p.m.. The course will cost US$50 to attend, plus a US$2 credit card processing fee. There’s a limited number of slots for the course, so reserve yours now!
If you’d like to get a better idea of what the course would be like — or if you’d like to supplement your iOS development studies — check out Craig’s book, iOS 10 Programming for Beginners. Like the upcoming online course, it’s aimed at beginners, but it’s full of material useful even to experienced iOS developers.
Most of the book, is devoted to building a single application: Let’s Eat, a restaurant review app that becomes more sophisticated and gains more features with each chapter. Each chapter begins with an explanation of the topics that will be covered, and features both clear explanations of those topics, along with step-by-step instructions for turning those topics into working code. Craig does an excellent job of explaining what he did with his code and why he did it. As you work on Let’s Eat, you’ll have built a professional-looking app that uses a number of iOS features, including GPS and maps, the camera, iPad multitasking, iMessage, and even 3D touch. When you’re done, you should be able to take the knowledge from working on the app and apply it to your own projects.
If you’re interested in the process behind the creation of Craig’s book, read his article, Using Kaizen to Improve as a Developer, in which he writes about adopting kaizen, the Japanese business philosophy of continuous improvement at all levels of an organization, in all areas.
Ben Affleck’s interview scene in Good Will Hunting.
Once, when asked the dreaded “Where do you see yourself in five years?” question in a job interview, I answered “Standing on a mountain of my defeated enemies.” Now, the interviewer and I knew each other enough for this joke to work, but that was just fortunate circumstance. Should you find yourself in the same situation, here are some articles on answers to the “five years” question:
What would you say are your biggest weaknesses? (My favorite suggestion: “Remain silent, and pull an index card out of your pocket that says ‘I over-prepare’.”)
How much money do you currently make?
Where would you ideally like to work?
If you were an animal what animal would you be?
I notice there are gaps in your CV, why’s that?
You seem overqualified, and might get bored here. What do you think about that?
“Many of our employees are young and put in 14-hour days. Are you up for that kind of challenge?”
“Congratulations on returning to the workforce. Given your family, will you need a flexible schedule?”
“When did you graduate from college?”
“Where are you from?”
“How can our company get better at recruiting people of color?”
“Can you tell me about your disability and how it has shaped you?”
“Have you worked with women bosses in the past, sir?”
“Our employees must look and carry themselves in a certain way. Would you be able to arrange your financial circumstances to rise to the occasion?”
Don Georgevich of JobInterviewTools.com has a set of useful videos on answering job interview questions, such as this one on top 10 interview questions, including “tell me about yourself”, “why should we hire you?”, “what are your strengths and weaknesses?”, “why did you leave your last job?”, and more:
Here’s a Georgevich video that focuses on “tell me about yourself”:
And here’s one about “behavioral” or “identity” questions, which are questions that try to determine your traits, motivations, likes, and dislikes:
Are you looking for your next great hire?
I’m looking for my next great job! If you’re looking for someone with desktop, web, mobile, and IoT development skills who can also communicate to technical and non-technical audiences, or a marketer or evangelist who also has a technology background and can code, you should talk to me.
An Alexa Skill is a voice interaction capability for Amazon’s Alexa voice service, which runs on various Amazon devices including the Echo, Echo Dot, Tap, Fire TV, and Fire Tablet, as well as some non-Amazon devices such as the Triby Bluetooth speaker. They’re similar to voice commands to the computer on Star Trek: there are Alexa Skills to tell you what the local weather is, play music, set an alarm or timer, answer health questions with the help of WebMD, plan vacations with the assistance of Kayak, order pizza, check stock prices or your bank balance, and more.
In this first meetup, they’ll do a step-by-step walkthrough that will show you how to create a simple Alexa skill. While knowing how to code will be helpful, coding skills aren’t absolutely necessary. Bring a laptop, and make sure you have an AWS account and an account for the Amazon developer portal. An Alexa device isn’t required — you can test Alexa skills via the developer portal, and there’s an iOS/Mac OS app that lets you use Alexa without an Alexa device.
Ybor Tech’sOpenHack is your monthly opportunity to get together with local techies at New World Brewery and socialize over craft beer (you buy) and pizza (they provide) at Ybor City’s most laid-back bar!
Lean Beer is the evening version of Lean Coffee, where people gather to discuss Lean and Agile practices over their adult beverage of choice. Participants propose discussion topics, discussions are timeboxed agile-style, and the conversation and company are always informative and lively.
If you’ve got tech event in or near the Tampa Bay area that you’d like to see announced here, drop me a line at joey@globalnerdy.com and let me know the details!
I’ve spent the last couple of days working on a magnum opus job application for a position at a software company you may have heard of. After submitting it this morning, I thought all that effort would be wasted if it were used on just one prospective employer. So I’ve decided to post the job application here on Global Nerdy, with any information about the company and role removed.
Feel free to share this with your friends and spread it far and wide. If you think that you or your organization would benefit from employing the sort of person who’d put in the effort to create this kind of work, feel free to contact me at joey@joeydevilla.com!
My name is Joey deVilla, and I want to be [Company X]’s [job title]. I’m a technically-minded person with a history of communicating and collaborating with developers, I’ve designed and documented desktop, web, and mobile software, and I have experience managing projects that delivered both software and services.
Contents
This is a long document written in response to [the online questionnaire] so I’ve provided this table of contents to make it easier to navigate.
I would be a great fit for [Company X]’s [job title] role. As a developer, I understand the work, the joys, and the frustrations of building applications. As a technology evangelist, I know how to talk to (and more importantly, listen to) developers and technology decision-makers, and help them understand and make the best use of the developer tools and platforms that I’m evangelizing. These two roles, which I’ve had for most of my career, make me particularly suited to managing [Company X]’s developer platform.
I enjoy making things, and I enjoy helping makers make things. I want to take the next logical step: making things that help makers make things. The [job title] role sounds like a dream opportunity, and one where I could serve [Company X] and the developers that build on it well.
How technical am I? Well, in just the past two weeks…
I won the “Judges’ Fetish” prize at GM’s Makers Hustle Harder hackathon at Tampa Hackerspace. GM is holding hackathons in three cities this year to promote their new Next Generation Infotainment (NGI) API for their in-car dashboard consoles. The API gives developers unprecedented access to nearly 400 data points (speed, door status, fuel level, lateral acceleration, and so much more), the audio playback system, and navigation. Developers write apps for the platform using the HTML5/CSS/JavaScript trio and the NGI SDK, which includes an emulator. At the hackathon, developers had the chance to install their apps on actual cars’ consoles to try out their apps in real life.
I contributed to one serious app (WeatherEye, which takes the car’s current speed and heading and displays the weather conditions 10 miles ahead) and put together a not-so-serious serious app (Shotgun, which determines who of a number of passengers gets to ride shotgun), but my winning app was one I threw together at the last minute: Fitness Fire Drill. It referees the car game classically known as “Chinese Fire Drill”. With all passengers in the car and all doors closed, the game begins when someone presses the start button. Players must exit the car and run around it once, return to their original seat, and close the door. When the last door is closed, the game ends, and the app reports the team’s time.
I wrote an Android app for an upcoming article at a well-trafficked mobile developer site on face detection and adding cartoon features to people’s faces like Snapchat does. The code lives on my GitHub, under the name FaceSpotter.
I taught beginners how to write “fortune cookie”-style apps in Swift for the iPhone and iPad at Tampa iOS Meetup, a regular gathering of new iOS developers that I run. I followed it up with an article that covers the material in the meetup and walks the reader through the process of building a “fortune cookie’ app called Oblique Strategies, an app that suggests randomly-selected ways to break past a creative block.
I have continued with my work writing a tutorial for the Smart Cosmos RFID/real-world object virtualization API, using code examples in Ruby and PHP and Postman as a container.
My recent work experience
In my most recent role as Smartrac’s Technology Evangelist, I wrote API tutorials and scripted API demo videos, met with major clients and partner organizations to discuss their requirements, and performed demonstrations of the company’s integrated RFID hardware/cloud software platform at the 2017 National Retail Federation “Big Show” conference in New York.
A video that I wrote, produced, narrated, and edited on behalf of GSG for IBM’s NICO program.
At GSG, I worked closely with IBM’s NICO (Network Infrastructure Cost Optimization) team to build NICO Quick Assess, a custom online questionnaire (they didn’t want to use “canned” solutions such as SurveyMonkey for security reasons) that served as an initial enterprise telecom audit. It was designed for an audience of finance and technology decision-makers at enterprises who spent at least $5 million/year on telecommunications and networking. Working with telecom auditors and IBM executives, I designed the questionnaire and oversaw its implementation.
As the CTO, I oversaw the development of web-based and mobile software at Comprehensive Technology Solutions, including a web app that helps medium- to large-sized enterprises move their employees from corporate-liable mobile devices to indvidual-liable ones, as well as an app that runs diagnostic checks on iOS and Android smartphones.
I have a strong grasp of API and data fundamentals
I’ve been on both sides of the API divide: a developer using other people’s APIs, and a developer evangelist who’s helped developers use my company’s APIs.
I’ve spent long days and nights trying to get an application to work with an API only to discover that it was my misunderstanding of the API that was causing me all that grief, and I’ve seen the “a-ha!” moment of realization on developers’ faces after explaining a poorly-documented API to them. I’ve even helped developers come up with solutions to their problems and brainstorm new, interesting, and unusual uses for an API.
I just won a prize at a hackathon where we had to write apps using GM’s Next Generation Infotainment API, which provides access to nearly 400 data points in GM’s newest cars, and am currently working on an article that showcases the Android Mobile Vision APIs, namely the text recognition and face recognition APIs. I worked at Microsoft just long enough to have some experience with SOAP APIs and know why you should avoid them whenever possible.
I’m comfortable with a number of different flavors of SQL, from Microsoft’s Transact-SQL (used in SQL Server) to PostgreSQL to MySQL to SQLite. I’ve played with MongoDB, CouchDB, and Azure storage. I’ve also written scripts to pull data from and write data to Excel files, .CSV files, tab-delimited files, Dbase exports, well-formatted XML and JSON, poorly-formatted XML and JSON, and some of the most messed-up text files you’ve ever seen.
Before I switched to computer science, I was an electrical engineering student, and had to take all the requisite math and stats courses, so I know my median from my mean from my mode, and I know that a “standard deviation” doesn’t mean getting a piercing somewhere other than the ear. I’m comfortable with analytics of all sorts, from web analytics tools to see how well a piece online is performing, to application analytics tools to see how well an app is (or isn’t) performing.
In the end, this role is all about the API, and ensuring that developers can quickly and easily use it. While [Company X]’s goal is to get more applications to make use of [Company X] more often, it’s important to remember the developers’ goal, which is to ensure that their application works and that their users are getting what they need from it — to them, [Company X] integration is just a means to that end. If the [Company X] integration experience isn’t clear, or simple, or efficient, or unobtrusive, developers will simply avoid [Company X], and that’s not what we want.
I love talking to developers
Meeting Linus Torvalds at LinuxWorld Expo NYC.
Talking with developers, writing for developers, making podcasts and video for developers, and building developer communities is what I do, and this would be a fundamental part of what I would do as [Company X]’s [role].
Ever since that LinuxWorld Expo when I jumped in front of a news camera with my accordion and parleyed it into an interview where I talked about my company and its P2P platform, I’ve held developer evangelism roles at a number of prominent places, including Shopify,Microsoft, and Tucows.
Me and Steve Ballmer at the Canadian Windows 7 launch in Toronto.
I was hired by Microsoft not just to be an evangelist, but to be a “square peg in a round hole“. I came there from the world of open source and found myself talking to developers who were deep in Windows culture. I specialized in presenting topics, technologies, and practices that were well-covered in the open source, but less so in the land of Windows and .NET, which at the time included MVC web frameworks, PHP, JavaScript, mobile development, and distributed version control.
I helped build bridges between the open source and Windows worlds by trying seemingly crazy things such as speaking at open source conferences, getting Microsoft to sponsor an Android developer conference (they were short money, and for some reason, they weren’t able to get sponsorship from Google)…
I was Microsoft Canada’s most prolific blogger, having written nearly 750 articles between January 2008 and April 2011 on Microsoft’s “Canadian Developer Connection” blog. I was also editor of the Canadian edition of the MSDN Flash newsletter, which was sent to 48,000 Canadian subscribers every two weeks. My work promoting mobile development earned me a spot on the Windows Phone 7 Champion team, a group of Microsoft employees hand-picked to promote the then-new Windows Phone 7 platform. I also oversaw Windows Phone 7 beta testing program for Canadian “breadth” developers, which included providing them with advance access to phones, developer support and documentation, and even organizing showcase events like this one:
At Shopify, I helped put together the Shopify Fund, a $1 million fund that helped sponsor developers who wanted to work full-time on building high-demand apps for the Shopify platform:
I also represented Shopify on the 2011 BarCamp Tour, where I talked to developers and entrepreneurs at BarCamps in eight cities all over the U.S., and wrote articles for the Shopify blog.
I’ve also done video aimed at developer audiences…
I’ve even done video for developers of the junior variety:
I’ve expanded my audience beyond developers to talk to business decision-makers, such as with this webcast I did for Enterprise Mobile, a subsidiary of Honeywell:
When I lived in Toronto, I was a steward of http://barcamp.org/w/page/402370/DemoCamp a monthly “show and tell” for local developers…
I love setting my own course, and doing so efficiently
I’m a firm believer in gaining a clear understanding of the “what” and “why” of “commander’s intent” — the desired end state of a group of organization — and then running with it and coming up with the “hows” that help the group reach that desired end state. I take great care to communicate my efforts within the organization in order to make clear how I’m helping to achieve the desired end state.
I’ve spent most of my career working either at startups, and when I’ve worked in larger organizations, I’ve either been part of or spearheaded “intrapreneurial” efforts within those organizations. I know that in these situations, your actions have to make the most of existing resources, or as I like to say, “make a buck out of ten cents”. I work to ensure that any work product I create can be reused in a number of scenarios and media, and that my efforts scale.
As a startup, [Company X] has to “punch above its weight”; there just isn’t room for wasted effort. It needs people who are self-starters that can work with a distributed team and make smart judgement calls with a minimum of hand-holding. That’s the sort of work I’ve been doing for the past decade, and the work I’d love to continue doing with [Company X].
Aspirations Winery’s Wine Crush:repository and site. This is the code for my app in the App Store, a “Candy Crush”-style game written for my friends’ winery.
Fitness Fire Drill: One of my submissions for the GM “Makers Hustle Harder” hackathon. This one won the “Judges’ Fetish” prize.
FaceSpotter: An in-progress app demonstrating Android’s face detection API.
Global Nerdy is my technology and software development blog, and it’s been active since the summer of 2006. I’ve published over 3,200 articles in it, and the blog has over 8.6 million pageviews over its lifetime.
The name “Global Nerdy” came from “The Duke of URL”, an application I wrote to demonstrate Tucows’ “Namespinner” API, which provides a list of available domain names based on keywords that you provide it. You can see this API in action when you visit their domain name site, Hover.
The projects that I’ve done with employers are covered under non-disclosure agreements, so I’ve chosen to discuss one that I did on my own: Aspirations Winery’s Wine Crush, a “Candy Crush”-style game with Aspirations Winery’s branding.
Wine Crush is an iPhone/iPad app that I posted to the App Store in July 2016. It’s available for free, so if you want to install it on an iOS device, use this App Store link. Alternately, you can watch this video, which provides a quick overview of the app:
I approached Bill and Robin Linville, Aspirations Winery’s owners, with a proposal to create an app for them at no cost to them other than the occasional free bottle of their wine. They would get something most small wineries don’t have — their own branded promotional app — and in return, I could add an app to my portfolio.
Building on a game engine
The goal of the app was to promote Aspirations Winery with a simple, addictive, enjoyable mobile game. The game didn’t have to be original; this was advertising that just happened to be a game rather than a game that just happened to contain advertising.
With this goal in mind, I decided that rather than build a game from scratch, I would start with an existing game engine, and then build upon it. I decided to base the game on “Cookie Crunch”, a basic “Candy Crush” game engine presented in a series of tutorial articles on the mobile developer site RayWenderlich.com. Code posted on that site is freely available for anyone to use in their own projects, and using their engine as a basis for my app would easily save dozens of hours of development time.
If you follow the steps in the tutorial article series, you will end with a basic “Candy Crush” game that looks like this:
The game has a single level; once you clear it, you play the same level again. The code has some “scaffolding” for adding different levels to the game, but implementing them was left as an exercise for the reader.
My plan was to take the basic game from the tutorial and expand upon it to include the following:
A title screen, which would present the following options to the user:
Start a new game.
View instructions on how to play the game. This would require adding a new “screen” to the game, which would display the instructions.
Visit Aspirations Winery’s site. This would be done by opening Safari and pointing it at Aspirations’ site.
Multiple levels. In the basic game, once the user cleared a level, s/he would be presented with the same level again. The finished game should feature a few dozen different levels, each one slightly more difficult than the last. The background image should be different for each level.
Gameplay features:
A hint button. When I showed the basic game to Aspirations’ owners, they requested a “hint” button similar to the ones that appear in “Candy Crush”-style games. When a player is stuck and can’t see any possible moves, s/he could press the button and be shown one of those moves.
“No possible moves” detection. There are times when no moves will be available to the player, especially on the more difficult levels. The game announce this to the player. If the player has at least two moves remaining, the game should tell him/her to use the “shuffle” button. If the player has one or fewer moves left, the game should end.
A target score display. This should display the number of points remaining for the player to reach the next level.
A “quit” button. This should cancel the game and return the player to the main screen.
Branding: The basic game features cookie-themed graphics and sounds. The final game should feature wine-themed graphics and sounds, as well as Aspirations Winery’s branding.
Phase 1: Language upgrade and some new graphics
At the time I started working on the app, the game engine in the tutorial was written in Swift 1, and the current version of Swift at the time was 2.0. Version 2.0 introduced significant changes to Swift’s syntax, particularly with error handling. I decided that my first step should be to port the game engine code from Swift 2, partly as an exercise in learning the new syntax, and partly in order to avoid having to pay off technical debt at a later date.
Xcode provided a Swift 1 to Swift 2 automated migration tool, but some of the changes in syntax were large enough that an automated tool couldn’t perform the migration. I first used the automated tool to migrate the code, which still left about two dozen parts of the code that needed to be migrated manually. I marked those parts with // TODO: comments, which makes them very easy to find within Xcode. I then manually migrated them one by one.
The migration process was relatively straightforward; I completed it and tested my changes over two evenings.
With the basic game upgraded to Swift 2.0, it was time to present a basic version to the client. I made some new wine-themed icons and an impressionist background used them to replace the original game’s cookie-themed icons and background. The game now looked like this:
At this point, it was still a single-screen game with just one level, but it was now something that the client could try out on their iOS devices.
Making test versions available to the client
There are only a couple of ways for beta testers to install test versions on their iOS devices. I thought about using the TestFlight beta testing service, but the process at the time was so convoluted and confusing to the client that I opted for the lower-tech method of sending them the application package, and having them use iTunes to install the package. I provided them with a set of easy-to-follow instructions for installing beta test versions, which you can download here.
New graphics
With a test version to play with, the client had a much better idea of what the final product could be like. They provided me with four of their labels, which they wanted to use a backgrounds for the game. We decided that as the player progressed from level to level, the backgrounds would cycle in round-robin fashion:
For level 1, wine label 1 (Swamp Juice) would be used as the background
For level 2, wine label 2 (Tropical Paradise)…
For level 3, wine label 3 (Catchin’ Some Rays)…
For level 4, wine label 4 (Crashing Waves)…
For level 5, we’d cycle back to the beginning and use wine label 1 (Swamp Juice) as the background.
They also provided me with some icons to replace the ones I used in the initial version.
In the basic game, a “crunch” sound is played when the player matches three or more items, which fit with its cookie theme. Since Wine Crush is wine-themed, I replaced that sound effect with the “clink” of a wine glass.
At this point, the game still had a single level, so I simply changed the background graphic to wine label 1 (Swamp Juice), replaced the game icons with the ones that the client provided, and then sent them a new version to try out.
Now comes the hard part
Any changes that I’d made to the basic game engine were superficial or relatively simple, what with changing media and updating programming language syntax. From this point forward, many of the changes I would make would require reverse-engineering the code in order to determine how to add the gameplay features that I wanted to implement.
Before adding any features, I reviewed the existing code, added comments where appropriate, and took some quick notes on what each class did. Here’s a sample:
Click the image to see it at full size.
Adding gameplay features
I decided to add gameplay features starting with what I thought would be the hardest to implement, so I began with changing the game to support multiple levels. This was the first of many times where having done reverse-engineering before making any serious changes to the code paid off. Luckily for me, the game engine was written so that it would support multiple levels, but their implementation was left as an exercise for the reader.
The next task was to implement the hint button. Once again, my initial review and diagramming of the code’s structure made this relatively easy — game state is stored in the Level class, which represents the current state of the game board. It maintains an instance variable called possibleSwaps, which in turn is a set of instances of the Swap class, each of which represents a valid move.
Once I’d determined how to get the set of valid moves, it was a simple matter adding a new method, hint() to the Level class. It returns the first item in possibleSwaps if one existed, or nil if possibleSwaps was empty.
Now that I could identify a valid move, the next step was to find a way to show it to the user without affecting the game state. Once again, having done the initial reverse-engineering step paid off: it was clear to me that the GameScene class, which controlled the visual representation of the game state, was the best place to look. A quick review of GameScene’s methods revealed that it had a method for animating an attempt to make an invalid move: it swaps two game pieces, but then returns them back to their original positions. This animation was perfect for giving the user a hint.
I then had the minimum information required to wire up a hint button. Once I had the hint button working, I added a couple of additional related features:
A score penalty of 10 points for each use of the hint button
A boolean to track if the hint button has been used this turn (the score penalty should only count once per turn)
My initial reverse-engineering review also paid off for building a function that detects if the player has no valid moves. Once again, the place to look was the Level class, which has the swapsCount() method, which returns the number of valid moves available to the player. I harnessed this method to create a feature that tells the player that there are no valid moves available and if the player has enough moves remaining, tells the player to use the shuffle button to randomly refill the board.
Committing early, committing often
One of the key factors in my successfully finishing the project was consistent, constant use of version control, namely git. This was a particularly experimentation-heavy project, and there were many times where I would end up in a “blind alley” and need to revert back to a previous working version.
I decided to follow the same workflow that the GitHub team uses (see the diagram above), which is based on a set of simple maxims:
Anything in the master branch is deployable.
Working on anything new — adding a new feature, making a tweak, or even just refactoring — requires creating a new branch first, and working on that branch.
Commit to the branch regularly.
If the change can be confirmed as working properly, merge the branch into master.
Adding the other screens
Once I had all the gameplay features added, it was time to implement the other screens:
Title
Instructions
Aspirations Winery web site
Until this point, the app had only one screen: the game screen. When you launched the app, it went straight to the game. The next step was to restructure the app like so:
Click the image to see it at full size.
The game was self-contained, so making this change was relatively easy. I created a new view controller for the title screen, and made it the view controller that was presented upon app launch. I added a “play game” button to the title screen, and wired it so that pressing it loaded the game view controller. This change necessitated adding code to the game view controller that returns back to the title screen when the game ends or when the player presses the quit button.
The instructions button takes the player to the instructions screen, which is implemented as its own view controller. To simplify its implementation, most of it is taken up by a web view that displays an HTML page embedded within the app. The web view provides a lot of features that I wouldn’t have to implement — support for multiple fonts, static and animated graphics, scrolling — and makes it simple to edit the instructions.
The “visit Aspirations Winery’s site” button was the simplest to implement. It simply launches Safari and points it at aspirationswinery.com.
Fixing bugs and responding to feature requests
After I added the title screen, I noticed that the longer you played the game, the more it slowed down. That type of behavior usually indicates a memory leak, and after several runs of the app while monitoring its memory usage with the Activity Monitor, I confirmed that the app was leaking memory. It was a byproduct of bouncing back and forth between the title screen and the game screen; every time the player went from the title screen to the game screen, a new game screen object was created. After a handful of game plays, the device’s memory would fill up.
Once I found the cause of the slowdown, I changed way that the app switched between screens. I used some code that I remembered seeing in an iOS programming book that made use of a view controller that transitioned from screen to screen by explicitly loading the next screen into memory and unloading the previous screen.
A couple of testers tried listening to podcasts while testing Wine Crush, and found that it wasn’t possible. The app’s sound channels overrode any other app’s sounds, including those running in the background, such as podcasts. They asked me if I could allow other app’s sounds to be heard even when the game was playing.
It took a little research and testing, but within an hour, I found out how to support audio channels from other applications.
Shipping
Six weeks after the start of the project, all the features that I planned to add to the basic app were complete, and my small group of testers couldn’t find any more bugs. Immediately after my final commit to version control, I submitted Wine Crush to the App Store.
The submission process was mostly straightforward. The only complication arose from the fact that the app is all about wine and features wine imagery. I had to specify that the app prominently features alcohol, which meant that it would be age-restricted in some countries and completely unavailable in some others.
The app was approved in less than 48 hours, and on July 7, 2016, it became available in the App Store.
Over a span of ten years, I’ve promoted, demonstrated, documented, and assisted developers with various tools and platforms from a number of organizations: OpenCola, Tucows, Microsoft, Shopify, and Smartrac. In that time, I’ve developed a deep understanding of the specifics and subtleties of products geared towards developers…
They’re tools for hackers*, makers, tinkers, and experimenters
Let me start by clarifying what I mean when I use the term hacker. I’m not using it in its more popular colloquial form, which means “someone who gains unauthorized access to computer systems”. Instead, I’m using the classic meaning,as stated in the Jargon File:
A person who enjoys exploring the details of programmable systems and how to stretch their capabilities, as opposed to most users, who prefer to learn only the minimum necessary. RFC1392, the Internet Users’ Glossary, usefully amplifies this as: A person who delights in having an intimate understanding of the internal workings of a system, computers and computer networks in particular.
The last part so important that it bears repeating: A person who delights in having an intimate understanding of the internal workings of a system…
This is the key distinction between developers and other end users. Most end users simply want tools that “just work”. On the other hand, developers want tools that do more than “just work” — they want tools that they can dive into, explore, experiment with, and use to create new applications (and even new tools).
Products geared towards developers need to accommodate this mindset. Where most end users will skip the documentation and even a “quick start” guide, developer products need to have strong support and almost excessive documentation, which may include:
A “quick start” guide so that they can experience the rush of early wins — I call this “helping developers go from zero to awesome in 60 minutes”
Clear documentation with examples where applicable
Sample applications that they can run, reverse engineer, and modify
Examples of successful uses of the product
A healthy support system and community that they can turn to for assistance and inspiration
They are tools used in conjunction with other tools
The combination of Moore’s Law, nearly ubiquitous computing, and growing user expectations means that software is becoming increasingly complex. It’s very rare to see anything built using a single tool and using only a single API. These days, no software project is written in a vacuum, but by linking together disparate pieces using a wide selection of tools created by different organizations and developers and somehow get them to work as a cohesive whole.
Products geared towards developers need to support this heterogeneity and reduce the confusion that comes with it. APIs need to support de jure and de facto standards and be designed with the Principle of Least Astonishment in mind. APIs and tools need to be designed to communicate using standard, and if possible, human-readable, interfaces. Vendors need to keep abreast of the changing fashions and trends in software development and constantly update their offerings to match. Where possible, the developer product documentation should provide examples of interactions with other APIs and tools.
“The street finds its own uses for things.”
“The street finds its own uses for things” is a line used by Automatic Jack, the narrator of William Gibson’s seminal cyberpunk short story Burning Chrome. He was using it to refer to how people in the dystopian future world of the story used drugs for things other than their intended purposes, but it’s also an apt description for how developers use tools in unexpected ways more often than regular end users do.
A classic example of the street finding its own uses for things is XMLHttpRequest, which Microsoft originally developed for the sole purpose of making Outlook Web Access behave more like its desktop counterpart. Developers discovered that it could be used for making asynchronous requests in their web applications, and the Ajax revolution was born.
(For a supremely geeky variant of the street finding its own uses for things, you may want to look at a C programming trick called Duff’s Device, which speeds up time-critical loops by eschewing standard loops structures and making unorthodox use of a switch statement.)
Products geared towards developers need to take this tendency into account. This can be done by embracing a number of design philosophies including:
The Unix tool philosophy, in which you provide a set of tools, each of which does a single thing, and does it very, very well.
Postel’s Principle: Be flexible with the input that you accept, but be strict with the output that you produce (named after Jon Postel, this appears in one of his early specs for TCP).
The team player approach: Build developer products with the expectation that they will be used as a cog in a system or part of a collection of tools, and will need to interface with other tools, systems, and applications.
They are a means to an end
Products geared towards developers are meta-applications: applications that help them create applications. Application building is a time-consuming, brainpower-intensive, frustrating, complex, and confusing exercise, so products meant to be used in the process must:
Work reliably
Work predictably
Reduce cognitive load
Integrate with other systems
Be flexible enough to be used in cases that no one has considered yet
Scale
Most exciting
Here are the five things from [a list provided on the application form] (plus one or two items of my own) that excite me the most:
Own the developer platform strategy
Own technical context about how to develop apps on the [Company X] Platform
Talk to developers *and* listen to them, identify the 20% whose projects make the heaviest use of the [Company X] platform or are the most dependent on it, and bring observations, data, and feedback to the [Company X] product team
Learn a new skill to fill in a gap on your team
Do remote or in-person user testing for new developer features
Least exciting
Here are the five things from [a list provided on the application form] that excite me the least:
Set and communicate a project timeline with your team (but hey, it’s gotta be done)
Manage your team’s tasks on a weekly basis (again, gotta be done)
Commit HTML or JS code directly to our main repo
Ship good looking CSS directly to our main repo
Do support at [Company X]
And finally…
Congratulations on making it this far. I’d like to close with this video by New Relic, who make a software performance monitoring system. It features some of the software world’s brightest lights: Matz, Guido, Linus, DHH, Bill Joy, James Gosling, Sir Tim, Marc, Woz, Rasmus, The Gu, Sergey, Dries and finally Zuck. But guess whose picture they close with at the 1:04 mark!
I have no relationship with New Relic — they somehow found that picture of me online and thought it captured the kind of developer that they wanted to feature.
Last Saturday in Tampa was sunny, cloudless, and warm, and still I chose to spend half the morning and half the afternoon indoors to participate in GM’s Makers Hustle Harder hackathon at Tampa Hackerspace. And it was worth it — I got to meet new people, hang out with friends, work on some interesting tech, and even won a prize!
Using the NGI SDK, developers can write apps for the in-car infotainment consoles located in many GM vehicle center dashboards, like the one pictured above. The SDK gives you access to:
An 800-pixel high by 390-pixel wide touchscreen to receive input from and display information to the user
The voice system to respond to user commands and provide spoken responses to the user
Data from nearly 400 sensors ranging from the state of controls (buttons and the big dial) to instrumentation (such as speed, trip odometer, orientation) to car status information (Are there passengers in the car? Are the windows open or closed?) and more.
The navigation system to get and set navigation directions
The media system to play or stream audio files
The file system to create, edit, and delete files on the system
An inter-app communication system so that apps can send messages to each other
The SDK allows you to build and test apps for GM cars on your own computer. It comes with an emulator that lets you see your apps as they would appear on the car’s display, simulate sensor readings, and debug your app with a specialized console.
Crown, a local auto dealer, provided 3 NGI-equipped GM vehicles: 2 Buick Lacrosse sedans (pictured above), and a GM Sierra truck:
The NGI team were there to answer our questions and help us install our apps onto the in-car console to give them some non-emulator, on-the-real-thing testing. I gave one of my apps, Shotgun, a “smoke test” early in the morning on the Sierra’s console…
…and I have to say that there’s nothing like the feeling when your code runs for the first time on a completely new-to-you platform. I also ran a smoke test for WeatherEye, an app written by my teammate Chris Woodard (whom I know from his Meetup group, Tampa Bay Cocoaheads), and it worked as well.
Tampa Hackerspace was a hive of coding activity, what with teams working on all sorts of projects. With about three hours remaining in the allotted hacking time, I came up with an idea for an app: a referee for the car game classically known as “Chinese Fire Drill”. Here’s how it works:
Four people get in the car, close the doors, and someone starts the app. They’ll see this screen:
When everyone’s ready, someone in the front presses the start button.
If any of the doors are open when the start button is pressed, the players will be told to close all the doors first:
If all the doors are closed when the start button is pressed, the game begins. The screen looks like this:
Players exit the car, run around it once, return to their original seat, and close their doors.
The game ends when all four doors are closed, at which point the time it took them to complete the drill is displayed:
Yeah, the app’s not pretty, but that’s not what hackathons are about — they’re about working code in the time allotted. If you’d like to see the code, I’ve put it in a repo on my GitHub account.
Everyone who built a project presented it at the end of the day to the panel of judges, and the organizers saved Fitness Fire Drill for the very end — it got a lot of laughs.
My wife Anitra was flying out early the following morning on business, so rather than stay for the hackathon dinner and judges’ results, I high-tailed it home to have dinner with her. Before going to bed, I noticed that Chris had sent me an email telling me that I’d won the “Judges’ Fetish” prize for Fitness Fire Drill, which was a pleasant surprise.
My thanks to GM and Tampa Hackerspace for making this event happen!