Allen Pike 2015-10-01T00:30:46-07:00 Allen Pike Working Title 2015-09-30T18:00:00-07:00 Allen Pike <p>We recently interviewed a developer who was a new grad, brimming with enthusiasm. They answered our interview questions deftly, did well on our coding test, and presented a side project app that was sophisticated for somebody only six months out of university. Even better, their primary language was <a href="">Swift</a>.</p> <p>They had been writing Swift 70 hours a week, and were working methodically to develop their skills at an accelerated rate. Their goal, which they hoped to pursue by learning from our team at Steamclock, was to become a “senior developer” in 1.5 years.</p> <p>Now, I love enthusiasm and a can-do attitude. In fact, for junior developers, it’s one of the things I value most. That said, idea of a new grad toiling 70 hours a week trying to soon be deemed Senior Developer ruffled my feathers. To start, constant overtime <a href="">is unsustainable and counterproductive</a>. More than anything though, the mere thought of a new grad expecting to be a “senior developer” in less than two years got me agitated, even though I couldn’t articulate why. Even though I use the term “senior developer” when talking about growth or putting together a team, I realized that I didn’t have a working definition of what it means.</p> <p><img style='max-width: 100%' src="/images/2015/business-card.jpg" /></p> <h2 id="untitled">Untitled</h2> <p>We’ve never really had titles at Steamclock. I’m a co-founder, and Nigel is a co-founder. For the most part I run the business, but I’m not Chief Business Runner or chief anything else. Any attempt to coin a Chief Something Officer title for myself never really captured what I do, and felt overwrought for a ten-person team. I’m not a chief, I just run the place.</p> <p>Beyond the founders, we employ developers, designers, and somebody who helps us manage our office. Like most independent software shops, we prefer flexibility over formality. Job titles, especially when assigned to individual contributors like developers, are a formality - harbingers of politics and bureaucracy. Rands even goes as far as to <a href="">declare them toxic</a>:</p> <blockquote> <p>The main problem with systems of titles is that people are erratic, chaotic messes who learn at different paces and in different ways. They can be good at or terrible at completely different things, even while doing more or less the same job. A title has no business attempting to capture the seemingly infinite ways by which individuals evolve. They are imprecise frameworks used to measure the masses. To allow leadership to bucket individuals into convenient chunks so they can award compensation and measure seniority while also serving as labels that are somehow expected to give us an idea about expected ability. This is an impossibly tall order and at the root of title toxicity.</p> </blockquote> <p>Rands is right, as he often is. Attempting to quantify a developer’s skill or value or experience is at best imprecise, and at worst gross. In a perfect world, we could just put that aside, pay every employee the same, and avoid the process of labelling some people senior and other interns. These aren’t <a href="">spherical developers in a vaccuum</a>, they’re people. Unfortunately, without titles you can end up with a different kind of vacuum.</p> <h2 id="the-art-of-the-title">The Art of the Title</h2> <p>Titles help people outside your organization orient themselves to who they’re talking to. Avoiding titles or, alternatively, letting people choose meaningless titles makes it harder for new hires or clients to grok your organization. We’ve worked with large companies that lack formal titles, and determining whether the Chief Pixel Assassin or Senior Code Snorfler has the final say on a key product decision can be a… challenge.</p> <p>A lack of formal designations in a larger organization can also make it harder for certain people to communicate authority. For example, people from underrepresented groups in senior roles can have an even harder time communicating their authority if they don’t have a title to back it up. You can dislike titles all you want, but if the strongest developer at your company is a black woman, equipping her with business cards that actually say “Principal Software Developer” is going to be a net win. Of course, that’s only helpful if your institutional biases don’t prevent her from attaining that title in the first place.</p> <p>Besides their value in communication, titles’ most important role is to help reason about growth. Talented people want to grow their skills and responsibilities, and need recognition and compensation for that growth. Doing that in a totally ad-hoc way without any kind of labels gets hard as a company grows.</p> <p>Even at our size, where we’re small enough to do without titles, we need some way to discuss professional development and paying people fairly. We need to make sure bright developers with a lot of potential see a path to becoming seasoned developers with a lot of skill. We also need to talk about compensation, and understand what it means when some competitor is paying “senior developers” a “shitload of money” to “move to San Francisco and live in a closet in the Tenderloin”.</p> <h2 id="the-title-sequence">The title sequence</h2> <p>With that in mind, I attempted to hash out for our Enthusiastic Applicant what we mean at Steamclock when we discuss terms like intern, junior, and senior, even if we don’t have those terms on any business cards.</p> <p><strong>Intern</strong>: Does not actively sabotage app development. Is learning the language and tools, probably has some education but hasn’t held a full-time development job. Isn’t experienced enough yet to evaluate further.</p> <p><strong>Junior</strong>: Has shipped at least one app, and are generally productive. Junior developers still typically need oversight, might not be comfortable yet with gnarly tasks like choosing open soure components or code signing, and are still primarily evaluated on enthusiasm, attitude, and growth. <em>Typical experience: 0-3+ years.</em></p> <p><strong>Intermediate</strong>: Has the experience and wisdom to lead technical direction on a small project, coach and review other developers’ code, and prioritizes well. Has become comfortable with the technical tradeoffs that present themselves day by day, and actively works to better understand these tradeoffs and design patterns. Intermediates can work directly with non-developers and know when to escalate issues, technical or project-wise. Intermediates have developed the skills for discussing project issues productively with the team, and have refined key communication skills around software development. Technology wise, they have knowledge of the various tools and frameworks that relate to their work, and have gotten relatively fast at picking up new ones. When they encounter technical problems, they are usually hard problems like caching or naming things. <em>Typical experience: 2-6+ years.</em></p> <p><strong>Senior</strong>: Has the wisdom, intuition, and humility of a battle-worn developer. Can accurately estimate tasks and projects, primarily by drawing on experience. Has led other developers and is good at motivating, teaching, prioritizing, and coordinating. Has overcome and can spot common bad instincts like “not invented here” and “second system”. Has internalized the costs and general futility of overwork. Builds good relationships with other employees and clients using a honed sense of organizational and personal awareness. Thinks in terms of product and business success. Could probably have their own company, but knows they’re stronger as part of a team. Can systematically address technical problems that are mysterious and messy. Has developed specialties and technical expertise in specific areas that makes them unusually valuable on certain projects. Is active in the community and helps recruit and interview new talent. Is in control of their own motivational whims to the degree that their productivity isn’t limited to tasks they enjoy. <em>Typical experience: 5-15+ years.</em></p> <h2 id="title-card">Title Card</h2> <p>Having read my outlines of what career development might look like at Steamclock, our Enthusiastic Applicant was humbled yet motivated. They realized that becoming a senior member of a software team wasn’t just about having typed a lot of Swift and having read a lot of blog posts, but more about being tempered in the fire of mistakes and self-improvement. They still like the idea of getting to a “senior” level in a couple years, and while that seems exceedingly unlikely, why not let them try? Worst case scenario, we have a bright developer working on getting better at their craft for years to come.</p> <p>Well, worst case scenario is that they leave after six months to make a hojillion dollars burning themselves to a husk at Amazon. But it’s my job to be an optimist.</p> <p>Wait - Chief Optimism Officer? Nah, co-founder will have to do for now.</p> Moving Swiftly 2015-08-31T18:00:00-07:00 Allen Pike <p>Last year, Apple revealed Swift, the future of software development on their platforms. <a href="">Next Wednesday</a> they’re expected to officially release Swift 2 as part of Xcode 7 GM. In just a year, everything has changed. We went from writing our apps in an object-oriented flavour of C, to writing almost exclusively Swift. I’m personally writing more code than I have in years, in part because it’s just fun.</p> <p><img style='max-width: 100%' src="/images/2015/new-language.jpg" /></p> <p>Now, to be clear, writing Swift 1.0 was not fun. It was novel, it was at times exciting, but it was not fun. The compiler would crash, the syntax highlighter would crash, the IDE would crash. The running app would surprisingly not crash, but that was pretty much the only non-crashing thing in the vicinity of any Swift 1.0 developer’s desk. I think this caused a bit of bad blood, and a number of folks who tested the Swift waters early promptly returned to the Objective-C they knew and loved.</p> <p>While that was happening, Steamclock dug in. We started building internal tools with Swift last June. That October, we decided to start giving clients the option of going for Swift for new app builds. It seemed optimistic, but we were excited to level up our Swift experience and give new projects a leg up on the future. The results were blow-away: of roughly a dozen clients, only one opted for Objective-C. Swift became our default programming language almost overnight.</p> <p>Now, as the language is hitting its stride, we’re more productive, we’re seeing fewer issues in the field, and our clients are happy to be ahead of the curve. Almost as importantly, it’s fun - it sure makes recruiting easier when you’re hiring people to write <a href="">Stack Overflow’s “most loved” language</a>. (By the way, if you’re a Vancouver mobile developer who’d like to come write Swift at Steamclock, <a href="">we’re hiring</a>.)</p> <h2 id="trouble">Trouble</h2> <p>That’s not to say that the Swift transition didn’t cause some pain. For example, the explicit lack of source compatibility between versions is pants-on-head insane. At least, that’s what people say when they hear the term “no source compatibility between versions.”</p> <p>In practice it’s not quite so bad. Lack of source compatibility means that each time a new version of Swift is released, you need to block out an hour to a day to migrate your code to it, after which point it will no longer run on the old version of Swift. In the common case that you’re not distributing your code that’s not <em>so</em> bad, but when you start dealing with Swift-based CocoaPods, it gets messy.</p> <p>The bigger issue is that Swift versions are tied to Xcode versions, and Xcode versions are tied to iOS versions. So, if you want to debug your Swift app on an iOS 9 device, you need to use Xcode 7 beta, which only compiles Swift 2, which means you need to port your app to Swift 2 to debug it on iOS 9. Meanwhile, even this late in the game, you still can’t send betas to customers or reviewers from Xcode 7 beta, which means you can’t beta test Swift 2 apps, which means Testflight and Swift don’t go well together.</p> <p>It’s clear they’re going to improve this little mess, though it’s unclear exactly when or how. Either Swift needs to start locking down some source compatibility, or Xcode and Swift need to be more decoupled. Either way, Testflight definitely needs to support external beta testing with beta versions of Xcode, because srsly.</p> <p>All that said, we’ve successfully worked around it, mostly by relying less on Testflight and by avoiding the Xcode betas for projects that might need to be distributed to the App Store any time soon. It’s not ideal, but this dance been a worthwhile tradeoff for the benefits Swift gives us. It seems like the language is in a good enough place that future versions should require substantially less thrash, but are we out of the woods yet? It’s a bit hard to tell.</p> <h2 id="salt-in-the-wound">Salt in the wound</h2> <p>With Swift 2, the other issue I still regularly hit is quirky error reporting. Errors matter a lot in statically compiled languages, which ask a lot more of developers than a loose language does in terms of just getting the damn thing to run. Swift is more heavy-handed this way than Objective-C, due to its stricter mutability and optionality rules.</p> <p>As such, writing Swift code that doesn’t compile is easy, especially when you’re learning. Luckily, a great compiler can have a nuanced enough understanding of your code to point out issues clearly and rapidly. Swift was designed to enable exactly this, via great autocompletion and expressive error messages. </p> <p>Unfortunately, while the infrastructure for developing good errors was in place early on, initial versions of Swift tended to produce very misleading errors, even from simple typos. Even with 2.0, Xcode will give you the occasional self-referential error that really makes you wonder what exact strain of hallucinogen it has recently consumed.</p> <p><a href=""><img style='max-width: 100%' src="/images/2015/cgfloat.png" /></a></p> <p>Luckily, the errors are getting a lot better, and seem to be rightly recognized as a priority to the Xcode team. In many cases, Swift now gives better errors than were possible in Objective-C. For example, this code can’t compile because Swift won’t coerce Int to a String:</p> <pre><code>let number: Int = 1 let text: String = (number &lt; 0) ? "" : number </code></pre> <p>For that code, in Swift 1.2 the error you would get was:</p> <p><strong>Could not find an overload for &lt; that accepts the supplied arguments</strong></p> <p>Which is wacky, since “&lt;” has nothing to do with the problem. I filed a Radar, and in Swift 2 the error is now much better:</p> <p><strong>Result values in ‘?:’ expression have mismatching types ‘String’ and ‘Int’</strong></p> <p>Which is exactly the problem and immediately clear. With that positive reinforcement, I and many others keep filing <a href="">silly error Radars</a>. The error messages keep getting better, and my affection for Swift grows.</p> <p>In this way, the march of progress has been both steady and relentless. Swift 1.1 brought improvements to the Cocoa APIs to make them more Swift-friendly, tweaked and improved the language, and made Xcode more reliable and performant. Swift 1.2 brought more of the same. Swift 2.0 brought yet more. A year later, the annoyances and remaining issues feel small compared to benefits we’re getting, and it just keeps getting better.</p> <h2 id="think-about-the-good-times">Think about the good times</h2> <p>Meanwhile, lot of smart people are still <a href="">holding off on using Swift</a>. I get the rationale – it was rough out of the gate, and learning a new language is a substantial undertaking. Swift is a bigger language than Objective-C or something like JavaScript, and it has a lot of depth. This is clear from the fact that other smart people are still <a href="">theorizing and dissecting</a> their experience of learning Swift, working to understand how best to use this new tool.</p> <p>Yet as much as it may seem like work, this investment will pay off quickly. Basic Swift is very easy to write, and learning something new never goes out of style.</p> <p>So I have a proposal to all you Objective-C developers out there. Next Wednesday, when the Xcode 7 GM delivers Swift 2 in its full shininess and, likely, <a href="">open source</a> goodness, jump in. Start something new. A side project, a game, a new view in your existing app - anything to get over the idea that you don’t know Swift. Something to get you addicted. Know that the fear of something big and new, the fear of losing what you know, the fear of “doing it wrong” at first, is natural. You’ve just gotta shake it off. Shake it off.</p> Can't Stop the Music 2015-07-31T18:00:00-07:00 Allen Pike <p>Five years ago, Steamclock launched our first app, <a href="">WeddingDJ</a>. The concept was simple: a foolproof music app that you can use to run a wedding. A simple interface lets you plan out your songs and playlists, and the playback screen keeps a fat finger from skipping halfway through “Here Comes the Bride”.</p> <p>The app was well received, but we immediately started getting requests for one specific feature above anything else: crossfading.</p> <p><img style='max-width: 100%' src="/images/2015/weddingdj-crop.jpg" /></p> <p>Crossfading is in some ways the feature that distinguishes a DJ app from a basic playback app, and it was an obvious feature missing from the default iPod app that’s still absent today. Adding crossfading was no small task, since it required leaving behind the padded room that is Apple’s high-level MediaPlayer API. While MediaPlayer is easy to use, it essentially just pokes at the system iPod playback mechanisms: play, pause, and skip.</p> <p>Adding crossfading meant getting serious and writing our own audio engine. Luckily, iOS provides a world-class set of APIs for this. The AV Foundation APIs open up a world of possibilities for how DJ apps can play your iTunes music, and for the truly serious, Core Audio gives extremely fine-grained control over audio playback.</p> <p>These advanced APIs allowed us to implement crossfading in WeddingDJ, and later Party Monster, our general-purpose queueing DJ app. As proud as we are of our little apps, their usage of the audio APIs pales in comparison to blockbuster DJ apps like <a href="">Djay</a> and innovative audio apps like <a href="">Capo</a>. With this rearchitecture, we joined a rich ecosystem of apps that can play back your iTunes library in creative ways.</p> <p>Unfortunately, there is one tiny little problem with playing back iTunes audio yourself: sometimes you can’t.</p> <h3 id="you-shall-not-pass">You shall not pass</h3> <p>When we launched the first version of WeddingDJ that used AV Foundation in 2011, we immediately started getting reports of certain songs “randomly” not playing. Within a day, we understood that our app could no longer play back old iTunes Store purchases that were encumbered with DRM. While this was kind of annoying, and we filed a Radar asking for an official solution, it was a short term hurdle. You see, the iTunes Store had already been selling DRM-free tracks for four years by that point, and folks were slowly replacing their legacy libraries with unencumbered AAC files. For the meantime, we patched our app to alert the user when it encountered unplayable songs, adding an explanation of the DRM issue and how to work around it.</p> <p>We planned to wait patiently for the issue of unplayable music to fade away, but Apple never stands still. Within months of our new audio engine debuting, Apple started to roll out new services that instilled iTunes with the boundless power of The Cloud™.</p> <p><img style='max-width: 100%' src="/images/2015/itunes-errors.jpg" width="400" /></p> <p>First, we got iTunes Match. This magical service would match your poorly ripped or questionably acquired songs with high quality, DRM-free tracks from the iTunes Store. What’s not to like about that? In addition, iTunes Match tracks would be available in the cloud until your device needed them.</p> <p>Unfortunately for anybody building a 3rd party DJ app on iOS, these magical cloud songs aren’t downloadable or streamable via AV Foundation or Core Audio. The best you can do is alert an iTunes Match subscriber that they should go download their songs in the Music app and, once they’ve finished, return to your app to play them.</p> <p>So, no DRMed songs, and no iTunes Match songs. We added to our disclaimers, made our error messages longer, and filed more Radars.</p> <p>iTunes’ next big step towards streaming was a quiet one. Even as close Apple watchers, we didn’t notice the change until I started getting mysterious support mail. It turns out that iOS 6 introduced a clever new feature where new device restores no longer download all the music you had on your old device. Instead, restored devices display purchased tracks as streamable from iTunes in the Cloud. Next thing you know, users who weren’t even iTunes Match subscribers were upgrading their devices, opening their DJ apps, and not being able to play anything at all.</p> <p>After another round of new error messages, disclaimers, and Radars, developers of DJ apps everywhere were concerned. We knew there were sharks in the water, but the path forward wasn’t clear. Should we keep trying to surf the wave of uncertainty churning the seas of our users’ iTunes libraries? Or, did we need to bail on our advanced playback features and just grab a beachside beverage, dump the sand from our shorts, and start considering new markets for us to torture with a surfing metaphor?</p> <p>This month, Apple answered that question. By prompting every user of the Music app with a free subscription, Apple Music has flooded folks’ iTunes libraries with music they haven’t purchased <em>and</em> offline versions of tracks that are protected by the second wave of DRM. This is bad.</p> <p>Now, the surge in songs we can’t download or stream is a pain, but the re-introduction DRM is a brick wall. Not only can we not play DRMed songs, but DJ apps can’t even detect their presence. An enterprising developer may find that the AVAsset API has a property <code>hasProtectedContent</code> that sounds like it would help. Unfortunately, to get an AVAsset you need an asset URL, and if you ask for the URL of a DRMed MPMediaItem, you just get <code>nil</code> – the same value you get if it’s an iTunes Match track. Or an iTunes in the Cloud track. Or an Apple Music track. Or a really bad cover of Billy Ray Cyrus’ Achy Breaky Heart and it is currently a Thursday.</p> <p><img style='max-width: 100%' src="/images/2015/cant-play.jpg" width="350" /></p> <p>As a result, our ability to communicate to the user why we can’t play their songs is pretty limited. </p> <p>At first we filed Radars and otherwise lobbied for improved playback through AV Foundation, but in the context of a subscription service, it’s not a problem Apple can fully solve. Apps might get support for downloading iTunes Match and purchased iTunes in the Cloud tracks one day, but letting 3rd parties decode DRMed Apple Music tracks in our sandboxes would almost certainly violate Apple’s agreements with the music labels. <a href="">DRM on purchased music</a> is ridiculous, but DRM on offline caches of songs that you have because of an active subscription service isn’t even controversial. In the modern world of streaming, it’s just a fact of life.</p> <h3 id="what-do">What do</h3> <p>So, like anybody else who sells a DJ app on iOS, my inbox is now filled with messages like this one I received yesterday:</p> <blockquote> <p>iPhone will not let Download songs on the app because of Apple music. Please help!!!!</p> </blockquote> <p>According to our latest stats, 17% of Party Monster users have been unable to play a song in their iTunes library, and 22% of WeddingDJ users have tried to cue a playlist that has so many unplayable tracks that we need to display a warning. While it’s a miracle that we’ve been able to maintain a 4 star rating through all of this, it’s not going to last if we stay the course.</p> <p>Given all of this, we have a couple options. We could double down and go pro, catering to serious DJs who can load DRM-free music into our sandbox. Pro DJs who use our apps often have a large licensed library of songs, and won’t rely on iTunes Match or Apple Music.</p> <p>Alternatively, we could steer towards the mass market, drop crossfading support, and regain full iTunes compatibility. We could also put in the work to add support for Spotify or other competing streaming services, and focus our apps less on playback features and more on having a great UI for queueing.</p> <p>We’re still evaluating our options, but I think we may end up trying both. First, we’d do an update to the apps that adds a crossfade-less compatibility mode using boring old MPMediaPlayer. Then, we’d add Spotify support. Finally, we would investigate more deeply a “Pro” version of the app that would add support for actually loading songs into our app bundle using a NAS or other means, and explore the more advanced features like beat matching and stripping silence that we’ve long wanted to do.</p> <p>We have another option, one that not long ago seemed ridiculous but might just make sense. We receive a lot of requests for Android versions of our apps. Historically the library and audio API situation on Android has been such a hellstew that it hasn’t made sense, but the issues with AV Foundation have made us realize that we’re willing to put up with a fair bit for the love of the music, and users appreciate it when we do. We also have a couple great Android devs on staff now, and Android 5.0’s new MediaBrowser API may bring it close enough to iOS parity that it’s worth a serious look. </p> <p>Either way, we need to keep up with the times. Apple Music may take off, or its <a href="">quirks</a> and <a href="">pitfalls</a> may prevent it from really getting traction. Regardless, we’ve seen the writing on the wall: we’ve built our apps on a data source that we don’t control, and it’s slowly being eroded out from under us.</p> <p>Given this struggle and the relatively modest sales volume of DJ apps in 2015, some folks have asked why we don’t just bail on music apps entirely. Perhaps from a cold business perspective, there’s an argument to be made, but here’s the rub: we love working on music apps, and they pay our rent. We’ve been in the indie software business for five years now, and we’ve learned to recognize when something’s right - and to put in the work to keep it going. Wish us luck.</p>