# Justin Williams > The personal landing page and portfolio for Justin Williams, a software developer in Denver Colorado. Public Ghost content for AI and LLM tooling. This file includes a bounded export of public pages first, then recent public posts. Append `.md` to any post or page URL to get the content in Markdown (for example, `/example-post.md`). ## Pages _No public content available._ ## Posts ### Removing Unremovable Files after Upgrading to macOS Catalina URL: https://www.justinw.me/blog/unremovable-files-macos-catalina/ Last updated: 2019-08-22T19:06:48.000Z Against the better judgement of my own common sense, I decided to update my iMac to the macOS Catalina beta recently. One of the major internal changes in going from Mojave to Catalina is the [transition to a read-only System volume](https://developer.apple.com/videos/play/wwdc2019/710/?ref=justinw.me). During this process, I ended up with a folder on my desktop of files that the upgrade was unable to handle. Most of these files seemed innocuous, and I just deleted them. There was one folder, however, that I couldn’t delete because the system claimed it wasn’t empty. Blowing it out via the Finder or the Terminal was a fruitless task. In the interest of saving you time if you run into this scenario, these are the steps I took to solve my issue. 1. Reboot your Mac into [Recovery Mode](https://support.apple.com/en-us/HT201314?ref=justinw.me). Authenticate your user account if required. 2. From the menu bar, open the Terminal application. 3. Disable [System Integrity Protection](https://support.apple.com/en-us/HT204899?ref=justinw.me) and reboot: `csrutil disable; reboot` . 4. Once your Mac reboots (and assuming it's still not in recovery mode), open the Terminal app. 5. You need to mount the new file system as read-write temporarily so we can blow the folder(s) away: `sudo mount -uw /`. This is temporary, and rebooting will revert back to the safer read-only variant. 6. Delete the files you want to purge via the `rm` command. You’ll probably need to use `sudo`. 7. As a last step, you need to re-enable System Integrity Protection. To do that, reboot back into Recovery mode. 8. From the Recovery Mode menu bar, open the Terminal application: `csrutil enable; reboot` Once the reboot completes, your Mac should be back to the expected state, just with a few less zombie folders. You can verify SIP is active by opening Terminal and executing the `csrutil status` command. ### The Joys of a Two Week Vacation URL: https://www.justinw.me/blog/two-week-vacations/ Last updated: 2018-01-08T11:59:59.000Z Today is my first day back at work after a wonderful two weeks unplugged from the normal day-to-day workings of a software developer. I don’t unplug entirely, but my iMac with Xcode and all the trimmings is mostly replaced with the iPad Pro 10.5 I am presently typing on. In my twenties I would rarely, if ever, take a day off. Holidays and weekends seemed to bleed into the previous and next days and there was always *something* that I wanted to be working on. There was a new release of [Elements](https://www.wired.com/2011/12/elements-app/?ref=justinw.me) with a feature I was worried a competitor would beat me to. Other times, it was that gnawing calculator in my head telling me that every hour I don’t work and bill clients is money I am leaving on the table. As I’ve settled into my thirties, however, I’ve learned to appreciate taking time to reset and just get away the work. I still haven’t taken a proper destination vacation or unplugged entirely to silently meditate, or whatever you do when you don’t use technology. What I do try to stick to, however, is taking two weeks off twice a year: once in the middle of summer and again at the end of the year between Christmas and New Years. My summer conveniently lines up with the summer shutdown at my current day job where nearly every single person in the company (sorry, devops) disappears for two weeks and takes their vacation at the same time[\[1\]](#fn1). The first time I took a two week break like this I was quickly bored and ready to get back to work. Having never taken even a week off before, two weeks seemed insane and unnecessary. As I’ve continued the habit though, I’ve realized that it’s actually the perfect amount of time to decompress, recharge, and maybe even learn new things without having to worry about making time before or after work. It’s also great at forcing you to truly separate from your work. With a long weekend, or even just a single week away, I’d spend the majority of the time just trying to unwind and transition out of ‘work mode’, which is sometimes challenging for someone as high-strung and invested as I can be sometimes. By adding the second week away, I am allowing myself a full week of true vacation where I’m in the rhythm of whatever I’m most interested in during that time. These last two weeks have been spent just reading books I’ve had saved up as well as catching a few different TV shows I’ve wanted to see. I may or may not have completely reorganized my kitchen too. My two week break over the summer was spent doing repairs around the house or building things in my shed such as a [new monitor stand](https://ugmonk.com/2017/02/23/my-diy-monitor-stand/?ref=justinw.me#premium). I rarely open Xcode, though that’s not a hard rule I have. I just find I don’t want to or feel the need to. Most importantly, I unplug entirely from work and make myself as unavailable as [Tom Hanks on a deserted island](https://youtu.be/YdHAJ5Ypw6A?ref=justinw.me). Admittedly I have a bit of privilege in being able to take this much extended time off regularly and it may not be possible for others with different life scenarios. One trade off for me is that since I am a for-hire contractor I don’t get paid for this time or any vacation days, so it does require a bit of budgeting and discipline[\[2\]](#fn2). Despite that, if you can figure out a way to pull the two week vacation at your job, I highly recommend giving it a shot. Now, I wonder if my app still compiles . . . --- 1. If I ever ran a company again, I would steal this idea and implement it. [↩︎](#fnref1) 2. Something I have never really been good at until early last year. That’s a story for another day. [↩︎](#fnref2) ### How I Made Twitter Tolerable, for Me URL: https://www.justinw.me/blog/make-twitter-less-terrible-again/ Last updated: 2018-01-04T16:33:01.000Z At some point in 2016 I opted out of most social media, especially Twitter. I don’t remember the exact day or what the final straw was that brought me to that point, but my response was to delete nearly a decade's worth of tweets, unfollow every account and just stop participating. There was no major discovery from breaking away from social media. I didn’t find enlightenment, start drinking more water, or become a better person. I just stopped feeling bad about whatever micro-outrage would make its way through my network on a given day, only to be forgotten about as soon as the next day’s outrage arrived. I stopped arguing about stuff it turns out I didn’t care nearly that much about to have a firmly held opinion on. Developers are miserable people. We complain *a lot*. Being connected to tens of thousands of them throughout your day is probably not the best idea if you’re someone like me who isn’t great at letting stuff go easily. So I opted out. This is the point where I confess that while I “quit” Twitter, I didn’t actually “quit Twitter.” While you may have seen the mass destruction of the [@justin](https://twitter.com/justin?ref=justinw.me) account as me signaling my desire to cameo in a [Logan Paul video](https://www.vanityfair.com/style/2018/01/logan-paul-youtube-apology?mbid=social%5Ftwitter&ref=justinw.me), I was actually still using the service, albeit in a much more pleasant way. ### Private Twitter Private Twitter is the account I use to follow close friends, see sports GIFs, and get my news from [College Football Twitter](https://twitter.com/edsbs?ref=justinw.me). More importantly, it’s a private account that only 80 of my closest friends have access too. These are the folks who I would be happy to see if I randomly ran into them at a bar or restaurant. It doesn’t include colleagues, casual acquaintances, or any random person who thinks I might be an interesting follow because I sit and stare at Xcode all day for the day job. By limiting the follower list with such a heavy hand, I’m able to more freely share things that are boring, mundane, or only potentially of interest to me. I have no one to impress, no stats to juke, and no need to worry about being retweeted in to a viral hellscape of “Well, actually.” My friends who follow me on Twitter may not be super interested in seeing that I reorganized my kitchen cabinets or took apart and washed my keyboard, but that’s the type of mundane and boring stuff you talk about with friends. Private Twitter is also not about reciprocating follows or worrying about the social awkwardness that can be caused by not following back. Some of my [closest friends](https://www.caseyliss.com/?ref=justinw.me) follow me on Private Twitter, but I don’t follow back because they talk about technology and whatever “iOS Community” drama there is on a daily basis. I have active iMessage threads with these friends daily, and that acts as a filter of sorts to bubble up the actual news I need to worry about. Personally, I just do not care to see or hear about whatever is going on in the tech sector anymore, because it’s mostly noise and very little signal. If I want to dip my toes in for whatever reason, I search for a few friends’ accounts and read their timeline for the last day or two. I usually regret it because I get a headache from eye rolling, but it was my choice to make. ### Is Private Twitter for Me? The only reason I am writing this is because a week doesn’t go by without me talking to someone that hasn’t quit Twitter or is on the verge of quitting because the negatives far outweigh the positives anymore. My advice to them is usually always the same: 1. Create a new Twitter account and set it as [private by default](https://help.twitter.com/en/safety-and-security/how-to-make-twitter-private-and-public?ref=justinw.me). 2. Follow a few accounts related to things you truly like. In my case that was college football, the greatest sport of all. 3. Follow a few accounts related to your city, if relevant. I follow [CDOT](https://twitter.com/ColoradoDOT?ref=justinw.me), [RTD](https://twitter.com/ridertd?ref=justinw.me), and the [Mayor of Denver](https://twitter.com/MayorHancock?ref=justinw.me) so I can know if there are traffic accidents I need to know about or something interesting is happening in Denver. 4. Follow your family, unless they annoy you. Follow a few close friends. 5. Throw your old account into the sea. My Twitter solution is definitely not for everyone, but it has worked well for me for almost two years now. I still take Twitter breaks periodically, but it’s rarely because I’m annoyed at what I’m reading or seeing anymore. ### Back On Public Twitter In January of this year I started tweeting again from [@justin](https://twitter.com/justin?ref=justinw.me). I set a few ground rules. First, I try to only post positive things rather than just using it as an outlet to complain. I *try* to stick to this 100% of the time, but I’m sadly not perfect. My second rule was to not follow anyone on the account. When I use my public twitter account I think about it as throwing a note over a wall and then walking away. I’ll check the replies and interact occasionally, but that is an exception, not a norm. People have described Twitter and social media in general as an avenue for people to shout their opinions out into the open while other people are shouting theirs. I now fully embrace that with my public account. You’re welcome to follow my public shouting if you’d like. Private Twitter, though? That’s for me and my friends. ### My 2017 Home Screen URL: https://www.justinw.me/blog/homescreen-2017/ Last updated: 2018-01-01T19:05:59.000Z [![My Home Screen - 2017 Edition](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2018/01/homescreen_iphone_2017_small.png)](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/12/homescreen%5Fiphone%5F2017.png?ref=justinw.me) As a matter of archiving and historical significance that is potentially only useful to me, I’m opting to share the current home screen of my iPhone on this, the first day of 2018. ### Embracing Defaults As the iPhone and iOS has matured over the last decade, the amount of third-party apps I have used for system-provided services seems to have dwindled. I no longer use a third-party email client because Mail is good enough for my needs. Apple Music allowed me to ditch Spotify. The Calendar app isn’t nearly as good as Sunrise used to be, but it’s good enough that I don’t want to be bothered using a third-party solution anymore. Probably the most controversial will be my use of the Apple Podcasts app over something else. The Podcasts app isn’t nearly as full-featured as my old stalwart [PocketCasts](https://www.shiftyjelly.com/pocketcasts/?ref=justinw.me "PocketCasts"), but I was willing to trade silence trimming for easily being able to tap on a share link and have it open where most podcasts expect: Apple Podcasts. ### Reading One constant is that I read *a lot* on my phone. Apple News has become a mainstay for me as a way to check in on the news of the day (both real and fake!), while also mixing in some of the entertainment and music news I am interested in as well. The [New York Times](https://www.nytimes.com/?ref=justinw.me) is my go-to in the morning for their morning briefing and for periodic push notifications throughout the day so I know when we have been nuked. I recently received a subscription to [The New Yorker](https://newyorker.com/?ref=justinw.me) and have found their app to be incredibly well done and now my preferred way to read their content. I still check the [Medium](https://www.medium.com/?ref=justinw.me) app daily as well, because there are a few pearls in their sea of masturbatory posts. I do enjoy their new audio posts feature for members, which is a nice addition for longer reads that I have been meaning to read for a while, but never actually sat down to enjoy. One change I made in the last year is that I stopped using [Pocket](https://getpocket.com/?ref=justinw.me), which was probably my most used app of the last five years. There wasn’t necessarily anything wrong with Pocket, but I found that I would just throw articles in there and never get around to reading them. Queue Guilt is a real thing. My new system is to either read the article at the time I find it, or open it in a background tab if I know I want to read it in the evening. Each morning, I close out those tabs, even if they are unread. ### Writing One of my goals for my 35th year is to get back into the habit of writing more, so I’ve put both [Ulysses](https://ulyssesapp.com/?ref=justinw.me) and [Day One](http://dayoneapp.com/?ref=justinw.me) on my home screen to try and facilitate that. Day One tracks my journaling, private moments (think Instagram posts , but without sharing and growth hacks), and my monthly and annual goals. Ulysses is where I do the majority of my professional and hobby writing, such as this post you are reading right now. And yes, I use the official [Twitter](https://www.twitter.com/?ref=justinw.me) app for both reading and writing tweets instead of Tweetbot. It’s fine. Don’t @ me. ### Photography One break from my “defaults” rule has been switching my photography app of choice to [Halide](https://halide.cam/?ref=justinw.me). The ability to shoot manually or with Raw when it makes sense is a major win over the default iOS Camera app. If I need to shoot a video or panorama, the system’s camera app is easily accessible via Control Center. Halide is the first third-party camera app that seems to have eliminated the annoying delay from launch to being able to capture an image. When I’ve tried (or worked on!) camera apps in the past, I found that the delay would cause me to lose several ‘in the moment’ shots. Either Halide is doing some secret magic, or Apple has finally fixed `AVFoundation` to not have that delay when using a camera view. For sharing photos or seeing what is happening in the lives of my friends & family, I still use Instagram. Facebook hasn’t completely ruined it, yet. ### A Work-Free Zone A trend I started around the middle of 2017 and hope to continue into 2018 is keeping all work-related apps and services off of my personal phone and tablet: no work email, Slack, or Asana. The TestFlight build of the [TED](https://www.ted.com/?ref=justinw.me) app is the closest I get to work-related content. My reasoning for this was to try and create a better separation from work and my day-to-day life. I realized that the notifications and always-on nature of modern work caused my anxiety to increase in ways that I didn’t like. Now, I just check these services when I am sitting at my desk and actually working, versus making myself seem accessible 24/7\. If a true emergency does come up (the 1% of the time it is a true emergency), people can contact me via iMessage and I’ll install whatever app I need temporarily if I’m unable to get to my iMac. ### Into 2018 If I have to guess about how my phone habits will change in 2018, I am guessing they won’t much. I rarely download new apps anymore as I’ve found the ten or so that suit me. The bar to get people to switch apps is incredibly high at this point. Forced to pick though, I’d say Instagram and Twitter will be gone by 2018\. I constantly struggle with Twitter being both a toxic cesspool of hate and abuse, while also making me laugh daily. I don’t trust Facebook as far as I can throw them, so I won’t be surprised if they do something that makes me delete my Instagram account. Given that I use Day One more for “posting” what I used to share on Instagram, I don’t know if I’ll miss it. ### Updating Your APFS Encrypted Volume / FileVault Password URL: https://www.justinw.me/blog/updating-your-apfs-encrypted-volume-filevault-password/ Last updated: 2017-11-30T14:59:59.000Z For as long as I can remember, I have been running into an annoying issue with my iMac where I’d have to authenticate twice upon restart: once with my old account password to unlock FileVault, followed by my new account password to actually get into my account. I finally took the time to figure out how to fix this the other day. I couldn’t find a succinct example on The Google, so here you go. Note that this is for an APFS volume on High Sierra (10.13). If you are using HFS+ or an older version of macOS still, the instructions may be a bit different. In Terminal run the following command: `sudo fdesetup list -extended` This will return a list of accounts that are associated with your Mac. The output should look something along the lines of below. ``` ESCROW UUID TYPE USER C20A4763-D4F8-4B3C-A889-0021B0735248 OS User justin 7DA69D0C-BA82-4575-AC68-CFE037778BA1 Unknown User 05E65DD7-AE83-4BD4-8B8B-AADA35A307E1 iCloud User ``` Copy the UUID for your specific user account as you will need it for the next command. Once again in Terminal, type the following command: `diskutil apfs changePassphrase disk1s1 -user [UUID]` Replace *UUID* with your UUID you copied from above, obviously. You’ll be asked to enter your old passphrase, followed by the new one. After that, you should be able to sign into your Mac and unlock FileVault using the same password, once more. ### A Note on carpeaqua RSS URL: https://www.justinw.me/blog/a-note-on-carpeaqua-rss/ Last updated: 2017-11-30T00:45:00.000Z In an attempt to try and simplify this website's setup I have consolidated the RSS setup down to a single feed, managed internally by [Ghost](https://ghost.org/?ref=justinw.me). This will likely result in me losing quite a few legacy subscribers from the early 2000s when this site launched. So be it. If you are still interested in keeping up with my occassional writing, please update your RSS client to point to [https://carpeaqua.com/rss/](feed://carpeaqua.com/rss/). If you have moved past the early 2000's and left RSS in the past, there is also a Twitter account at [@carpeaqua](https://twitter.com/carpeaqua?ref=justinw.me) that posts when there is new content published to this site. There is still no newsletter. I am the worst at growth hacking. Thanks for reading. Is anyone reading this? ### I Got Hacked and All I Got Was This New SIM Card URL: https://www.justinw.me/blog/hack-the-planet/ Last updated: 2017-07-07T17:21:49.000Z I like to think I take an above average amount of steps to secure myself online: I use a password manager, unique passwords as complex as the site will allow, and turn on 2-factor authentication when possible. A true security expert will likely find some sort of flaw in my setup, but I'll argue that I am doing more than 95% of the planet. So how did I, someone who is reasonably secure, have his cell phone disabled, his PayPal account compromised, and a few hundred dollars withdrawn from his bank account? ### You Can't Secure Against Human Error Yesterday evening, I was driving to the airport to drop off someone and noticed my phone had zero bars on AT&T: the "No Service" text was listed where the bars should be. I assumed it was because Denver's airport is in the middle of nowhere and a tower died. Or the iOS 11 beta is buggy and somehow it’s just a byproduct of that. I restarted the phone. No help. Reset network settings in iOS Settings. Still no success. I checked my iPad because I carry it with me and keep a SIM in it. The iPad still has service, which seemed interesting. At this point I was still blaming iOS 11 because I'm a software developer and we always blame the software. Once I returned home I checked my email and saw two new emails. The first is from Google with a security reset code. I did a quick phishing check and the URLs were legitimate. The second email I see was from PayPal stating that $200 AUD was transferred from my bank (which is an obscure / small bank) to another person. Again, checked for phishing just on the off chance that someone figured out who my bank was to craft an elaborate password fetching scheme. It's valid. Finally, it clicked: someone has taken over my cell phone. I instantly called AT&T's customer service line to explain what is happening. I give them my name, my phone number, and my security passcode (this is key). The man on the phone reads through the notes and explains that yes, someone has been dialing the AT&T call center all day trying to get into my phone but was repeatedly rejected because they didn't know my passcode, until someone broke protocol and didn't require the passcode. Once the intruder found someone who didn't require my AT&T security passcode the intruder had the AT&T call center rep switch my number from my iPhone's SIM card / IMEI to his/her burner phone (I don't fully understand GSM technology, so I may have this technically wrong, but you get the gist). I had the call center rep I was speaking with (who was great) suspend service on my phone, deactivate the "new" SIM that was created an hour earlier and make a bunch of notes on my account so it would be easier for me to go to the AT&T store this morning to get a new SIM. My next point of contact was to my bank to inform them of what happened. They were sympathetic but there wasn't much they could do beyond giving me new account numbers and canceling my debit card (for extra paranoia). I no longer have access to my bank account until this is resolved, so look forward to my Patreon in the next few days when I need to go to the grocery. Next I called PayPal to dispute the $200 AUD charge. I had assumed I'd talk to a live human, but no. It was all automated. I disputed the charges and got an email saying they'll let me know if I can have my money back in 9 business days. I'm not optimistic because PayPal is terrible. You're likely wondering how my cell phone being compromised leads to my PayPal account being compromised? All you need to reset a PayPal password is an email address and a phone number to accept the verification code. Since PayPal only supports SMS-based authentication, all the perpetrator needed was to be able to receive SMS messages as "me" and he was in. ### Lessons Learned? I have spent the morning trying to evaluate my security practices and there's not much I can think about that I'd do otherwise. Twitter tells me I shouldn't use SMS-based 2 factor authentication and should use app-based 2 factor instead. I agree! The problem is that some sites like PayPal don't offer the better security. The alternative is to just go back to single factor, which I am not so sure is the best solution either. I don't even place blame on PayPal for this directly. The fault lies with the AT&T call center representative who let someone manipulate my account without knowing my passcode. I've been told this is being escalated internally, but I haven't heard anything from corporate channels, so I remain skeptical until I see or hear something. Until then, I'll be going back to watching my bank account, ensuring my credit cards are valid, and wearing this tinfoil hat I crafted this morning. For all the advances that we have made in technology over the last decade, online security still has a ways to go. ### Swift's Evolution URL: https://www.justinw.me/blog/swifts-evolution/ Last updated: 2017-06-02T17:27:05.000Z I'm usually pretty good at inferring where Apple is going with their projects and products. With Swift, I'm left shrugging. Hopefully the purpose of Swift and how it relates to Apple becomes less muddy next week. Since 2004 (!) I have been attending WWDC on a regular basis. My first time was on a student scholarship thanks to some incredibly poorly written Objective-C code back in the Mac OS X Panther days. Fast-forward to 2017 and we've gone from Apple the underdog computing platform to Apple the juggernaut that has four top-tier platforms. After you've attended a handful of WWDC's, you start to realize the pattern. Unlike a conference like TED which explicitly puts the theme of the event on the cover, WWDC is a bit more subtle. If you attend enough sessions you start to realize both what Apple is interested in this year, but also in this new iOS era, where they are skating towards in the fall. ### Skating to Where the Puck Is Going When Apple introduced Auto Layout with iOS 7, they started pushing the idea of having both iPhone and iPad apps being built from the same core interface elements with minimal additional effort by the user. It was also a pretty good hint that Apple had their eye on a larger iPhone, someday. When size classes were introduced with iOS 8, they were literally beating you over the head saying larger phones were coming. Size classes were an important announcement in 2014 with iOS 8, but the biggest announcement was by far the introduction of the Swift programming language. Though not marketed as an absolute successor to Objective-C, most have taken the introduction of Swift as a pretty good indication of where Apple wants to take software development for their platforms for the next decade or more. With Swift, Apple gave themselves a clean slate to build a modern language for mobile development, without the legacy of a programming language that was designed for NeXT Cubes in the 80's. Swift checked many of the boxes that new and old Apple developers had been clamoring for by offering things like static typing, optional types, and not having to think about pointers for the majority of mainline use cases. Swift also infused a lot of new ideas into development on Apple's platforms. Subclassing began to be seen as a last resort when protocol-oriented programming and value types couldn't be used. A traditional `for` loop was passé. Instead, `map`, `flatMap`, and `forEach` were how you flexed your Swift muscles. ### Living on the Edge The first version of Swift was, dare we say, *challenging* and I avoided using it in production. With the release of Swift 2.0, the water seemed cool enough that the first bits of Swift code landed in production at the day job. In fact, most of the new code being written at that point was in Swift rather than Objective-C. The tooling still suffered from a lack of reliability and stability, but I kept reminding myself that I was using a new, rapidly iterating language and that just comes with the territory. Swift 3 was the first release after the open sourcing of the language, and honestly where I think my love affair began to wane. After being open sourced, Swift started to feel like a language that stopped actually moving forward in ways that made sense to me. Removing traditional `for` loops and increment/decrement (`++/--`) operators were pushed through the Swift proposal process as improvements the core language by the fact that there were "better" ways to replace their functionality. From a theoretical perspective, that makes a lot of sense. Practically, I was left wondering why it was worth the effort when there are still real problems needing to be solved. The biggest travesty was the "Great Renaming" which touched every line of Swift code I had and burned a week of my life on tedium. In my decade of professional development, I have never had a worse experience. The migration tool caused more issues than it automatically resolved, leaving a manual migration as the only sane path forward. How that migration tool ever made it through QA is beyond me, but I'd have felt better if Apple just said "good luck" instead of offering a half-baked utility. One can argue that renaming every method API method to be more "swifty" was worth the headache. I even agree to a point, but I also don't believe Swift 3 dramatically improved my experience as a software developer, especially when compared to the effort to get there. In fact, most of the decisions made since Swift was open sourced have left me scratching my head as someone just wanting to use the language to write iOS apps. ### Practicality vs. Ideology I'm a practical iOS developer by day. I try to use a value type where it makes sense, but I also still design my table views the old fashioned way with delegates and data sources. I still use Core Data for persistence. And I still use KVO where it makes sense. From the outside, it seems like important milestones like ABI stability continue to be delayed as Apple and its open source contributors continue to chase the dream of designing the most pure language they can. Removing "legacy" operators and arguing over access levels seems to have taken priority over actually moving Swift forward as a first class language for Apple development. The problem with that is that software development isn't pure. It's messy. I've never written a perfect line of code in my life. I don't plan to either. Fixing a language in post is obviously harder than pushing a new build of an iOS app, but chasing perfection is a fools game no matter what the project is. As a production developer I need ABI stability because it prevents me from having to recompile my dependencies every time the language is upgraded. It will also hopefully allow me to shave 8 megabytes off my download by no longer including a Swift runtime in every release. My product managers need those 8mb for more analytics libraries! I'd rather Apple spent its time giving me a concurrency story along the lines of `async/await` instead of looking for new ways to make protocol extensions useful in scenarios that just don't make sense for my shipping products. And for god sake, improve compile times. I only have one life. I'd like to spend less of it watching a progress indicator. I realize that the tools team and the Swift team are separate, but its hard to separate the two when Swift's primary method of development is Xcode. Xcode's quality as a Swift development language has never been great with its constant indexing, opaque compile errors, not great typing auto-completion, and lack of refactoring support still. With zero insight into the inner workings of Apple, it still feels like the language hasn't been embraced nearly as heavily internally as it has been externally. If it was, I'd believe that Xcode's Swift-related issues would be resolved much quicker than they have been. The biggest pain points external developers face always seem to be resolved once they become issues internally at Apple. If Apple can't use Swift to build its frameworks or its internal products because ABI stability is missing, they don't see all the warts we do. Apple's path with Swift doesn't seem to solve the problems I have as a day-to-day iOS developer. Instead, the language design focuses on implementing functionality that would benefit server-side Swift, Playground demos, and showy conference talks. If that's the goal of the language, I sure wish they'd come out and say it. Right now it feels like I'd have been better served by continuing on with Objective-C, which is still being improved in meaningful ways, rather than going all-in on Swift. ### A Software Developer’s Mac Pro URL: https://www.justinw.me/blog/a-software-developers-mac-pro/ Last updated: 2017-04-09T21:37:15.000Z According to the [transcript](https://techcrunch.com/2017/04/06/transcript-phil-schiller-craig-federighi-and-john-ternus-on-the-state-of-apples-pro-macs/?ref=justinw.me) of the chat, Apple has a few different types of pro users it is considering: 1. Video editors 2. Music creators 3. Graphic designers 4. Scientists 5. Engineers and Architects 6. **Developers** Developers you say? > **Craig Federighi:** I think if you use Xcode downloads as a metric, it’s possible software developers are actually our largest pro audience. It’s growing very quickly, its been fantastic. Sounds like me. I download *a lot* of Xcode builds. I am important! I can’t speak to what the other five types of users need, but I have a pretty good idea of what I’d want as an iOS developer who uses a Mac every day. Not that anyone in Cupertino is asking me, but if they did I’d say this is my dream Mac. Let’s assume that Apple is going to ship this new [Mac Pro](https://daringfireball.net/2017/04/the%5Fmac%5Fpro%5Flives?ref=justinw.me) in 2018\. Yes, they are being coy with the semantics of when it will be available (“It won’t ship this year”), but just for this thought exercise, it’ll be on my desk around WWDC 2018. ### A Tower of Boredom Despite the fever dreams [podcasters](http://atp.fm/episodes/216?ref=justinw.me) are having about what Phil Schiller meant when he said the new Mac Pro would be “a modular system,” I have no aspirations or desires for a stackable, modular computer where I can add an external GPU or other parts I desire. All I need is a tower that connects to an external monitor. That’s it. Make it look like the [Cheese Grater](https://www.flickr.com/photos/carpeaqua/2930186696/in/photolist-2Bjby-8iGsX-5sVYqh-8iGjY-8iGNX-8iGEB-64grp-38UXm-21CeB-64gxw-jy5f-jAwj-8iH33-8gQiF-21Cdw-64gyo-64gwv-21CfC-837s8i-5hezDR-dFJND-64gvn-jyrt-21Ceg-21CgC-jkmy-jkHk-jkHV-21Cfm-jkHz-jkHr-jkGP-jkGV-jkHa?ref=justinw.me) if you want, or spend time designing something more modern and attractive. If I get a say in size, I’d like something along the size of the Power Mac G4\. The Cheese Grater design was nice, but it was also a chore to lug around the few times I needed to move or rearrange my desk. I think it’s safe to assume there’s no optical drive required in a 2018-era computer, so that should hopefully offer some space and weight savings. I don’t need a micro-ATX architecture. ATX is fine. Just maybe make it not weigh 40 pounds if you can. We are developers, not bodybuilders. ### CPU I know Intel has been having trouble of recent years and has taken to [tocking](https://en.wikipedia.org/wiki/Tick-Tock%5Fmodel?ref=justinw.me) more than it’s ticking, but I also don’t see AMD as a viable alternative for CPUs[\[1\]](#fn1). Ryzen is interesting, but I’d rather have Kabylake or Cannonlake Xeons. In terms of speed, the reality is that I haven’t been hamstrung by CPU performance in years. What I need more than faster CPUs is more cores. The trash can Mac Pro got this right. My iMac maxes out at 4-cores. I’m going to want at least 8 for a Mac Pro. Anything more than that seems overkill for me personally, but I can appreciate others might need 12 or more. What will I use 8 cores for? Parallelizing my compilation in hopes of speeding it up. Well, assuming [these Swift performance issues](https://www.linkedin.com/pulse/best-hardware-build-swift-what-you-might-think-jacek-suliga?ref=justinw.me) are resolved before you ship this thing. ### GPU I know you backed yourself into a thermal corner with the trash can. That’s in the past. All will be forgiven if you just default to using a boring old PCIe video card from Nvidia or AMD. The GTX 1080s are what I have my eyes on for upgrading my PC desktop to. I’d gladly take one in my Mac Pro too. I don’t need multiple GPUs personally. I’m just a software developer who doesn’t do any game work. I just want to ensure that I have the best GPU I can get when I buy this so that I can ensure that macOS performs as well as it can for a few years. No stuttering when I toggle Mission Control! And speaking of games, I don’t play them on my Mac. This dream of the Mac ever being a best-of-class gaming platform is long gone. Linux on the Desktop has a better chance of succeeding than I do of getting Overwatch on my Mac day-and-date as PCs and consoles. ### Storage I only use SSDs at this point, save for Time Machine. I need the fastest write speeds you can offer me. I’d like to have the ability to mirror my boot drive using RAID for redundancy, but I’ll survive if I can’t. What I do need though is room for more than a single drive. If you’re going to give me a modular system, I’m going to want to move my Time Machine backup internal and maybe even have separate drives for different virtual machines or operating systems. I’m not doing macOS development right now, but I remember the times of having to boot up an old version of the OS to test or debug a release. And if one of my drives does fail? I need to be able to replace it quickly, without sending it off to the Memphis repair hub. ### Memory I know you all love DDR3, but [DDR5](https://arstechnica.com/gadgets/2017/03/next-generation-ddr5-ram-will-double-the-speed-of-ddr4-in-2018/?ref=justinw.me) is a thing now. Please? Lots of it. I can get by with 16GB of RAM on my laptop and the world goes on. If I’m going to buy a new tower that I expect to last for several years, I’m going to need at least 64GB of RAM. I’d take more if possible though! I prefer to not think about paging by throwing money at the problem. What am I using all this RAM for? I don’t necessarily need it for building my app in Xcode, but when you add the virtual machines I run in Parallels for testing, Docker containers, and how the dozens of tabs I keep open at any given time it adds up. Slack also eats memory. I know you aren’t allowed to use it at Apple, but out here in the real world we do and it is a memory hog. ### Ethernet Adapters may be fine for not including Ethernet on a MacBook Pro, but I keep my desktops connected to Ethernet at all times. I need the fastest possible speeds afforded by my Internet connection for downloading and uploading things like Xcode releases, builds to TestFlight, and other bits and bytes I see fit. The current Mac Pro has two. I only use one, but I won’t lose sleep if you give me two. Please include WiFi for things like Handoff and Airdrop, but don’t take away my Ethernet port for my primary Internet connection. I rely on it on my iMac and I would rely on it for my next Mac Pro as well. ### Ports of Connection I think it’s safe to assume that a developer’s Mac Pro would have the following connections: - USB-C - Thunderbolt 3 I’d *like* to have a USB-A port or two to connect my wired, clicky keyboard, but I can understand if you don’t want to include them. I’ll add an adapter and never think about it again. For the ports you do include, I need lots of them. I tend to keep an iPhone, iPad, and Apple Watch connected to my desktop at all times for deploying to via Xcode. I’d hope that without the space constraints of a laptop, every port has the same sort of bus speed. I don’t want to have to think about the upper-left USB-C port being faster than the lower-right one. ### Expansion Modern Apple is defined by how locked down the system has become. That’s fine for an iMac or MacBook Pro, but I need the ability to swap out a few non-core parts in the future. - Upgrading to a bigger / faster SSD as technology improves - Adding more RAM if I can’t afford to max it out at purchase. - Replacing / adding a new GPU card. If you don’t want to support them via AppleCare, that’s fine. That shouldn’t negate my ability to extend and improve my desktop tower, however. ### Everything else Apple computers are known for being quiet by default. I’m fine with the fans cranking when I’m processing a heavy load, but the default state should be minimal noise. I know there is a new Apple Pro Display coming, and I’ll likely buy it. Throw a few USB-C ports on the back of it so I don’t have to run long cables from the tower on the ground to my desk. Maybe test it [next to a WiFi router](http://www.macworld.com/article/3163446/macs/lgs-5k-monitor-doesnt-work-near-wi-fi-routers.html?ref=justinw.me) before shipping. I have been using an iMac for the last few years because it seemed like a better option for meeting my needs of wanting a Retina Display with good enough performance. This new Mac Pro has the potential to send me back to Apple’s most niche hardware class. In fact, I’m funneling money away for this new *Jesus Computer*. I haven’t been this excited about the future of the Mac since the last time Apple said [the Mac was back!](https://www.youtube.com/watch?v=klM4NmB%5FCTY&ref=justinw.me) --- 1. Yet. I’m keeping my eyes on you, Ryzen. [↩︎](#fnref1) ### Why Pro Matters URL: https://www.justinw.me/blog/why-pro-matters/ Last updated: 2017-04-07T01:32:07.000Z Sebastiaan de With pens what I consider to be the [best argument](https://medium.com/@sdw/why-pro-matters-75593220cb1ao?ref=justinw.me) for why Apple should care about a niche market of Pro Mac users: > Macs became the tool of choice of this new wave of designers, and as the web evolved Apple kept its OS and app ecosystem in sync with its trends; as online video became popular, Apple offered the easiest editing software in iMovie. Blogs and RSS had a peak; Macs came with iWeb that let you author blogs literally out of the box. These designers started to code, or came in contact with developers. I was there for this, with both G5 and Intel variations of the [cheese grater](https://www.flickr.com/photos/carpeaqua/2930186696/in/photolist-2Bjby-8iGsX-5sVYqh-8iGjY-8iGNX-8iGEB-64grp-38UXm-21CeB-64gxw-jy5f-jAwj-8iH33-8gQiF-21Cdw-64gyo-64gwv-21CfC-837s8i-5hezDR-dFJND-64gvn-jyrt-21Ceg-21CgC-jkmy-jkHk-jkHV-21Cfm-jkHz-jkHr-jkGP-jkGV-jkHa?ref=justinw.me) Mac Pro. Before Apple was the largest company in the world, they built the best computers and operating systems for the tastemakers of technology. I never worked with Seb on a project[\[1\]](#fn1), but I worked with some of the best designers that have gone on to build the biggest products of the mobile era. We'll ignore that I continue to toil in obscurity, dear reader. I haven't said much about the Mac Pro's demise because there's plenty of other people with opinions on the hardware. That said, I am glad to see it's no longer on its deathbed. It may not be Apple's most profitable product, but it doesn't need to be. When you have the ability to positively effect the real influencers of the industry[\[2\]](#fn2), it's hard to see the downside. I am not sure if the Mac Pro is for me anymore, but I much prefer an Apple that invests at least some of its billions in flexing its computing muscle from time-to-time. Not because it needs to, but because it wants to and can. (via [Pixel Envy](https://pxlnv.com/linklog/why-pro-matters/?ref=justinw.me)) --- 1. Someday! [↩︎](#fnref1) 2. The people that do the work, not just talk about it at tech conferences. [↩︎](#fnref2) ### My Ultimate Developer and Power Users Tool List for macOS Sierra (2017 Edition) URL: https://www.justinw.me/blog/my-ultimate-developer-and-power-users-tool-list-for-macos-sierra-2017-edition/ Last updated: 2017-04-03T14:38:13.000Z This is the latest installment of my must have must have list of tools and utilities as a macOS and iOS developer. The idea for this list was shamelessly ripped off from [Windows developer Scott Hanselman](http://www.hanselman.com/blog/ScottHanselmans2014UltimateDeveloperAndPowerUsersToolListForWindows.aspx?ref=justinw.me) whose list has long been an enjoyable read when he updates it. There have been significant changes since I last did one of these. I’ve tried to mark anything new in bold. ### Hardware Since I last updated this in 2013, my hardware has changed significantly. I am still maintaining a dual Mac setup. My daily driver is a Late 2015 27" Retina 5K iMac with a 1TB SSD and 32GB of RAM. After nearly five years, I replaced my old 2010 iMac that was starting to show its age when compiling Swift. Swift eats hardware for breakfast, lunch, dinner, and fourth meal. I’d say this was Apple’s genius plan to sell more Mac hardware, but they can’t be bothered to update their hardware lineup regularly so there went that theory. At home I am using my 15" Retina MacBook Pro with a 1TB SSD and 16GB of RAM. This is one of the new Touch Bar models and it’s fine. I somehow have been able to survive without a physical escape key or a row of function keys. I assume this makes me lose some sort of geek cred. Sorry, nerds. I used to be a big Dropbox user, but I’ve moved all of my files over to [iCloud Drive](https://www.icloud.com/?ref=justinw.me) because it’s good enough. I take advantage of the Shared Desktop and Shared Documents functionality of macOS Sierra. Photos are stored in iCloud. Calendar and Contacts too. It works, usually. There wasn’t anything wrong with Dropbox, but it was just another thing I was paying money for that wasn’t super necessary when there’s a good enough alternative baked into the OS now. In terms of accessories and upgrades: - I use a [Das Keyboard](http://amzn.to/2nOc2zP?ref=justinw.me "Das Keyboard"). I love it. The Das Keyboard doesn't make me a better developer, writer or person. It just feels satisfying to use. - On the left side of my iMac I use a [Magic Trackpad 2](http://amzn.to/2ntzXkD?ref=justinw.me "Magic Trackpad 2") for swiping and gesturing between full-screen apps and Mission Control. I am a big user of multitouch gestures in Sierra, so I am incredibly comfortable using the trackpad. - On the right side of my iMac I use a [Logitech MX Master](http://amzn.to/2nO2i8u?ref=justinw.me "Logitech MX Master") to do all my pointing and clicking. It has more buttons than I have fingers, but somehow I have found a way to map a unique action to each one. - Time Machine backups are handled by a [4TB LaCie d2 Thunderbolt 2 drive](http://amzn.to/2nKY1B7?ref=justinw.me "LaCie Drive"). It's fairly quiet and is one of the few external drives I've found that doesn't have a horrific design. The blue light has a piece of duct tape over it though because it was distracting. - I connect to the Internet through my [Netgear Nighthawk X8](http://amzn.to/2ntvxtT?ref=justinw.me). It has four giant antennas on the back and looks like it may take off at any point. I am interested in trying something like Eero in the future, but for now the Nighthawk works. ### Software I am really hard on software. This is for a variety of reasons, but I think it is because I build it myself. I have always envisioned that directors and actors can sometimes lose focus during a movie as they judge the decisions others made in their productions. I feel like I do the same thing with software. I loathe poor and/or non-native user interfaces and cherish simple tools. These are applications I constantly rely on. #### The Essential Five - [Dash](https://kapeli.com/dash?ref=justinw.me) \- I know Apple keeps trying to improve the documentation viewer that ships with Xcode, but I am still a loyal Dash user. Not only does it work with Apple’s documentation, but having other languages I may be using accessible as well is a big win. - [1Password](https://itunes.apple.com/us/app/1password-password-manager-and-secure-wallet/id443987910?mt=12&ref=justinw.me) \- One of the first tools I install. I store not only passwords, but also things like Amazon access keys, SSH credentials, and a variety of other things I need to secure with 1Password. Hopefully it’s more secure than the DNC email servers. - [OmniFocus](https://itunes.apple.com/us/app/omnifocus-2/id867299399?mt=12&ref=justinw.me) \- I don't know how I ever stayed organized before OmniFocus on my three screens. It's my brain. With my work tasks, I tend to take what I am currently working on and break it down into separate OmniFocus projects that I can focus on as a daily task. It’s easier than tracking everything in Asana or whatever bug reporter of the week my clients are interested in. - **[Atom](https://atom.io/?ref=justinw.me)** \- The last time I wrote one of these posts, I was a devout Sublime Text user. Before that I was a BBEdit user. Now? Atom from GitHub. I use Atom for any non-Xcode related development tasks I have as well as looking at log files and other random bits of text. - **[Tower](https://www.git-tower.com/mac/?ref=justinw.me)** \- I can use Git via the command line if I have to, but I don’t see any reason to when there’s a powerful app like Tower there to do hide all the weirdness from me. I probably use this app more than any other third-party app on my Mac. #### Developer Tools - [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12&ref=justinw.me) \- If you write macOS, iOS, tvOS, or watchOS applications, you spend most of your life in Xcode and Instruments. I am no different. - [Appfigures](https://appfigures.com/?ref=justinw.me) \- Manually fetching iTunes sales reports is tedious. Appfigures is a low-cost Web service that will import your reports and send you a daily sales email. I also like to funnel our reviews into a Slack channel so we are more aware of what users are saying. - [Base](https://itunes.apple.com/us/app/base-sqlite-editor/id402383384?mt=12&ref=justinw.me) \- Core Data generates a SQLite database under the hood. I'm constantly inspecting the database contents using this application. It's lightweight and easy to use. - [Charles](https://www.charlesproxy.com/?ref=justinw.me) \- Sometimes I want to snoop the traffic that is going through an iPhone app. Setting up Charles makes it pretty easy to do just that. - **[Color Picker](https://itunes.apple.com/us/app/color-picker/id641027709?mt=12&ref=justinw.me)**: Must have. Choose whatever color you want and then it will output a UIColor or NSColor for you. - Git: I am now exclusively on Git for version control. Thanks, GitHub. - [HockeyApp](https://hockeyapp.net/?ref=justinw.me) \- I am using Hockey for handling crash reports. Microsoft bought them a few years ago and continues to improve the service with other features, but I find the crash reporting to be the only indispensable function. At least until I can learn to trust iTunes Connect. - **[Hyper](https://hyper.is/?ref=justinw.me)** \- I am using more Electron apps by the year it seems. Hyper is a replacement for Terminal built on Electron. I don’t do anything special with it over the bundled Terminal app. I just like how it looks. I am such a Mac user. - [Kaleidoscope](https://itunes.apple.com/us/app/kaleidoscope/id587512244?mt=12&ref=justinw.me) \- I have never been a fan of the bundled merging tools with Xcode. Kaleidoscope is vital to my workflow when running diffs on my Git commits. It’s too bad this is seemingly abandonware. It’s a great app that I plan to keep using until it no longer launches. - [Patterns](https://itunes.apple.com/us/app/patterns-the-regex-app/id429449079?mt=12&ref=justinw.me): I don't think I will ever fully grasp Regular Expression syntax. Patterns makes it easier for me to fumble around trying to build and test a regex compared to doing sample finds in Sublime Text. - [QuickRadar](http://www.quickradar.com/?ref=justinw.me) \- The RadarWeb UI still sucks. QuickRadar makes me more likely to file bugs because it is in my Dock, it can cross-post to OpenRadar, and it has never crashed or lost a bug report while I was trying to submit it. - **[Realm Browser](https://itunes.apple.com/us/app/realm-browser/id1007457278?mt=12&ref=justinw.me)** \- Core Data is trash. I’d use Realm for every app if I could. Since Realm uses a custom format for its database you need an app to inspect it. For SQLite you use Base. For Realm, you use this. - **[Paw](https://paw.cloud/?ref=justinw.me)** \- I keep a Paw document for each API that I interact with so that I can quickly test out API calls to see what the JSON returned is. - [Sketch](https://www.sketchapp.com/?ref=justinw.me) \- If you work with a designer they are most likely using Sketch. Keeping a copy nearby so you can inspect files is handy. I also use it for my super rudimentary design on this site. - [Slender](https://itunes.apple.com/us/app/slender/id493656257?mt=12&ref=justinw.me) \- If you're using Xcode I bet you have a few assets in your Xcode project that are no longer in use. Those kilobytes are wasting your customers' bandwidth and yours. Slender analyzes your Xcode project and finds those assets that are no longer in use so you can safely delete them. - **[Slack](https://itunes.apple.com/us/app/slack/id803453959?mt=12&ref=justinw.me)** \- If you work for a startup, you are contractually required to use Slack at this point. - **[VS Code](https://code.visualstudio.com/?ref=justinw.me)** \- If you take all the disdain I have for Xcode and inverted it, you’d have my affection for Visual Studio Code. A powerful programmer IDE that gets meaningful monthly updates and has a vibrant, useful plugin community? I’m in love. - [xScope](https://itunes.apple.com/us/app/xscope-4/id889428659?mt=12&ref=justinw.me) \- I use xScope to detect colors on various UI elements, check alignment of controls and to measure the distance between objects. If you (or your designers) are meticulous about your UI, it's an essential utility. #### User Tools - [Acorn](#) \- Acorn is my favorite image editor for the Mac. It's fast, intuitive and looks pretty neat too. - [Backblaze](https://www.backblaze.com/cloud-backup.html?ref=justinw.me#af9kg4) \- While I primarily rely on Time Machine for my backups, I also subscribe to Backblaze to offload the contents of my hard drive to the Internet for when I am burglarized for the third time this decade. - **[iStat Menus](https://bjango.com/mac/istatmenus/?ref=justinw.me)** \- Since Swift enjoy eating CPUs for breakfast, I like to have a quick way to see how taxed my system is during compilation. iStat sits in my menu bar and gives me all the essential info I need. - [OmniOutliner Pro](https://itunes.apple.com/us/app/omnioutliner-pro/id404647179?mt=12&ref=justinw.me) \- When I am doing more complex writing projects than a blog post, I outline the entire thing in OmniOutliner. The ability to have drop-down fields is one of my secret weapons. Love that. - **[Pastebot](https://itunes.apple.com/us/app/pastebot/id1179623856?mt=12&ref=justinw.me)** \- I never thought I would be one of those clipboard manager people, but Pastebot is so simple that I converted. The ability to sync my clipboard over iCloud is honestly what won me over. It’s like Handoff’s copy/paste support, but reliable. - **[PDF Expert](https://itunes.apple.com/us/app/pdf-expert-edit-annotate-and-sign-pdfs/id1055273043?mt=12&ref=justinw.me)** \- Preview is a fine PDF viewer, but I’ve come to adore PDF Expert because of its editing capabilities and super easy signing of documents. - **[Rocket](http://matthewpalmer.net/rocket/?ref=justinw.me)** \- If you’ve adapted to using Slack for throwing emojis out, Slack brings that functionality to your Mac. Now I can easily throw out a 💯without a few keystrokes. - [Soulver](https://itunes.apple.com/us/app/soulver/id413965349?mt=12&ref=justinw.me): Soulver is the best calculator app on the planet. There is no debate. - [The Unarchiver](https://itunes.apple.com/us/app/the-unarchiver/id425424353?mt=12&ref=justinw.me) \- A file extraction utility is somewhat of an unsung hero, but when you need it, it's good to have a utility that is robust and can fit almost any bill. The Unarchiver does that and does it well. - **[TunnelBear](http://click.tunnelbear.com/aff%5Fc?offer%5Fid=36&aff%5Fid=2842&source=carpeaqua)** \- Since the United States Congress seems keen to allow ISPs to sell all my data without my consent, I tend to run a VPN as much as possible these days. TunnelBear is my preferred one for the last few years. It doesn’t hurt that their branding is adorable. - [Twitter for Mac](https://itunes.apple.com/us/app/twitter/id409789998?mt=12&ref=justinw.me) \- You probably use Tweetbot, but I actually prefer the official Twitter client for desktop tweeting. Sorry to all those offended. - **[Ulysses](https://itunes.apple.com/us/app/ulysses/id623795237?mt=12&ref=justinw.me)** \- I wrote this entire post in Ulysses. In fact, I do most of my writing in Ulysses these days. It’s both a fantastic Mac and iOS app. ### Showing Debug and Info Logs in the macOS Sierra Console URL: https://www.justinw.me/blog/debug-and-info-unified-logging/ Last updated: 2017-03-22T14:42:38.000Z This is one of those "it's obvious in hindsight" problems I ran into recently. At the day job, we have been migrating all of our logging code from [Aspen](https://github.com/justin/Aspen?ref=justinw.me) to Apple's new [Unified Logging System](https://developer.apple.com/reference/os/logging?ref=justinw.me). This has been a win for the most part: we got to terminate a third-party dependency, while also getting some advanced features such as log filtering based on a category or subsystem. The problem I ran into last week was trying to debug a background session issue on my iOS device. We use the different logging levels provided by `os_log` to help keep users logs a bit less chatty than just spitting out `print` or `NSLog` statements everywhere. By default, the new Console app in macOS Sierra only shows logs that match the `error` level (or have no level at all). I needed to see our debug and info log information. If you watch the [WWDC video](https://developer.apple.com/videos/play/wwdc2016/721/?ref=justinw.me) on the new logging system they show you a few Terminal commands you can run to adjust your logging level on the Mac. It doesn't really show you how to adjust that for an iOS device plugged into your Mac, however. Long story short, there's no Terminal command. There's two options in the "Action" menu on the Console. Just select "Include Debug Messages" or "Include Info Messages" and you are good to go. ![Turn on info and debug messaging in the Sierra Console](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/sierra_logging.png) I sure felt dumb once I figured that out. You win this round, Apple. ### Improving the iPad By Making it an iMac URL: https://www.justinw.me/blog/looking-backwards/ Last updated: 2017-02-23T22:17:32.000Z Jason Snell on [“improving” iOS for the iPad](http://www.macworld.com/article/3173253/ios/for-a-bigger-ipad-to-work-ios-needs-some-interface-improvements.html?ref=justinw.me): > Will we see a 20-plus-inch iOS desktop with a windowed interface anytime soon? I doubt it–but I could imagine one existing in the next three or four years. And I have to be honest, I’d be intrigued by the idea of replacing my 5K iMac with one. It just needs to be able to run a bunch of apps at once, and let me arrange them in a way that works for me. Tabbed interfaces, multiple windows, and a laptop form factor? If he had just mentioned needing a file system, I would have hit BINGO. ### The Conference Circus URL: https://www.justinw.me/blog/the-conference-circus/ Last updated: 2016-12-20T10:37:32.000Z I want to quote this entire article by [Pedro Piñera](http://ppinera.es/2016/11/16/in-a-world.html?ref=justinw.me), but I’ll just highlight my favorite part. > By tagging the elite as “experts” in different areas we put them under pressure. Pressure to keep that label and keep being active. I have to be at more conferences, I have to keep proposing more talks, I have to check Twitter or post that I opened a radar about a crash in the last Xcode version that is still beta. As you might guess some people can’t handle that and it leads them to burnout. I’ve heard it from a few developers. I had to stop attending conferences because I got burnout. Moreover, some can’t control the ego. Being part of the elite sets them levels above you. No matter how you approach them, the way they get back to you depends on the levels you are far from them. **That’s very bad**. I spent a good chunk of 2010 to 2014 on the Conference Circuit accepting speaking gigs as exciting as a theatre in Australia to a Holiday Inn in the Chicago suburbs. I noticed pretty much the same things as Pedro. You had a pretty good mix of: 1. Person who does nothing but conference talks year round. They talk about writing software more than actually writing software. 2. Person who is incredibly unprepared and will just eat shit in front of their audience. This is the worst person of all. 3. Person who is speaking for the first-ish time and has new and interesting ideas to share. I’d much rather attend a conference with the third person than the first two. I want to learn from people in the trenches, not someone who makes their living collection frequent flyer miles going from conference to conference. When I stopped doing the conference circuit, I was worried I was spending way too much time becoming #1. Now, I do one conference a year: [360iDev](https://360idev.com/?ref=justinw.me). Moreover, I will only do 360 if I have something new to share. I did three separate years worth of Auto Layout talks, each with a unique set of content for anyone that came annually. This last year I instead opted to do a talk on application architecture, because I had spent so much of the summer of 2016 digging into the guts of the application I work on most of the day and trying to imagine how to rearchitect it for its next 5 years of growth. Instead of just trying to sell more copies of the Auto Layout book by rehashing an old Auto Layout talk, I opted to take my newest learnings and share them with the audience. It takes me a week to prepare my presentation, but I hope everyone that leaves my room learns something and doesn’t feel like their time was wasted. ### Fighting Back URL: https://www.justinw.me/blog/fighting_back/ Last updated: 2016-12-19T07:00:36.000Z Like most people in [my bubble](https://www.youtube.com/watch?v=vKOb-kmOgpI&list=PLS%5FgQd8UB-hIPqw-93d3IRdf6phKCLGH2&index=7&ref=justinw.me), the US Elections didn’t exactly go how I planned. There’s been a lot of handwringing about how to best fight back against an administration that you and other like-minded folks are staunchly against. While I’m all for a good bit of [slacktivism](https://en.wikipedia.org/wiki/Slacktivism?ref=justinw.me) as much as the next guy, I’m trying to extend my anti-Trump rhetoric beyond just a safety pin and a few angry tweets. ### Staying Informed I admit that I have tuned out much of the news and politics over the last decade. As the right has gone farther right (and the left farther left), I have been left on an island in the center feeling unrepresented. Sticking my head in the sand and ignoring the issues hasn’t exactly worked out that well, so now I’m focused and paying attention. Keeping up with the daily news of what happens in Washington, locally in Denver, and even globally is more important than ever. The Affordable Care Act is flawed, but it’s also the only way I have been able to get healthcare in the last few years. I’ve long been rejected for individual coverage because I take anti-depressants. I’m otherwise a healthy, fit 34 year old. But my one $25 a month prescription was grounds for Anthem, United, or whomever to reject me. For all its flaws, Obamacare fixed that for me. If Donald Trump and his party want to repeal the ACA, they damn well better have a better solution. I’ll be paying attention and ready to judge that. ### Supporting The Press Beyond just paying attention to the news, I’m putting my money towards journalism more directly than just eyeballs through ads. I’ve subscribed to both the New York Times for my national news coverages and the Denver Post for local coverage. The approximately $20 a month this costs me won’t pay anyones salary, but my hope is that if newspapers have a bit more money to work with, they can focus on keeping our leaders honest instead of just keeping their lights on. ### Supporting Your Causes I am not much for protesting, a bit too busy to work a phone bank, and way too socially awkward to run around trying to collect signatures or whatever people with outgoing personalities do. I am however able throw a little money at problems. I have long been a financial supporter of the [EFF](https://www.eff.org/?ref=justinw.me), but my donations to other causes have either been nonexistent or one-off as I felt necessary. No more. I’m now a recurring supporter of the causes I care about and want to help protect. - The [ACLU](https://www.aclu.org/?ref=justinw.me) is already gearing up for many a battle with a Trump administration that will likely look to trample over our freedoms at every turn. - The \[Natural Resources Defense Council\]\[nrdc\] is prepared to protect our planet and hopefully prevent the new administration from undoing decades worth of forward progress against climate change. - I’m supporting [Planned Parenthood](http://plannedparenthood.org/?ref=justinw.me), both because I agree with their mission, but also because I know it drives my Fox News watching relatives nuts. You don’t have to support these, but if you are able, I’d recommend finding a group that you do align with, and supporting them however you can. ### Netflix, iOS, tvOS, CenturyLink, and a Netgear Nighthawk, Oh My! URL: https://www.justinw.me/blog/netflix-ios-tvos-centurylink-and-a-netgear-nighthawk-oh-my/ Last updated: 2016-11-18T14:18:13.000Z There is zero point to this post. I’m only writing it in case someone else runs into this issue. Hopefully they don’t have to spend as many hours as I did to debug this. Maybe someone can also explain why this was an issue in the first place. For the last six months or so I have been unable to use Netflix on any iOS or tvOS device (version 10.x at the time of this writing). I could sometimes get my list of content to load, but any attempt at playback failed with generic Netflix errors. Even signing into my Netflix account would be a chore. If you search the Netflix support site they offer the basic unhelpful support information: have you tried restarting your device or router? I have a CenturyLink Gigabit fiber line, so hearing that it might be an issue with my connection seemed wrong, especially when you consider that I use a variety of other streaming services without issue. The other questionable thing is that Netflix **does work** on any non-iOS device such as my Xbox One, TiVo Bolt, and (gasp) Android phone. Any device with a fruit logo, however, was a no-go. My home network setup isn’t super complex, but it’s also not a stock setup either. - CenturyLink’s fiber line comes into the house and is routed through a [Technicolor C2000T modem](http://internethelp.centurylink.com/internethelp/modem-technicolor.html?ref=justinw.me). This is in bridge mode so it merely acts as a passthrough. - For routing and WiFi I have a [Netgear AC5300 Nighthawk X8](http://amzn.to/2f7y3lq?ref=justinw.me). You might be wondering why I don’t take the C2000T out of the equation and just use PPPoE with this. I tried, but there is something with that C2000T that enables full speed. I couldn’t get above 500/500 speed with just the Nighthawk in play. - iOS and tvOS devices are all connected via WiFi. iMac and random Internet of Things devices are plugged into the router via Ethernet. ### What I tried and What Actually Worked My first thought was maybe it was some sort of Quality of Service (QoS) issue with the router. I checked and I didn’t have any QoS settings enabled. Just as an experiment I tried turning them on. Still no Netflix on iOS or tvOS. My next experiment involved trying to put my tvOS devices as the DMZ host so they had a straight passthrough from the router to the open Internet. My hope was that maybe whatever is going on in the router that was filtering the Netflix connection would just be bypassed. Hopes dashed. Still nothing. My last idea was based off a random guess, but turned out to actually work: I disabled IPv6 on the Nighthawk. **Success**! I have no idea what issue is with the chemistry between Netflix, Apple’s network stack, my router, and IPv6\. All I know is that I can now watch Black Mirror. **Update:** Maybe it has something to do with IPv6 being blocked by [Netflix’s war on VPNs](http://www.techrepublic.com/article/as-netflix-attempts-to-limit-vpn-use-ipv6-users-lose-out/?ref=justinw.me)? ### Advanced iOS Application Architecture URL: https://www.justinw.me/blog/advanced-ios-application-architecture/ Last updated: 2017-03-25T16:59:34.000Z I am mostly retired from the public speaking circuit. I do still make a point to try and do [360iDev](https://360idev.com/?ref=justinw.me) in Denver each year, considering the proprietor is a friend and I can sleep in my bed every night of the conference. This year I did a talk that was a departure from my last few years of Auto Layout talks. Instead, I did a walkthrough of how I architect modern iOS apps. If you attended the conference and saw the talk, I hope you enjoyed it. If you didn’t attend, it’s already online and ready to watch. ### What Old Is New Again in Auto Layout on iOS 10 URL: https://www.justinw.me/blog/what-old-is-new-again-in-auto-layout-on-ios-10/ Last updated: 2016-06-29T13:30:30.000Z The “What’s New in Auto Layout” talk seems to be becoming an annual tradition at WWDC. I didn’t attend in person this year, because I couldn’t get out of San Francisco fast enough on the Friday of the conference, but I recently sat down and watched the video and have been thinking about what Apple is offering this year. This year’s session was surprising, to say the least. After spending the last three years preaching that autoresizing masks weren’t long for this world, Apple went ahead and made me eat a full serving of crow by “introducing” a new feature in Xcode 8 called “autoresizing masks.” For those new to Mac and iOS development, autoresizing masks is the “old” way of doing things before Auto Layout was introduced back with OS X Lion. Instead of explicitly setting relationships between your views, you set the springs and struts values to assign the resizing and pinning behavior of the view. Even with Auto Layout, springs and struts never really went away. When the system unable to determine the layout of your application with your given set of constraints, it would plug in its own set of constraints implicitly, usually tied to springs and struts, to fill in the gaps. Any time you call `translatesAutoresizingMaskIntoConstraints` on a `UIView` you are opting out of letting the system create constraints for you based off autoresizing masks as well. With the new incremental adoption policies in iOS 10 and above, Apple is now stepping back its hardline on Auto Layout adoption and instead realizing that in some scenarios, the old way can actually can be better. Specifically, if you just need to set up some basic resizing behavior opting into letting the system add its default constraints at compile time with a little help from your defined autoresizing masks is less work than manually creating constraints yourself. In a lot of ways it feels like a more pragmatic middle ground between the old way of doing things and the 100% pure Auto Layout approach. Resizing masks are still not without their tradeoffs: if you are dealing with localization you’re going to want to opt into Auto Layout and all that is has to offer. I just localized an entire app and it would have been far more hellacious if I was sticking to autoresizing masks instead of Auto Layout. But, for things like fast prototypes or the most basic of views with minimal behavior requirements not having to set up constraints could definitely save you some development time. ### A Sane Reference for TargetConditionals URL: https://www.justinw.me/blog/targetconditionals/ Last updated: 2016-06-26T11:10:59.000Z I’ve spent the past couple days cleaning up some code to work on iOS, macOS, and watchOS. One thing I constantly struggle with is keeping the values I need from `TargetConditionals.h` in my head for when I want to `#if` branch a segment of Objective-C code for a specific platform. So . . . I made a table. Current as of: iOS 9.3, tvOS 9.2, watchOS 2.2, macOS 10.11 | Macro | 💻 device | 📱 device | 📱 simulator | ⌚️ device | ⌚️ simulator | 📺 device | 📺 simulator | | ----------------------------- | --------- | --------- | ------------ | --------- | ------------ | --------- | ------------ | | \`TARGET\_OS\_MAC\` | ☑️ | ☑️ | ☑️ | ☑️ | ☑️ | ☑️ | ☑️ | | \`TARGET\_OS\_IPHONE\` | 🙅🏻 | ☑️ | ☑️ | ☑️ | ☑️ | ☑️ | ☑️ | | \`TARGET\_OS\_IOS\` | 🙅🏻 | ☑️ | ☑️ | 🙅🏻 | 🙅🏻 | 🙅🏻 | 🙅🏻 | | \`TARGET\_OS\_WATCH\` | 🙅🏻 | 🙅🏻 | 🙅🏻 | ☑️ | ☑️ | 🙅🏻 | 🙅🏻 | | \`TARGET\_OS\_TV\` | 🙅🏻 | 🙅🏻 | 🙅🏻 | 🙅🏻 | 🙅🏻 | ☑️ | ☑️ | | \`TARGET\_OS\_SIMULATOR\` | 🙅🏻 | 🙅🏻 | ☑️ | 🙅🏻 | ☑️ | 🙅🏻 | ☑️ | | \`TARGET\_OS\_EMBEDDED\` | 🙅🏻 | ☑️ | 🙅🏻 | ☑️ | 🙅🏻 | ☑️ | 🙅🏻 | | \`TARGET\_IPHONE\_SIMULATOR\` | 🙅🏻 | 🙅🏻 | ☑️ | 🙅🏻 | ☑️ | 🙅🏻 | ☑️ | Hopefully someone else finds this useful. ### TED 3.0: Working Effectively with Legacy iOS Code URL: https://www.justinw.me/blog/working-effectively-with-legacy-ios-code/ Last updated: 2017-03-20T22:54:10.000Z I don’t talk often about the work I do to keep the lights on at my house, but I have spent a good portion of the last four years working on the [TED for iOS](https://www.ted.com/?ref=justinw.me) app. The 3.0 release is the biggest release we’ve undertaken at TED in terms of scope and amount of changes to bring it to a head. The marquee feature is the app is now localized in 20 new languages. Users all over the world can now experience TED in their native languages from Arabic to Turkish. Behind the scenes we have been planning to localize the app for over a year. What took so long? ### A History Lesson ![TED for iOS 1.0](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/ted-1-0.jpg) TED for iOS first arrived on the App Store in October of 2010, and was released exclusively for the original iPad. TED for iOS 1.0 was designed to run on iOS 3.2\. For the last six years we have been building on on this foundation as devices and capabilities for Apple’s platforms change. In my time at TED (September 2012 to present) I’ve seen: - Retina graphics, 3x graphics, and eventually vectors. - AVFoundation making it easy for us to do our own custom video player (my first TED project!). - The introduction of ARC as a replacement for manual retain/release. - XCTest replacing OCTest. - Larger and smaller devices such as the iPad mini, iPad Pro, iPhone 5, iPhone 6, and iPhone 6 Plus. - Auto Layout and size classes for bringing some sanity to managing all these new device sizes. - App extensions for things like widgets and custom share actions. - Oh, and a little thing called [Swift](https://swift.org/?ref=justinw.me). When TED shipped back in 2010 it was written entirely in Objective-C and designed to work on two device sizes: the iPhone 3GS and original iPad. Now we support phones as small as the iPhone 4s up to iPads like the 12.9″ iPad Pro. In that entire time, we have continued to update the same app code base. There has never been a full-on rewrite of the iOS project, as tempting as it may be at times. ### Renovating The House You Live In Early last year, I took over as the lead developer of TED and began to dedicate more time to it than anyone had in previous years (TED has always been at most 2 part-time developers, and sometimes just 1). This allowed us to shift our mindset from maintaining the existing app to keep the wheels on while adding features occasionally to trying to be more ambitious with mobile goals. The only problem was that a lot of our code was showing its age. I made a list of high level goals to modernize the app going forward in small chunks so that we could still continue to ship updates to make TED HQ happy, while I eliminated many of the things that kept me up at night. The first of those projects was to modularize the app. Since we are a small team, and have a fairly engaged group of users who upgrade quickly, we jump on the latest version of the iOS SDK faster than most companies. I set our minimum SDK to iOS 8 and began to break the app down into separate components. Instead of a single Xcode project with all our code in it, we broke it into separate dynamic frameworks: - TED: the main iOS app - TEDData: data layer and business logic related classes - TEDVideo: our custom video player - TEDCore: shared code that is used between all of the different frameworks By modularizing the code, it made it easier to start adopting unit tests for pieces of the code that had never sniffed XCTest in its life. It also helped the workflow so I could only try compiling TEDData if I was working with the data model exclusively, rather than having to wait and compile the entire app. ### Adopting Adaptivity When I found out that localizing the app into 20 languages was high on the list of priorities for TED, I made it pretty clear that the current foundation that the app lived on would not be capable of supporting it in a way that would allow the development team to be successful. Nearly every piece of code in the application was duplicated for both the iPhone and iPad. Up until earlier this year when you would launch the TED app on your iPhone, we would fork off to a different set of interface elements depending on if you were on an iPhone or iPad. So, for example, our Featured tab had `FeaturedViewController_iPhone` and `FeaturedViewController_iPad` with completely separate interface elements. On top of it, none of this interface code had been updated for Auto Layout, size classes, or Storyboards. In fact, most of it hadn’t been touched in years other than the occasional bug fix. This was by far the most painful part of the app and took several months (you can see the gap in our releases last fall.) to not only consolidate down to a single `UIApplicationDelegate`, but also to consolidate and clean up the TED interface as much as possible using size classes, Auto Layout, and Storyboards. We shipped all of this work in late January as part of TED 2.6\. You likely didn’t notice a thing had changed if you used the app, but that was by design. Our metric for success was the user **not** noticing anything had changed. Internally, however, the entire app had been built up on a new foundation that would enable us to move a lot faster and move closer to localization. ### Adopting Swift As of version 3.0, about 20% of the TED code base is written in Swift. That is up from 0% at this time last year. The first bits of Swift code we wrote were part of the adaptivity cleanup when I rewrote the entire ‘Surprise Me’ tab in Swift as a test case to see how it would go. You’ve heard the success stories before, so it should come as no surprise that I was a big fan. Not only was the code more concise and easy to read, but there was a lot less of it. I’m pragmatic when it comes to adopting Swift in TED. If we need receive new designs for an existing feature, we go through the process of rewriting the code in Swift. If we encounter some Objective-C code that isn’t a candidate for a rewrite, I do take the time to add nullability attributes to it so that it behaves better when we are calling it in Swift, which makes the entire mixed code base experience much more pleasant. I lose zero sleep over the lack of dynamism in Swift. ### Tests and CI The last component of our maturation as a mobile development team is building out our test suite and getting it running automatically as part of continuous integration. All commits are now automatically running our test suite on our CI server to make sure that we don’t add any regressions. Most (not all) new code is also being written with automated tests attached to it. We still have a major gap when it comes to integration and UI testing, but we’ll get there eventually. One example where we are having great success with our test suite is when it comes to working with localization. There are several edge cases we need to handle when it comes to mapping Chinese language codes between iOS and the TED API. We automate all of that using XCTest, which makes it super easy to understand the intent of the code without having to run the app and step through the debugger. ### The Localization Process This entire modernization process took place off-and-on from January of 2015 to April of 2016\. The actual process of localizing the app took place in the last four weeks. Since we went through the work of getting the app running on Auto Layout in as many places as possible, exporting and importing our xliff files meant that we had a minimal amount of interface work to do when it came to testing the actual interface. The biggest hassles turned out to be adjusting a few buttons to support multi-lines for more verbose languages like German. I was admittedly shocked that this worked as well as it did, but it’s a testament to the work we put in building up to this actual release. 16 months of preparation for 4 weeks of work! ### tl;dr - You don’t have to rewrite your legacy app from scratch. - Don’t fall too far behind Apple’s current functionality or you will pay for it, eventually. - Swift is great, but Objective-C is just fine too. - Localization is way easier with Auto Layout and size classes. - Unit testing and CI *are* worth it. There’s still a ton of work to be done both internally and externally to bring the TED app to where I want it to be, but I’m pretty pleased with the work that we put in to get to this 3.0 release. I hope you’ll [check it out](https://appsto.re/us/RObBw.i?ref=justinw.me) ![TED 3.0](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/ted-3-0.jpg) ### Picking your Swift toolchain from xcodebuild URL: https://www.justinw.me/blog/picking-your-swift-toolchain-from-xcodebuild/ Last updated: 2016-06-24T11:27:25.000Z With Xcode 8 `xcodebuild` uses Swift 3 to build by default. This will be great in about six months, but right now it’s somewhat of a pain. I am using Carthage as my dependency manager and all of those are using Swift 2.x still. If you want to build your Carthage dependencies (or anything from the command line for that matter) using Swift 2.3, add the `TOOLCHAINS` parameter. ``` TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 carthage build ``` **Update:** As of Carthage [0.17](https://github.com/Carthage/Carthage/releases/tag/0.17?ref=justinw.me) you can use a `--toolchain` option. This doesn’t help with raw `xcodebuild` obviously. ### When Good Apps Crash Unexpectedly URL: https://www.justinw.me/blog/when-good-apps-crash-unexpectedly/ Last updated: 2016-05-01T06:41:21.000Z I had a fun Friday evening. I received a Slack notification sent to everyone in our group stating that the iOS app was crashing on launch. This came as a surprise to me, because our most recent release had been out for several weeks at this point. It also was the most stable release in terms of number of crashes we’ve ever released. This was a **good** point release. After a few minor heart palpitations, I grab a few iOS devices and try launching the App Store version of the app. Success. No crashes for me. A few other team members launch the app successfully as well. At this point, I make a suggestion straight out of Microsoft’s 1990’s playbook: restart your phone. No more crashing on launch. My theory was correct. I’ve seen a few times in the last few months where an app will randomly begin crashing on launch for no rhyme or reason. I’ve never really tried debugging it because it wasn’t my app crashing, but now I was annoyed. I made a point to check the iOS device console next time I saw one of my apps doing this weird crash on launch behavior. Fast forward to yesterday when I wanted to check a few things in the Major League Baseball app. I tapped the MLB icon and . . . crash. Rinse. Repeat. I decided to go on a round-robin through my apps and see if any others are crashing. Turns out Medium, United Airlines, and Pocket are also crashing. The odds of four of these major apps all shipping at-launch crashers at once are good enough to make you rich in Vegas. At this point, I am pretty confident what’s going on but I’m not at home so I can’t easily plug my phone in and see what’s happening. I’ll just have to forgo three of my most used apps because I’m not restarting my phone yet. Once I get home, I plugged my iPhone into my Mac, popped open device console in Xcode and tried launching the failing apps again. Here’s what spit out: ``` Apr 30 11:17:55 iPhone kernel[0] : AppleFairplayTextCrypterSession::fairplayOpen() failed, error -42028 Apr 30 11:17:55 iPhone assertiond[12347] : Unable to obtain a task name port right for pid 14063: (os/kern) failure (5) Apr 30 11:17:55 iPhone SpringBoard[12335] : Unable to register for exec notifications: No such process Apr 30 11:17:55 iPhone SpringBoard[12335] : Unable to obtain a task name port right for pid 14063: (os/kern) failure (5) Apr 30 11:17:55 iPhone SpringBoard[12335] : Unable to obtain a task name port right for Apr 30 11:17:55 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.medium.reader[0x7257][14063]) : Service exited due to signal: Killed: 9 Apr 30 11:17:55 iPhone SpringBoard[12335] : Application 'UIKitApplication:com.medium.reader[0x7257]' exited abnormally via signal. Apr 30 11:17:56 iPhone SpringBoard[12335] : Application '(null)' exited for an unknown reason. Apr 30 11:17:56 iPhone kernel[0] : IOAccessoryManager::configureAllowedFeatures: tristar: revoking mask=0xffff Apr 30 11:17:56 iPhone iaptransportd[12353] : CIapPortAppleIDBus: Auth timer timeout completed on pAIDBPort:0x15cd06f70, portID:01 downstream port Apr 30 11:17:58 iPhone kernel[0] : AppleFairplayTextCrypterSession::fairplayOpen() failed, error -42028 Apr 30 11:17:58 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.ideashower.ReadItLaterPro[0x33c1][14064]) : Service exited due to signal: Killed: 9 Apr 30 11:17:58 iPhone assertiond[12347] : Unable to obtain a task name port right for pid 14064: (os/kern) failure (5) Apr 30 11:17:58 iPhone SpringBoard[12335] : Unable to register for exec notifications: No such process Apr 30 11:17:58 iPhone SpringBoard[12335] : Unable to obtain a task name port right for pid 14064: (os/kern) failure (5) Apr 30 11:17:58 iPhone SpringBoard[12335] : Unable to obtain a task name port right for Apr 30 11:17:58 iPhone SpringBoard[12335] : Application 'UIKitApplication:com.ideashower.ReadItLaterPro[0x33c1]' exited abnormally via signal. Apr 30 11:17:59 iPhone SpringBoard[12335] : Application '(null)' exited for an unknown reason. Apr 30 11:18:03 iPhone kernel[0] : AppleFairplayTextCrypterSession::fairplayOpen() failed, error -42028 Apr 30 11:18:03 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.united.UnitedCustomerFacingIPhone[0x620b][14065]) : Service exited due to signal: Killed: 9 Apr 30 11:18:03 iPhone assertiond[12347] : Unable to obtain a task name port right for pid 14065: (os/kern) failure (5) Apr 30 11:18:03 iPhone SpringBoard[12335] : Unable to register for exec notifications: No such process Apr 30 11:18:03 iPhone SpringBoard[12335] : Unable to obtain a task name port right for pid 14065: (os/kern) failure (5) Apr 30 11:18:03 iPhone SpringBoard[12335] : Unable to obtain a task name port right for Apr 30 11:18:03 iPhone SpringBoard[12335] : Application 'UIKitApplication:com.united.UnitedCustomerFacingIPhone[0x620b]' exited abnormally via signal. Apr 30 11:18:03 iPhone SpringBoard[12335] : Application '(null)' exited for an unknown reason. Apr 30 11:18:07 iPhone syslogd[12297] : ASL Sender Statistics Apr 30 11:18:07 iPhone kernel[0] : xpcproxy[14066] Container: /private/var/mobile/Containers/Data/Application/C1AEAFEE-6FDD-46F1-BBAB-F3E345D35EB9 (sandbox) Apr 30 11:18:07 iPhone kernel[0] : AppleFairplayTextCrypterSession::fairplayOpen() failed, error -42028 Apr 30 11:18:07 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.mlb.AtBatUniversal[0x37dc][14066]) : Service exited due to signal: Trace/BPT trap: 5 Apr 30 11:18:07 iPhone ReportCrash[14067] : Formulating report for corpse[14066] AtBat.Full Apr 30 11:18:07 iPhone SpringBoard[12335] : Application 'UIKitApplication:com.mlb.AtBatUniversal[0x37dc]' crashed. Apr 30 11:18:07 iPhone ReportCrash[14067] : Saved type '109(109_AtBat.Full)' report (3 of max 25) at /var/mobile/Library/Logs/CrashReporter/AtBat.Full-2016-04-30-111807.ips ``` The big thing that points out to me is this line: ``` Apr 30 11:18:07 iPhone kernel[0] : AppleFairplayTextCrypterSession::fairplayOpen() failed, error -42028 ``` Fairplay is the DRM Apple uses for App Store (and iTunes purchases in general). Something is going wrong with the DRM on these apps causing them to fail to launch. Confidence inspiring! This is as far as my investigation has taken me at this point. I don’t really have a theory *what* is causing this. My first thought was it was caused by an app being updated, but the United app hadn’t been updated in a while and it was crashing for no reason. I am mostly writing this up because when I was trying to defend that this was an iOS issue and not a bug in our code, I really didn’t have much of a source to cite other than the few tweets I remembered seeing from other folks running into the same issue. I’d love to know more if you have any theories. Apple folks, have a radar: rdar://26032481 ### GoogleCast, GitHub, Git-LFS, and You URL: https://www.justinw.me/blog/googlecast-github-git-lfs-and-you/ Last updated: 2017-03-20T23:04:35.000Z My main project these days bundles Google’s GoogleCast / Chromecast framework in it to allow users to stream video content from their iOS devices to Google’s little streaming sticks. Overall, I like the Chromecast devices. They seem to work a bit more reliably than Airplay in a lot of ways. What I don’t like, however, is the framework that Google provides for iOS to enable casting support in third-party apps. We have had the framework in our git repository for the last year without much issue. Only recently did we try to update to the latest version (2.10.4 as of this writing) that the issues started to really pop up. Seemingly overnight, the GoogleCast framework ballooned from 17MB to 439MB. That is not a typo. It really did grow 25x in size. I opened [an issue](https://code.google.com/p/google-cast-sdk/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sort=&id=824&ref=justinw.me) and Google is quick to blame Bitcode for the issue, though I’ve never seen a framework grow 25x. So our app is now a little bigger because we have this giant framework embedded in our project. No big deal, right? The problem is that we use GitHub for our version control system and it has a hard limit of 100MB for a file size that can be pushed to a repository. If it’s over that 100MB size, the file is rejected and GitHub suggests adding it to GitHub’s [Large File Storage](https://git-lfs.github.com/?ref=justinw.me) system. Git-LFS is an extension to the Git protocol that replaces giant files like a 439MB iOS framework with a pointer to a location on a remote storage location that is better designed to house such large files (think Amazon S3). Easy fix, I thought. I installed the Git-LFS extensions and tried adding the GoogleCast framework to LFS, but was met with an error: ![GitHub LFS WTF](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/Screen-Shot-2016-04-25-at-5.54.54-PM.png) Long story short, to get a file on GitHub LFS it has to have **zero history** in your repository. Otherwise, the pre-push hook won’t recognize it as an LFS file and you’ll be in a jam. GitHub has a [page](https://help.github.com/articles/remove-sensitive-data/?ref=justinw.me) that explains this and how to get around it. It took a bit of trial and error for me still to get GoogleCast to behave with Git LFS. These are the steps I went through in Terminal: ### 1\. Analyze The Damage Using gitk I was able to see how far back and how many commits were around with the GoogleCast Framework as a part of it. To get gitk working on El Capitan, however, you need to update the copy of tcl through Homebrew. ``` brew cask install tcl gitk --all -- External/GoogleCast.framework ``` In the output you should see the commits that include the GoogleCast framework and its children inside. ### Sweep It All Away Here comes the painful part. You’re going to need to go through and remove *every* reference of the file in your repository history on every branch and tag. You’ll then need to force push the changes to your repo, which is always a little scary. There’s two ways to do this: `git filter-branch` or a third-party tool called [BFG Repo Cleaner](https://rtyley.github.io/bfg-repo-cleaner/?ref=justinw.me). The BFG is supposed to be faster, but I was unable to get it to successfully work for what I was trying to accomplish, so I went the slow and time consuming route. You’ll need to repeat this on every branch you have open in your repository. Grab a drink: ``` git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch External/GoogleCast.framework' --prune-empty --tag-name-filter cat -- --all ``` This will go through and remove the GoogleCast framework files from every commit in your history. After you’ve finished cleaning up a branch you can run gitk again with this command to ensure it’s no longer in your history: ``` gitk -- External/GoogleCast.framework ``` ### Clean Up After this, it’s probably worth running the Git garbage collector. ``` git gc --aggressive --prune=now ``` And finally, you’ll want to force push all your changes back to your repository. ``` git push origin --force --all; git push origin --force --tags ``` ### On to LFS Now that we’ve got a cleaned up copy of the repository on GitHub, we can finally start re-adding the GoogleCast framework back to your repo and making sure its under LFS. Go ahead and add a fresh copy of the GoogleCast `framework` and `xcassets` files to where you previously were storing them. Make sure your app builds at this point just for safety. First we need to install the Git LFS pre-push hook in our repository: ``` git lfs install ``` Next, we’ll go ahead and tell LFS about our oversized GoogleCast files. ``` git lfs track External/GoogleCast.framework/Versions/A/GoogleCast git lfs track External/GoogleCast.framework/Versions/Current/GoogleCast git lfs track External/GoogleCast.framework/GoogleCast ``` You’ll notice I am doing this three times. For some reason only known to Google they are bundling the same 139 MB binary three times in their “framework” so you have to make sure you hit all three instances of it. Commit all your changes, including the new `.gitattributes` file additions that were made to track the new oversized GoogleCast files. You should now be able to push your changes to your `master` or `develop` branch and have the oversized files added to GitHub’s LFS system. Finally you can go back to getting actual work done. ### Rock-Paper-Scissors URL: https://www.justinw.me/blog/rock-paper-scissors/ Last updated: 2016-02-28T21:38:22.000Z I can’t say enough good things about this [Android commercial](https://twitter.com/android/status/704018601494220800?ref=justinw.me) ad that played a few times during the Oscars. ### Stephen Wilkes's Day to Night Photography URL: https://www.justinw.me/blog/stephen-wilkess-day-to-night-photography/ Last updated: 2016-02-24T12:03:41.000Z [Stephen Wilkes](http://www.stephenwilkes.com/fine-art/day-to-night/5408defb-b7c0-4d9c-b89d-25740a627753?ref=justinw.me) is a professional photographer who gave a talk at TED last week on his day to night photography project. Wilkes sets up at a location for an entire day or more capturing the same shot repeatedly. He then heads back into his studio and stitches the moments together into single photograph that captures the activity of that location over a single day. The photos are incredibly mesmerizing. I probably will have more to say about my experience at TED. [Probably](https://brooksreview.net/2016/02/we-are-now-at-peak-ted/?ref=justinw.me). ### @Justin Bieber Explains Twitter's Difficulties URL: https://www.justinw.me/blog/justin-bieber-explains-twitters-difficulties/ Last updated: 2017-03-20T22:56:08.000Z In case you weren’t aware, [Twitter is doomed](http://www.theverge.com/2016/1/26/10833024/is-twitter-doomed?ref=justinw.me)! Like, [Apple levels of doomed](https://www.google.com/?gws%5Frd=ssl&ref=justinw.me#q=%22apple+is+doomed%22+site:daringfireball.net). User growth has been stalled for years. Advertising isn’t [picking up](https://www.theinformation.com/articles/why-twitter-is-hard-to-buy?ref=justinw.me) nearly as well as they’d hoped. And the stock price is trading at less than my high school allowance because Wall Street is losing faith. I would personally prefer they regain their faith in Twitter, because I bought the stock at $45\. I’d like to recoup that investment. Ever since [Jack](https://twitter.com/jack?ref=justinw.me) came back to save his flailing company, people have been waiting for him to sprinkle pixie dust on Market St and suddenly solve all of Twitter’s problems. Sadly, not even Steve Jobs’s spiritual son can perform this kind of magic in just a few months. There have been a few different product launches since last fall and another round of #ExecutiveShuffle, but the ultimate problems of Twitter still remain. [Twitter is too damn hard](http://www.theverge.com/2016/1/27/10836466/walt-mossberg-twitter-is-too-hard-to-use?ref=justinw.me). Not for you, the fine person reading this article. Not for me certainly. I’ve been on it for a decade this July. But for those other people out there in the world? The “normals”? They don’t get it. How do I know? I am [@justin](https://twitter.com/justin?ref=justinw.me) on Twitter and this has been my mentions tab for at least half a decade. [![My Twitter Mentions Nightmare](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/fml_twitter.jpg)](https://www.justinw.me/2016/02/12/justin-bieber-explains-twitters-difficulties/fml%5Ftwitter/) You’ll notice that most of these tweets aren’t necessarily for me. I am constantly inundated with tweets to “@Justin Bieber”, “@Justin Trudeau”, “@Justin Timberlake”, and maybe once even “@Justin Guarini.” The examples above are just a few random people who were confused while tweeting. It gets worse when someone like TMZ (3.69 million followers) tweets about “@Justin Bieber” instead of “@JustinBieber” and I can’t use Twitter for a few days without wanting to switch back to Pownce. When Bieber himself tweets I am well aware, because my mentions stream blows up even worse than this. More than annoying, it can also be somewhat sad. I’ve seen teen girls confess their undying love to Bieber. I know when they cry because he wore a green shirt. I’ve even seen people threaten to cut themselves if he doesn’t reply to them. Am I supposed to reply to that tweet? It was sent to me (@justin bieber), and not Bieber (@justinbieber), after all. I ultimately end up spending an inordinate amount of time blocking these accounts to try to keep my mentions at some sort of sane level. At last check, I’ve blocked well over 60,000 accounts. That’s at least 1/3 of Twitter’s 4th quarter monthly active users! Because of this, I don’t really enjoy Twitter that much anymore. This is also why I don’t use it nearly as much as I used to. It’s bad enough that the culture of Twitter is centered around [abuse](http://www.theverge.com/2015/12/29/10684616/twitter-harassment-abuse-rules?ref=justinw.me), [actually-ing](https://twitter.com/Rachelskirts/status/661745152940208128?ref=justinw.me) people, and making it way too easy for dumb people to [try to sound smart](http://twitter.com/paulg?ref=justinw.me). Add on top of it that most people don’t understand the product and I have to spend part of my life doing manual labor trying to make the service usable for me. No better way to spend a Saturday night than Twitter Block Button and Chill. The fundamental tenents of Twitter are obviously broken for most people and they have been for years. Based on the currently super confusing interface the product offers, Twitter’s conversational nature lets me gauge where Bieber is still most popular (South America, Southeast Asia) and how Justin Trudeau is doing up in Canada (pretty great!). The product does not enable people to successfully talk to their favorite celebrities or #brands. Instead they end up talking to an iOS developer in Colorado who really doesn’t want to know them. Why would I want to keep using a product that enables this exactly? Twitter the the company seems aware of this based on their last [shareholder letter](http://files.shareholder.com/downloads/AMDA-2F526X/1490875108x0x874459/8A4D1A1D-D184-4AFE-9AC1-F880C5EA06F1/Q415%5FShareholder%5FLetter.pdf?ref=justinw.me). > We are going to fix the broken windows and confusing parts, like the .@name syntax and @reply rules, that we know inhibit usage and drive people away. We’re going to improve the timeline to make sure you see the best Tweets, while preserving the timeliness we are known for. The timeline improvement we announced just this morning has grown usage across the board (including Tweeting and Retweeting). We’re going to improve onboarding flows to make sure you easily find both your contacts and your interests. We’re going to make Tweeting faster while making Tweets more expressive with both text and visual media. We’re going to help people come together around a particular topic, such as our @NBA timelines experiences. Relentlessly refining Twitter will enable more people to get more out of Twitter faster. Whether this is just lip service to shareholders to try and quell another mass sell-off after a disappointing quarter, or something actually will change remains to be seen. I personally welcome the algorithmic timeline, because I no longer check Twitter more than once a day or so. I don’t want to see every tweet from every person I follow and since my mentions are usually a dumpster fire I don’t have much to look for in there either. If @jack is looking for a fuzzy metric to determine whether Twitter is getting easier to use, take a peek at my mentions every couple months and gauge my misery level. The happier I am, the easier Twitter is becoming to use most likely. ### Using Operator in Xcode URL: https://www.justinw.me/blog/using-operator-in-xcode/ Last updated: 2017-03-20T23:01:47.000Z ![Operator in a Playground](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/OperatorPlayground.png) For the longest time I have been using [Meslo](https://github.com/andreberg/Meslo-Font?ref=justinw.me) as my monospaced font of choice in Xcode, Atom, and Terminal. I couldn’t resist the urge to give Hoefler & Co’s [Operator](http://www.typography.com/fonts/operator/overview/?ref=justinw.me) release as a replacement. I don’t really have issue spending money on tools that make me more productive in my day to day work. I never truly considered buying a font for development work though. For $179, I could have spent that money on at least 150 iOS apps! After rolling my eyes at the absurdity of that thought, I transferred $179 from my bank account to Mr Hoefler’s, installed the font, and updated my Xcode theme to use it at 16pt universally. My quick verdict? I like it. I don’t starch my plaid shirts nearly enough to offer a critique on the baselines and kerning of a font. I’ll leave that to the designers. But, it’s pleasant on my eyes and I can easily tell the difference between a capital *O* and a zero. Is a new font going to make you more productive? Doubtful, unless you’re using something like Papyrus. I like it though, and you might too. [Check out Operator from Hoefler & Co](http://www.typography.com/fonts/operator/overview/?ref=justinw.me) ### @carpeaqua on Twitter URL: https://www.justinw.me/blog/carpeaqua-on-twitter/ Last updated: 2016-02-02T10:59:56.000Z A short note to let you know that if [RSS](https://feedpress.me/carpeaqua?ref=justinw.me) isn’t your thing, you can now get updated on new posts to this site via Twitter. [Follow @carpeaqua on Twitter.](https://twitter.com/?ref=justinw.me) I’ll eventually get around to putting out an [email version](https://brooksreview.net/2015/12/newsletters/?ref=justinw.me) of the site as well, but that’s not a short-term goal. ### The Gang of Four URL: https://www.justinw.me/blog/the-gang-of-four/ Last updated: 2016-01-30T18:13:43.000Z [Scott Galloway](https://www.youtube.com/watch?v=jfjg0kGQFBY&ref=justinw.me): This is probably one of the most engaging and interesting talks I’ve sat through. If you want to have a really good idea of the size of business the Gang of Four (Facebook, Amazon, Apple, and Google) are doing I doubt you’re going to find a better resource. There’s so many quotable things in it as well. On their growth as a media company: > Advertising is becoming a tax only poor people pay. On generating profits and why Amazon doesn’t: > Profits are heroin to investors. They love them. They get addicted to them. And when you take them away, they get very irritable. We truly are living in Larry, Mark, Jeff, and Tim’s world. ### DigitalOcean Migration URL: https://www.justinw.me/blog/digitalocean-migration/ Last updated: 2016-01-30T16:34:34.000Z If you can read this, then everything has moved successfully. I’m now hosting the site on a server at [DigitalOcean](https://www.digitalocean.com/?refcode=08745ff7fad4&ref=justinw.me) rather than on Azure. Why? Predominantly performance. Azure is notoriously slow when it comes to MySQL, apparently because it’s outsourcing the database to a third-party company rather than hosting it themselves. I was faced with either running my own virtual machine instance of MySQL myself or moving somewhere else. I used that as my opportunity to evaluate other options. I settled on [DigitalOcean](https://www.digitalocean.com/?refcode=08745ff7fad4&ref=justinw.me) based off referrals from friends, but also their one-click WordPress install and ample documentation. I haven’t run my own VPS in a while, so I was a bit rusty in remembering all the nooks and crannies I needed to cover to secure a Linux system. Thankfully, there are plenty of first-party tutorials provided. - [One-Click Install WordPress on Ubuntu 14.04 with DigitalOcean](https://www.digitalocean.com/community/tutorials/one-click-install-wordpress-on-ubuntu-14-04-with-digitalocean?ref=justinw.me) - [How To Install an SSL Certificate from a Commercial Certificate Authority](https://www.digitalocean.com/community/tutorials/how-to-install-an-ssl-certificate-from-a-commercial-certificate-authority?ref=justinw.me) - [How To Configure Secure Updates and Installations in WordPress on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-configure-secure-updates-and-installations-in-wordpress-on-ubuntu?ref=justinw.me) - [Initial Server Setup with Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04?ref=justinw.me) - [Additional Recommended Steps for New Ubuntu 14.04 Servers](https://www.digitalocean.com/community/tutorials/additional-recommended-steps-for-new-ubuntu-14-04-servers?ref=justinw.me) Hopefully the speed increase of carpeaqua will motivate me to write more than I do. Every time I sat down to write something before, I’d get annoyed at how long it was taking for a request to process. Now things are instantaneous. I’m running out of excuses. If you want to check out DigitalOcean, [click or tap on this referral link](https://www.digitalocean.com/?refcode=08745ff7fad4&ref=justinw.me). You get $10 in credit and I get a little kickback too. ### My iOS Development Kit - January 2016 URL: https://www.justinw.me/blog/my-ios-development-kit-january-2016/ Last updated: 2016-01-14T10:22:07.000Z If you surveyed me annually, you’d likely find that my toolkit for building Mac and iOS applications changes a bit year over year. This year, however, the changes seem to be even bigger than before. With Swift 2’s release, I made the full transition from Objective-C to Apple’s new language du jour. The transition has not been without growing pains (hello, constantly crashing debugger!), but overall I am writing better, more idiomatic code. And this is coming from someone who spent the last decade happily writing Objective-C. Since I’m making the transition, I’ve also used it as an opportunity to re-evaluate the third-party libraries I am using in my client applications. I tend to have a fairly reserved stance on third-party dependencies. I am not vehemently against them like some, but I also don’t want to turn my app into a Lego set where I’m merely piecing together library after library that I don’t fully understand. The tools below are things I have used and successfully deployed to production. ### Carthage In the Dependency Wars, I have tried them all. I started with vanilla Git submodules, and did a brief tour of duty with Cocoapods. Submodules didn’t offer nearly enough wins for the management overhead I seem to have. Cocoapods worked for the most part, but I have fundamental disagreements with how they package and build their products. [Carthage](https://github.com/Carthage/Carthage?ref=justinw.me) seemed like a happy medium for me. I get the wins of using some sort of dependency management system, and it sticks with using the shared Xcode schemes that are bundled with the project itself. ### RxSwift This is the most recent addition to my list, but it’s one I’m growing to enjoy most. Functional programming is what all the hipster developers are doing these days, so I am trying to wrap my head around it. I may not understand why they wear wood framed glasses, tight jeans, and so much flannel, but I am starting to come around to the idea of building things functionally. [RxSwift](https://github.com/ReactiveX/RxSwift?ref=justinw.me) is from the same folks who do Rx.net, RxJava, and a host of other implementations, which may or may not be appealing to you. When learning something new, documentation is important and I’ve found the docs for RxSwift to be pretty well done. There’s still cases where the generic ReactiveX documents are “TBD” in terms of RxSwift, but having the header docs fills in many of those gaps. My biggest complaint with RxSwift isn’t so much a complaint with the library as it is with the idea of functional programming. It is a major change in how you think, so I spent most of my first few weeks re-reading docs, cursing and trying to understand what was actually happening. Eventually it will click, and when it does it’s a really nice way to build iOS libraries. RxSwift includes a library for making UIKit more reactive, but I’m shying away from it presently. Right now I have limited RxSwift mostly to integration with network modules I build. I reserve the right to change my mind about this in the future, but right now delegates and data sources don’t bother me that much. ### SwiftyJSON It is a toss-up whether there are more Swift JSON parsing libraries or Republican presidential candidates in the US. I don’t really have anything negative to say about [SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON?ref=justinw.me). It works and saves me from writing JSON parsing code over and over again. You can likely choose one of the other 107 libraries and it will do pretty much the same thing: just like a Republican presidential candidate! ### Realm I have used Core Data since it was introduced way back in OS X 10.4\. I have never loved Core Data, but it has always gotten the job done and proved better than raw SQLite queries (I’m that much of a masochist). I interviewed the [Realm](http://realm.io/?ref=justinw.me) folks way back when on my [CocoaRadio podcast](http://justinw.me/cocoaradio?ref=justinw.me) and found it to be an interesting project. I just didn’t have anything to implement it in since I was already successfully deploying Core Data in my existing client projects. With a new project that ramped up early last year, I decided to give it a shot. I’m having a hard time convincing myself to go back to Core Data for anything right now. Core Data has always felt bloated to me, especially when trying to bring up the stack in an application. I also have many battle wounds to show for Core Data threading issues over the years. All things of the past with Realm. I can query the same Realm from any thread and bringing up a new one is at most three lines of code. Apple is working to improve Core Data each year, but I’m starting to believe they should just reboot the framework like a comic book movie and start over. Or keep it as is, and I’ll keep using Realm. ### Aspen I was a longtime user of CocoaLumberjack, but was running into a issues when starting to migrate an existing client application to use Swift in some places. I also started having issues where there updates to the library would just fail to work in the application without me spending a few hours each release debugging things. I decided to use that as a chance to write my own clean room logging implementation that does everything I need: which isn’t that much. I call it [Aspen](https://github.com/justin/Aspen?ref=justinw.me), and you probably **shouldn’t** use it. It works for me and is deployed on millions of iOS devices, but it’s also something that I don’t really see growing beyond the scope of the project as is. I’d like to add log rolling and ASL support, but after that there’s not much else I need in a logging framework. If your needs are greater, any other solution will probably work better for you. ### Fastlane The newest piece of my kit is [Fastlane](https://fastlane.tools/?ref=justinw.me), a suite of Ruby scripts from Twitter’s development folks. I am using Fastlane to help run unit tests from the command line, build releases and automatically upload them to TestFlight. The suite can do a lot more, but my needs are fairly simple. The next piece to my Fastlane puzzle will be getting some sort of continuous integration component. Maybe next year. ### Plain Old NSURLSession You’ll notice that I’m not using a networking library like AlamoFire or similar. For most of the projects I am working on, I don’t need the extra overhead those libraries offer me. I tend to put each network request in its own Swift class and make them return an RxSwift *Observable*. I then have a parent class that will vend those request classes out. I may write about this more in the future, if enough people ask nicely. ### The Chicken or the iPad Pro URL: https://www.justinw.me/blog/the-chicken-or-the-ipad-pro/ Last updated: 2017-03-20T22:57:04.000Z ![iPad-Pro-Pencil](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/iPadPro_Pencil-Hand-PRINT.jpeg) The iPad Pro went on sale this week. I picked one up at my local store, though my Pencil and keyboard case won’t ship for another few weeks. I haven’t been this fascinated by a new device since the original iPad was released back in 2010\. That is the device that got me re-energized to build my own iOS products after frustrations with the original incarnations of the iPhone App Store. My mind has been racing for weeks about ideas for this thing. There’s just one problem: I don’t understand why the device exists. I use my iPad mini 4 every single day in the morning and evening as my primary method for reading, watching TV in bed, and sniping at people on Twitter. I keep no work-related apps on it. It is my personal device that is designed to let me focus on things that don’t involve my day-to-day duties as a software developer. According to interviews with Tim Cook over the last few days, Apple is positing the iPad Pro as a full-on replacement for a PC or Mac for [“many, many people.”](http://www.telegraph.co.uk/technology/apple/11984806/Apples-Tim-Cook-declares-the-end-of-the-PC-and-hints-at-new-medical-product.html?ref=justinw.me) > “I think if you’re looking at a PC, why would you buy a PC anymore? No really, why would you buy one?” > > “Yes, the iPad Pro is a replacement for a notebook or a desktop for many, many people. They will start using it and conclude they no longer need to use anything else, other than their phones.” Apple wants to cast the larger iPad as [where the puck is going](http://www.macleans.ca/economy/business/why-business-people-wont-stop-using-that-gretzky-quote/?ref=justinw.me) when it comes to knowledge workers. The days of carrying around a laptop or having an iMac or Dell on your desk to do your job are a thing of the past with the powerful iPad Pro. No doubt if you are someone at the executive level who spends most of his or her time in email or browsing the web, the iPad Pro will likely be a great product. With anyone outside of that email and browser bubble, I struggle with seeing how the device fits without a tanker ship of compromises. ### The Legacy Problem I went home a few weeks ago, and my brother showed me his new MacBook he purchased for his online classes. His day job is managing a retail store, so his computing needs aren’t that heavy. An iPad sounds like it could be a great fit for him, right? Sadly, it was a nonstarter when he found out that the course required Silverlight in the browser. I’ve looked at this software. All of it could be rebuilt on iOS and likely offer a better experience for students. Apple has provided all the APIs you need. What’s the financial incentive, however? iPad sales have been sluggish the last few quarters, and the iPad Pro has a giant question mark over it as to whether or not the general public will embrace it. This isn’t a new problem. Apple faced something similar with the transition from MacOS to OS X in the late ‘90s and early 2000s. The biggest difference between then and now is that OS X isn’t going anywhere. Convincing someone who is getting by building web apps in Silverlight they should scrap all their existing code and build something natively on the iPad is a much harder sell than telling Adobe they need to embrace Carbon to get Photoshop running on Mac OS X. ### The Ecosystem Problem The majority of productivity apps that I have on my iPad Pro fall into three camps: first-party tools from Apple, a productivity suite from Microsoft, or $5 apps from hobbyist developers. This is likely where you expect to read the same excuses about app sustainability and the lack of trials and upgrade pricing on the App Store. I’ll spare you rehashing those arguments for the millionth time. The overarching reality is that, like any business, selling software is hard. The mythical App Store — where just building something means you will be swimming in a pool of money — still hasn’t surfaced after seven years of people promising it was coming. What has shown up, however, is a world where the top grossing apps on the store are free-to-play games from two or three major game publishers. Game of War and Candy Crush have dominated the top grossing chart of the App Store for years at this point. They are likely raking in six figures (or more) a day just from the App Store. Add Google Play on to that, and now you know who actually has the swimming pool of money. Compare that to the podcast app market, which is now switching to the tip cup model — used by panhandlers around the world for decades. These are “premium” apps that used to sell for the outrageous price of $4.99 and now have now switched to the “pay if you can be bothered” model because getting people to pay for software today is an even more difficult proposition than it was a decade ago. Trials and upgrades aren’t going to solve the problem of developers shooting themselves in the foot or continuing to refuse to understand fundamental business concepts like marketing. As a thought exercise recommend your favorite paid app to someone that is not a nerd. I have friends who are allergic to exercise that will run for the first time ever to avoid paying even $.99 for something on their phone. You’re telling me those folks are going to spend $39.99, even if the app can make them more organized and likely help them do their job better? Omni makes it work, though. They have dozens of employees and don’t sell their software at bargain basement prices. The sad reality is there aren’t enough Omnis in the ecosystem right now to make the iPad Pro a viable productivity platform for anyone but those executives, retired folks, and [masochist bloggers](https://www.macstories.net/stories/ipad-pro-review/?ref=justinw.me) who jump through more hoops than a circus elephant to use an iPad instead of a Mac. The app ecosystem isn’t the only problem. As I mentioned [previously](https://www.justinw.me/on-the-ipad-pro-and-the-constraints-of-ios/), iOS looks somewhat out of place on the iPad Pro. Visual oddities like the amount of spacing between app icons on a 13” screen seem like something that has to be resolved in iOS 10 with a re-imagined home screen of some sort. Split-screen support doesn’t solve any of the interconnectivity problems apps still have where it’s not a trivial task to move a chart or spreadsheet from one document and insert it in another. These are problems that a mouse and drag-and-drop solved decades ago but are still a chore to do on iOS. New features like extensions, app groups, and enhanced URL scheme support have helped make iOS a better overall platform. Having links from Twitter open directly in the Twitter app versus Safari is a great experience. A lot of those improvements to iOS are related to helping individual apps be more extensible versus enabling Vendor A’s app to talk to Vendor B’s in a sane way. To improve this sharing, iOS 8 added the concept of [document providers](https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/DocumentPickerProgrammingGuide/Introduction/Introduction.html?ref=justinw.me). The feature has been available for nearly a year, and I can count on my left hand the number of apps I’ve used that have implemented it in a meaningful way. Even my favorite Omni apps consider document providers “beta” in favor of their own OmniPresence sync solution. The apps that I have used a document picker with haven’t exactly been easy to use either. Most have copied the file from the document picker into their own app sandbox, which now gives me two different versions of a document in two different places. The future! Smart people have worked out ways around a lot of these issues using apps like [Workflow](https://workflow.is/?ref=justinw.me) or writing scripts in apps like [Editorial](http://omz-software.com/editorial/?ref=justinw.me). To argue that writing scripts is a viable solution for anyone but the hairiest of neckbeards is insane. I have no doubt Apple is aware of iOS’s limitations, and presumably working on solutions for it. As of today, however, I can’t imagine doing more than the most basic things on iOS without feeling like I am paddling upstream. ### Why Does the iPad Pro Exist? Like the Apple Watch, I’m having a hard time understanding why the iPad Pro exists right now. In a lot of ways, it feels like they threw this out as a reactionary tactic to slumping sales to see what happens. Each new platform or device Apple releases is met with the same “We can’t wait to see what you develop for this” message to developers. With the iPad Pro, that invitation is feeling more hollow than ever, given the state of everything I’ve outlined above. It’s possible that I’m overanalyzing all of this and the target is really schools or enterprise deployments. Selling 50,000 iPad Pro tablets to someone like IBM so they can load their own in-house software on the device makes a lot of sense. I’m fine with the fact that I will always be a “Mac person.” I build software for a living, so I am someone who will likely always need all that OS X affords me to do my job. It’s for people like my brother, who just dropped nearly $2,000 on that new MacBook just for his online coursework, that I want to see something like an iPad Pro succeed — and become what technology is for the majority of people. With all the legacy software out there, the lack of financial incentive to rebuild it for a new platform, and iOS’s current limitations, I am hesitant to say that is going to happen anytime soon. *P.S. I wrote and published this on my 27” iMac with 32GB of RAM, a 1TB SSD, and a 4GB GPU.* ### "Despite Its Flaws . . ." URL: https://www.justinw.me/blog/despite-its-flaws/ Last updated: 2015-11-02T06:32:21.000Z [![appletv_v2015](https://i1.wp.com/104.236.158.40/wp-content/uploads/2015/11/appletv_v2015.jpg?resize=1024%2C702)](https://i1.wp.com/104.236.158.40/wp-content/uploads/2015/11/appletv%5Fv2015.jpg?ref=justinw.me) > . . . I like Apple Music. It works for me. > > . . . the Apple Watch is pretty neat. I wear it daily. > > . . . the new Apple TV is pretty good. This is how I’ve described Apple’s three new products released this year when asked. I like them, but I’m hesitant to recommend others buy them because of frustrating flaws or the absense of essential features. If you ask me to describe my iPhone 6s Plus, iPad mini 4, or Retina 5K iMac, I have nothing but gushing praise. Admittedly, they are more mature products, but I’d also argue my review of the original iPhone and iPad was much more positive than my reviews of any “Version One” Apple has put out this year. The original iPhone not only changed the industry, but it changed my life — from the first day. The original iPad showed me the future of computing. Even if I only use my iPad for watching video and reading, I use it for hours a day. And the iMac and OS X are so mature at this point, niggling bugs are really all I can complain about. So what’s changed from those products to these new ones? I refuse to believe or use the “Steve Jobs” excuse. Apple is filled with brilliant people at all levels of the organizational chart. You don’t become the biggest corporation in the world being run by dummies. I’d entertain the idea that Apple is stretching itself too thin. Despite being the biggest company in the world, they have gone from a single platform (OS X) to managing six (OS X, iOS, tvOS, watchOS, iCloud, and CarPlay). Apple has always struck me as a company that does more with less, but even this amount of annual innovation seems like an insane amount of work for one company to do without more than a few hiccups along the way. My guess is our expectations for these products have grown exponentially from nearly a decade ago when Apple started really pressing the gas pedal on mobile and technology in general. The original iPhone was compared to a Blackberry or Nokia. The original iPad’s biggest competitor was a Windows PC Tablet. The only place I ever saw one of those was a university classroom. Compare that to Apple Music, running up against Spotify, which is really damn good. The Apple TV is competing against Roku, TiVo, Xfinity X1, and a variety of other incumbents. I’m really not sure who or what the Apple Watch is competing against. FitBit? Android Wear? Omega? > When I die, I want my eulogy to mention all the time I wasted manually entering secure passwords on the new Apple TV. > > — Justin Williams (@justin) [October 31, 2015](https://twitter.com/justin/status/660542111138250752?ref=justinw.me) When the bar is raised by existing competition, the flaws of a 1.0 product stick out far more than they did when you’re revolutionizing and changing a market that is either dormant or nonexistent. The piss-poor performance of apps on the Watch is hard to ignore. The clusterfuck of an interface that Apple Music has compared to Spotify is hard to justify. The lack of an update to the Remote app or Bluetooth Keyboard support on the Apple TV makes me curious how Apple prioritizes features; that truly seems like a glaring omission. The Watch, Music, and TV products will continue to evolve over the next few years and see continued improvement, but I can’t deny I’m longing for the days of an original Apple product putting my jaw on the floor and giving me zero hesitation recommending it to others. ### HTML5 Colorado — A Tribute to Alex King URL: https://www.justinw.me/blog/html5-colorado-a-tribute-to-alex-king/ Last updated: 2015-10-12T14:55:16.000Z > In tribute to Alex King, this is a re-released version of his geeky & meta tee. The HTML5 canvas code on the shirt draws a Colorado state flag. We think of it as a celebration of an amazing person and one of his many great creations. [See Alex model the original shirt himself](http://alexking.org/blog/2012/05/14/colorado-flag-web-geek-t-shirts?ref=justinw.me). I have the original blue shirt, and am wearing it today even. I’ve ordered a new one as well as a tribute to my friend. You might [consider purchasing one too](https://cottonbureau.com/products/html5-colorado-a-tribute-to-alex-king?ref=justinw.me). ### On the iPad Pro and the Constraints of iOS URL: https://www.justinw.me/blog/on-the-ipad-pro-and-the-constraints-of-ios/ Last updated: 2015-09-10T12:00:56.000Z In their current incarnations, I believe that Windows 10 is better suited to the Surface than iOS is to the iPad Pro. Now, with that quotable hot take out of the way, let me explain. I have every intention of dropping some serious coin on the highest end iPad Pro, keyboard, and a don’t-call-it-a-stylus Pencil this November. I use my iPad Air 2 every single day for reading my [Pocket](http://getpocket.com/?ref=justinw.me) queue, Kindle books, and watching video from a variety of different source apps. Occasionally I will even do some “real” work on it too. During the Apple event this week, the company brought on stage various partners to showcase apps they had built to take advantage of the hardware and accessories of the new iPad Pro. They showed someone annotating an email attachment and then sending it back (something I believe has never happened in the history of mankind outside of a technology demo). Microsoft came on stage to show how you can get business done with an iPad Pro and Office. Adobe showcased a few different apps for touching up photos. What was not highlighted nearly enough, however, is how awkward iOS looks on such a seemingly large device. > Can we all agree that iOS’ homescreen looks increasingly stupid? [http://t.co/Qur2Pjvbyg](http://t.co/Qur2Pjvbyg?ref=justinw.me) > > — 512pixels.net (@512px) [September 9, 2015](https://twitter.com/512px/status/641709512311767041?ref=justinw.me) This is a 13″ screen using the same grid of icons as its other iPad counterparts. On the Pro, however, there is so much space in between each icon that you could rush for a touchdown on every play. Compare this with the Surface 3 and Windows 10\. You can organize your apps on a full screen view that has its icons closer together and in grouped with a far better visual metaphor than a folder. Your most frequently used apps are surfaced (sorry) along the left edge of the screen as well. Is it more complex than iOS? Yeah, but I wouldn’t say it’s too complex to understand. Windows still has the same concept of press and hold to move icons around and swiping left and right to page between different parts of the screens. And we haven’t even started talking about the third-party ecosystem for the iPad. I can count the number of apps on my left hand that are thoughtfully designed for the iPad screen size. Most are, for lack of a better phrase, blown-up iPhone apps. Just this week, Twitter updated their iPad app to be exactly like the iPhone version but with a bit more padding on the edges to make up for the larger screen size. That’s fine for the iPad mini and mostly tolerable for the Air. On the iPad Pro? That’s approaching [clown shoes](https://www.google.com/search?q=bozo+clown+shoes&client=safari&rls=en&tbm=isch&tbo=u&source=univ&sa=X&ved=0CCEQsARqFQoTCPeExOmh7ccCFcGZgAodx%5FEDbA&biw=1240&bih=623) territory. A lot of this thinking is thanks to Apple and the invention of [size classes](https://www.justinw.me/2014/06/14/thinking-in-terms-of-ios-8-size-classes/) in iOS 8\. With size classes, you are able to more easily adapt your interface to work with a variety of different screen sizes and orientations. This is a great thing. I’m currently in the middle of converting a rather large legacy project from having two different interfaces (iPhone and iPad) to using a single storyboard and size classes. Most developers for whatever reason (time and/or money I presume) don’t bother thinking of the iPad beyond throwing their iPhone views into a split view and calling it a day. The majority of users are on the iPhone after all. The iPad has always been somewhat of an afterthought as a destination. Size classes help alleviate that since it’s so easy to now build universal apps, but that doesn’t mean you’re building an app that is going to feel at home on a 13″ tablet. It’ll feel bigger at least? You will not see any defense by me of Windows software, especially modern Windows apps designed for 8 and 10\. It’s also mostly hot garbage, and likely for all the same time and financial constraint reasons as the iPad. Software in this new app era is even harder than it used to be. Side-by-side apps, a new feature of iOS 9 can help with some of the multitasking issues that have always plagued the iPad. For instance, try writing a paper on an iPad using Pages while looking up research in Safari. There is a lot of double-tapping of the Home button to jump between apps. Now you can at least pin both of them side-by-side, which helps. It’s still fairly rudimentary, especially compared to the types of Window management you can achieve on OS X or Windows. On the iPhone this sort of limitation makes sense. You don’t need to run multiple apps side-by-side on a phone. On the iPad though, the window management story is not that simple. There has to be something better between the bare minimum features of iOS and the window management hell you can theoretically get into on a desktop. All of this so far and we aren’t even touching on the problems Apple and the iPad have as a software ecosystem. There’s been more than enough pixels spilt over how difficult it is to build a sustainable software business in today’s app economy where $4.99 is considered premium, trials are a thing of the past, and Apple keeps printing money off the back of Smurf Berries and other in-app purchases. The iPad Pro is a device that is begging for great third-party software from both large companies like Adobe and Apple, as well as the smaller guys like Gus at [Flying Meat](http://flyingmeat.com/?ref=justinw.me). A larger screen, keyboard case, and a Pencil aren’t going to solve those problems. You can’t have a Pro tablet without pro apps to go with it. There are a few great iPad apps out there, but most of them feel like minimum viable products at best. And for the record, I don’t think OS X on these devices is the answer. I want a forward-thinking, touch-powered device this size. The iPad Pro is close, but iOS is going to hold it back. iOS *could* be a great operating system for professional computing, but right now the iPad remains to me a great device that is being held back by its OS being primarily for phones. But, man. Imagine how fast the Kindle app is going to fly with 4GB of RAM! ### Achieving Zen With Auto Layout (2nd Edition) URL: https://www.justinw.me/blog/achieving-zen-with-auto-layout-2nd-edition/ Last updated: 2015-08-18T20:00:38.000Z Last year I released a book based on all my speaking engagements around Auto Layout called [Achieving Zen With Auto Layout](https://gumroad.com/l/autolayout?ref=justinw.me). The book was very well received when it was announced and it made me realize I enjoyed writing about technical topics again (with the absence of a publisher, everything is wonderful!). I’m pleased to announce that I’ve spent the last few months updating the book for a second edition. This new edition of the book contains a ton of new content and converted nearly every piece of code from Objective-C to Swift. New topics covered include: - Working with size classes - Active and inactive constraints - Using layout guides effectively - Layout anchors - Debugging constraints using Swift (which is harder than it should be!) - Much, much more. If you’re new to iOS and Auto Layout or just want to learn about what’s new with layout in iOS 9 and El Capitan, this is the book for you. [Purchase Achieving Zen With Auto Layout.](https://gumroad.com/l/autolayout?ref=justinw.me) ### Auto Layout Debugging In Swift URL: https://www.justinw.me/blog/auto-layout-debugging-in-swift/ Last updated: 2015-07-07T20:00:25.000Z I’ve been working with Swift primarily over the last month. Recently I started working on a new custom interface piece that was having some rendering issues with its layout constraints. I went into LLDB and quickly realized that using private methods such as `_autolayoutTrace` and `recursiveDescription` to print out a hierarchy of my views and see ambiguity wasn’t possible out of the box. The reason for this is that when you’re in a Swift frame, LLDB is expecting you to call a Swift method it knows about. Since `_autolayoutTrace` and the like are private API, they don’t have any visibility to Swift. Safety! There are a few different ways to get around this. The first is straight in LLDB. You can use the expr command to tell LLDB that you are passing it a snippet of Objective-C code like so: ``` expr -l objc++ -o -- [[UIWindow keyWindow] _autolayoutTrace] ``` What we’re doing here is printing out our entire view hierarchy to the debugger. Frequently typing that long of a statement is obviously a bit tedious, so I tend to put it in my .lldbinit file. ``` command alias alt expr -l objc++ -O --[[UIWindow keyWindow] _autolayoutTrace] ``` Now you can just type alt and get the same output from the debugger. You’ll notice that I am throwing this out for the entire contents of the keyWindow. I haven’t been able to find a way to pinpoint it down a single property such as self.view, so if you have any feedback on that, please share! If you’re mixing Objective-C and Swift, you likely already have a bridging header. You can bridge add a category on UIView that exposes the recursiveDescription and \_autolayoutTrace methods to Swift. ``` #ifdef DEBUG @interface UIView (LayoutDebugging) #pragma clang push #pragma clang diagnostic ignored “-Wincomplete-implementation” - (id)recursiveDescription; - (id)_autolayoutTrace; #pragma clang pop @end #endif And the implementation file. #import “UIView+LayoutDebugging.h” #ifdef DEBUG @implementation UIView (LayoutDebugging) // Nothing to see here! @end #endif ``` Let’s walk through this. You’ll notice that I have the entire thing wrapped in an #ifdef DEBUG statement because I am working with private APIs that I presume the App Store usage checker would flag and reject your app against. With the #ifdef, I am saying that it should only be included on development builds. Apple will have no idea what abuses we are committing since it will never make it to the release builds! The other atrocity I am committing in this file is the use of #pragma clang diagnostic to tell the compiler to ignore any ‘uninmplemented method’ warnings that will pop-up from not being able to find an implementation for the two methods we defined in our category. Since they exist as private API, we don’t need to reimplement them. Now if you break in a Swift frame with LLDB and try to call self.view.\_autolayoutTrace() you’ll get an output you expected. Happy debugging! *If you’ve found this post useful, and want to learn more about how to best take advantage of Auto Layout in your OS X and iOS apps, be sure to purchase my new book Achieving Zen With Auto Layout* ### Repurposing the Titanic URL: https://www.justinw.me/blog/repurposing-the-titanic/ Last updated: 2014-10-24T19:00:20.000Z My biggest mistake with Glassboard was having blinders to the fact that the design decisions Sepia Labs made when building Glassboard would likely clash with mine. That doesn’t have anything to do with visual design. Instead, I’m referring to the platform architecture decisions they made as a funded startup, or spin-off, or whatever they were. The folks at Sepia had a parent company in Newsgator that was funding everything on Glassboard from the server costs, their salaries, and all the perks that go with that. More importantly, they were funding these things with the typical startup mentality in mind: get as many users as humanly possible and then worry about monetization later. Glassboard under Second Gear had a completely different mindset: try to convert our most passionate existing users to paid users, and then grow from that. I sadly failed at doing that. There are a variety of different reasons for that failure, but one of them is how much time I spent undoing some architectural decisions from their previous owner. That’s not a knock against Sepia or NewsGator. They built a great product. They just built it with a far different set of constraints than I had as the new owner funding this out of pocket. ### E-Mail One of the biggest was e-mail. Glassboard was sending over 150,000 emails a day when I took over. The SendGrid bill was $2400 in November of 2013, which is kind of crazy. I was able to cut that bill in half by negotiating a better rate to account for how much email we send, but it was still four figures a month. Sepia didn’t need to worry about justifying that cost because it was another feature in the checkbox to try and acquire users. Don’t want to use an app and get push notifications? We’ll send you an email every single time someone comments on your board posts! E-mail to Second Gear’s Glassboard is, however, a sunken cost because none of those costs were ever passed on to my customers. My thinking at the time was that I could convert enough users to premium accounts to fund the transactional email for everyone. In reality, that proved to not be the case. I spent far too long in that mindset. When I finally wised up and made transactional email a premium user feature, my costs dropped down to under $100 a month. It also pissed off more users than it converted, but that was to be expected. The lesson I learned is that people *wanted* those emails, but they didn’t want to pay for them. It was a nice-to-have thing, but not a must have. I wish I had learned that lesson $15,000 ago. ### Computing Costs The biggest project I undertook during my time with Glassboard was converting the entire backend to use computing resources more efficiently. There were three different cloud services that powered Glassboard: - Notifications Role: this handled dispatching push notifications, emails, and archive processing. It ran on 2 medium-sized cloud service instances. - Attachment Processor Role: this would take the videos users uploaded, compress them, and make them more mobile friendly. This ran on a single Large cloud service instance. Why I didn’t kill video on day 1 is beyond me. What a poor job on my part. - Glassboard Platform: This was the kitchen sink project. It ran the API, the web app, web hook processors, and pretty much everything else. It was 4 medium sized instances when I took it over (I may have the number wrong, but it was quite a few). I was able to get a few quick wins by enabling auto-scaling so that the instances would rise and fall based on usage patterns. It’s silly to pay for a ton of servers at 3AM on a Sunday when there’s not nearly enough users to justify the costs. The biggest issue is that the only way to scale Glassboard in that incarnation was to throw more hardware at it. I spent an ungodly amount of time converting the entire backend platform to use C#’s async-await pattern. I am fairly confident I touched every single file in the project. One does not merely convert one portion of their code to be asynchronous. It’s a rabbit hole that you keep going down until you reach the bottom. It was a lot of work, but once it was deployed I cut my server costs across the board **in half**. Of course, by the time I got to that point, it was too late. I cut costs on a product that wasn’t commercially viable. Oops! ### Lessons Learned Building products with a bootstrapped mentality is completely different than a startup mentality. When bootstrapped, every decision you make affects the bottom line, and that is a bottom line you care about from day one. Trying to convert a platform that wasn’t designed with that in mind proved to be too great of a challenge for me as the sole proprietor of Glassboard. Rather than focusing on improving the core Glassboard product, I spent most of my time trying to cut costs where possible to curb our losses. Would it have been more feasible if I had some help? Most likely, but I still don’t think that would have saved the platform. If I had a do-over, I think my first decision would have been to shut down the Glassboard service as it was in November of 2013 and relaunch it without any of the legacy user accounts or data. If you wanted to continue using the service under Second Gear, subscribe now. That would have lowered costs up front and allowed me a lot more runway and likely time to delay a lot of cost-cutting projects that took up most of my 2014\. Of course, there’s obvious tradeoffs in this decision too. Hindsight is a bitch. ### What Problem Are You Solving? URL: https://www.justinw.me/blog/what-problem-are-you-solving/ Last updated: 2014-10-16T19:00:11.000Z The worst day I had in my time with Glassboard came last month. It was becoming obvious that even with the latest round of changes to the business model and pricing schemes, things weren’t turning around as well as I had hoped. I had no beliefs that new pricing would be a magic bullet to solve all of the platform’s problems, but I did think it’d be more successful converting users than it was. In reality what happened is that rather than paying a small monthly or annual fee to continue using Glassboard as they were, more people opted to find another free alternative to move their group or business whether it be Slack, Google+ (lol really), or any of the 85,000 other alternatives on the market. Couple this with me having a pretty big crisis with a botched migration to a new push platform, and things weren’t going really well for me. This was the point I started to think about where to take Glassboard next. Rather than keep all those discussions internal to my brain, I emailed a variety of different people ranging from friends, colleagues, users, and other business owners. This is the email I sent them: *Have come to the realization that running Glassboard in its current state is not tenable financially, mentally, or physically.* *A lot of different problems with it as a product and not sure how to solve that. Mostly it feels like a niche product without a well defined audience.* *Any ideas on how to figure that stuff out or where to go with it? Trying to get a bunch of different opinions, because I’m honestly not sure what to do.* Most everyone responded back, and not much of the feedback was good in the “your platform is great! Keep going!” sense. Most people were scratching their heads just as much as I was about where to take this thing next. The best response I got fairly direct: who is the audience for your Glassboard and what problem do you solve for them? I didn’t have a good answer for either of those questions. Shit. ### Finding An Audience If the answer to “who is your product’s audience” is “anyone with an iPhone or Android device” you are likely screwed. One of the biggest things I have learned from the entire Glassboard experience is that ‘spray and pray’ audience targeting is something that isn’t likely to work. Glassboard’s marketing message has always been fairly generic from both its time as a Sepia Labs product and under my helm. The last marketing message was “Talk to your people”, with people being a pretty generic term meaning it could work for personal or corporate communications. There are very few collaboration products on the market that work well for both of those markets. I spent a good amount of time over the last few weeks looking at analytics data to try to understand who was currently paying for the service and trying to analyze each of the markets that was being served by Glassboard currently. I analyzed them by three different metrics: - **Audience size:** How many potential customers are there like this group? - **Likelihood they will pay:** Do they have money AND are they willing to part with it to solve the problem? - **Access to market:** How easy is it for you to market to these people and get them to pay you for it? My potential markets based on analytics and user interviews were families, small businesses (think Q Branch), medium-sized businesses (think OmniGroup), conferences, consumer ad hoc groups (a book club), and professional ad hoc groups (a beta test board or a cocoaheads meetup). Analysis said I should focus my efforts towards the professional ad hoc groups and medium sized businesses because they had a large audience, were likely to pay if Glassboard could solve an actual problem for them, and there weren’t too many gatekeepers preventing me access to marketing at them. ### Solving A Painful Problem The key to selling a product to a user (whether it be a consumer, business, or enterprise) is to offer a solution to a problem they are having. If you can make that problem less painful, people are willing to pay for it. For instance, an app like OmniOutliner is successful because it’s far easier to create complex outlines in it across platforms than it is using just plain text files. TextExpander makes good money because they help power users save keystrokes by automating repeatable strings of text. Glassboard? Well, I realized that Glassboard wasn’t really targeted at any specific group and it didn’t really solve any real sort of problem. Here are a few different ways I tried to explain the problems Glassboard solved: 1. It allows anyone with an iPhone or Android to communicate securely and privately. 2. It allows users to have threaded conversations rather than IRC-style chat lines. 3. It allows conference attendees to communicate with each other from their mobile devices. None of these are real painful problems. You can likely name a variety of different apps that can solve #1 and #3\. Threaded communications is nice, but it’s also proven to be far too niche and not really something people are willing to pay for. I realized that Glassboard in its current form is for all intents just yet another chat platform for iOS and Android. Yeah it had an audience, but not an audience that was willing to pay for it to stay around. It didn’t solve an actual problem better than any of the free alternatives out there, so people left rather than keeping the lights on. ### What Did We Learn? What lesson can you take from my failures? Take a look at your current product and ask yourself what problem it is solving that makes it stand out from the competition. Also, ask who has that problem and if you are reaching them as well as you could. If you are in a situation like me where you don’t have a good answer for either of those questions, you need to sit down and start answering some hard questions about where you take things next. In my case, the risks of shifting Glassboard towards where I thought it should go next were too high for me to take on. Every business and product is different. Hopefully you learn from my mistakes and can make an excellent (and successful) product. ### The Gamble URL: https://www.justinw.me/blog/the-gamble/ Last updated: 2014-10-10T19:00:01.000Z Last week I announced that Glassboard will be [going out of business](http://glassboard.wordpress.com/2014/10/10/glassboard-closing-down-november-1-2014/?ref=justinw.me) as of November 1, because I was unable to turn it into a profitable business. There are a lot of different things I want to cover eventually about the past year I’ve spent working on this thing. For one, it’s therapeutic to me to get it out of my head. Second, my hope is that people can learn something from my successes (yes, there were some) and failures (those too). I knew going in that Glassboard was a moonshot. I was in essence taking over a platform that was run by six people with stable salaries from a parent company and doing it by myself, while trying to shift what turned out to be the titanic away from the iceberg. Running any business, large or small, is mostly about managing risk. You want to invest in the things that will grow profits. Startup culture skews this in our industry, because venture capitalists are willing to assume near-term losses in favor of potential long-term riches, but for our purposes, let’s assume we are building a business like our parents made. The goal is to spend less than you are bringing in. I am a terrible Blackjack player, but I know enough to be able to play on a few hundred bucks and have some fun. If you’re under 12, you want to take another card, because you’re really not going to hurt yourself. If you’re over 12, you’ve got to start figuring out what cards have been dealt already from the deck and determine if its worth the risk of possibly busting or not getting a high enough count to beat the dealer. Despite being terrible at Blackjack, I play it fairly conservatively and don’t stray from those two rules too often. I try to run my businesses in the same way. Second Gear and Glassboard have always been small shops that are run with the intent of supporting me and if it grows beyond that, great. I knew the risk of taking on Glassboard up front would be how much money it was losing each month in sunken hosting costs (not including development and design time). I projected a few different scenarios for good, great, and ‘make it rain’ levels of growth to get the business out of the red and towards profitability. Despite cutting the monthly losses by 80% from the time I took over to today, I never fully got to that break even point and began to realize that getting there and beyond was going to require a lot more hard decisions and evaluation. So, how do you know when you’re done and it’s time to fold? When you start thinking about shutting things down, you’re done. There may be a Hail Mary out there that could possibly save the sinking ship, but my guess is that it will only prolong the inevitable. For me, I knew for sure last Thursday that I was done. I realized it was going to be another $60,000 or so to turn Glassboard into the product that I thought it could be eventually. There was no way I could do that emotionally, mentally, or financially. The risk was too big. I announced the next day I was cutting my losses and shutting the service down. Glassboard was a gamble that didn’t really pay off financially (no, mom. I am not losing the house), but it was still rewarding in a lot of other ways. Hopefully those will become apparent over the next few weeks as I dump all this out of my head. ### Auto Layout In iOS 8 - layoutDebuggingIdentifier URL: https://www.justinw.me/blog/auto-layout-in-ios-8-layoutdebuggingidentifier/ Last updated: 2014-08-27T19:00:14.000Z Another new identifier Apple added in iOS 8 is the private API property `_layoutDebuggingIdentifier` to `UIView` that you can use to clean up what is output in `_autolayoutTrace`. Since it is private API, you don’t want to ship with this code in because Apple will likely reject it, but for debugging purposes it can be mostly harmless. Mostly. There’s no easy way to set the `_layoutDebuggingIdentifier` identifier in a Storyboard or Xib, so we will have to add a bit of code to take advantage of it. To take advantage of this: 1. Open one of your view controllers. 2. Override `- (void)viewDidLoad` if you haven’t already. There’s a few different spots you could likely define the `_layoutDebuggingIdentifier`, but for view controllers, I tend to just put them in `viewDidLoad`. Here’s a sample of the code I use: ``` #ifdef DEBUG SEL selectorName = NSSelectorFromString(@"_setLayoutDebuggingIdentifier:"); NSString *identifier = @"Email Label"; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [self.emailLabel performSelector:selectorName withObject:identifier]; #pragma clang diagnostic pop #endif ``` Oh boy. This looks crazy. Let’s break down what’s going on line-by-line. On the first and last lines, I’m again wrapping everything in an `#ifdef DEBUG` block because I don’t want to ship this bit of code with my product to the App Store. The second line I am creating a `SEL` variable by calling the `NSSelectorFromString` function and passing in “\_setLayoutDebuggingIdentifier:” as a string. The line below it is defining what I want the `_layoutDebuggingIdentifier` string to actually be. From there, things start to get weird. I’ve got three different `#pragma` calls. The first one is saying that I am going to start adding some specific instructions for the compiler about things I want it to take into account in the following set of code. That’s what “push” is. The last `#pragma` says “pop”, which means I am done passing those bits of code specific diagnostics in. The specific diagnostic message I am calling is `#pragma clang diagnostic ignored "-Warc-performSelector-leaks"` which is telling the compiler to ignore the warning about my performSelector call possibly leaking, because it may not exist. Since `_layoutDebuggingIdentifier` is private API, the public framework headers don’t know what to do with it, so the compiler assumes it doesn’t exists. I assure you it exists as of iOS 8 though, so we can safely ignore that warning. The one caveat of course is that since this is private API, Apple can either remove it or change it in a future release. Be aware. Thus far we’ve set a single `_layoutDebuggingIdentifier` for our email label. Go ahead and set them for the rest of the controls that you care to have nicer output from. After you do that, run the application again and print out the output of `_autolayoutTrace`. ``` (lldb) po [self.view _autolayoutTrace] UIWindow:0x7fdb8511de90 | •UIView:0x7fdb83d3d470 | | *Email Label:0x7fdb83d3d780 | | *Password Label:0x7fdb83d3fae0'Password' | | *Logo Image:0x7fdb83d3ff70 | | *Email Field:0x7fdb83d40980 | | | _UITextFieldRoundedRectBackgroundViewNeue:0x7fdb83d4a240 | | *SignIn Button:0x7fdb83d4cfe0'Sign-In' | | *Password Field:0x7fdb83d4e070 | | | _UITextFieldRoundedRectBackgroundViewNeue:0x7fdb83d4f4b0 | | *_UILayoutGuide:0x7fdb83d4f9a0 | | *_UILayoutGuide:0x7fdb83d503b0 ``` Ah…much nicer. *If you’ve found this post useful, and want to learn more about how to best take advantage of Auto Layout in your OS X and iOS apps, be sure to purchase my new book [Achieving Zen With Auto Layout](http://www.autolayoutzen.com/?ref=justinw.me)*. ### Ninety Days URL: https://www.justinw.me/blog/ninety-days/ Last updated: 2014-08-04T19:00:59.000Z Aside from a [bit of snark](https://www.justinw.me/2014/07/29/my-thoughts-on-being-indie-in-2014/), I’ve kept mostly quiet about this year’s indie developer snafus. It’s not really my place to tell you how to run your business, but I can share some things I have done that I have found to be successful. When [Jared](https://jaredsinclair.com/?ref=justinw.me) told me last year he was going independent and planning to work on an RSS app for the iPhone, he asked me for some advice. I gave him the same advice I give anyone who is striking it out on their own. **Do not spend more than ninety days on your 1.0.** Jared spent approximately 365 days on his, so I apparently give crummy advice! But, there’s a reason I told him this (and anyone else that would listen). 3 months is a quarter of the year. When you are bootstrapping a company and don’t have much cushion to fall back on, every decision counts. You could argue its far more risky than playing with some venture capitalist’s funny money. Ninety days is a good amount of time to get a semi-polished 1.0 out in the world, especially in mobile. It won’t have every feature that you wanted to ship, but it will be out there and either be validated or invalidated by the buying public. Best case scenario, people find your product, start using it, and (most importantly) recommending it to others. Now you’re generating revenue and your customers are funding your work adding those missing features and putting those extra bits of polish in your UI. Worst case scenario, people don’t find your product, you make a couple hundred bucks, and you’re in debt for the project. This is the most likely statistical outcome at this stage. Would you rather find this out after 3 months or 6 months (or a year)? Ninety days. If the product bombs, you’ve burned 3 months of the year on the project, but there’s still 9 more months to try and find something that will stick with consumers. Kill the old product. Start a new one. Move on. The notion that you have to build this perfectly polished 1.0 in 2014 is poor advice. I like to reduce the amount of risk I take on in business. Taking four swings at the fences a year to find a new business is way less risky than trying to take just one. Don’t ship junk. Just don’t bother spending weeks or months polishing something that users may not even care enough to buy. ### Auto Layout In iOS 8 - Layout Margins URL: https://www.justinw.me/blog/auto-layout-in-ios-8-layout-margins/ Last updated: 2014-07-24T19:00:41.000Z Apple has added a few additions to both iOS 8 and OS X Yosemite that make working with Auto Layout even more of a no brainer than before. Over the next few weeks, I am going to take some time to write about each one of them to give fellow developers an idea of how to make use of these features in their products. Up first is layout margins. In iOS 8, Apple added the `layoutMargins` property on `UIView`. `layoutMargins` takes a `UIEdgeInsets` value that lets you explicitly define the whitespace that your views can use to guide where portions of the interface should be placed. ``` UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero]; label.translatesAutoresizingMaskIntoConstraints = NO; label.layoutMargins = UIEdgeInsetsMake(-20, -20, -20, -20); ``` For anyone that has used the `topLayoutGuide` or `bottomLayoutGuide` properties on `UIViewController` in iOS 7, laying out along a margin shouldn’t be a foreign concept. Those predefined values made it so that the content of your view wouldn’t be sunk underneath a transparent tab or navigation bar. With iOS 8, Apple has extended that functionality so that you can apply custom margins to any `UIView` that you work with. To go with the new layout margins functionality, there are new attributes added exclusively for iOS 8 for establishing relationships with Auto Layout. - `NSLayoutAttributeLeftMargin` – The left margin value of the view. - `NSLayoutAttributeRightMargin` – The right margin value of the view. - `NSLayoutAttributeTopMargin` – The top margin value of the view. - `NSLayoutAttributeBottomMargin` – The bottom margin value of the view. - `NSLayoutAttributeLeadingMargin` – Similar to `NSLayoutAttributeLeftMargin`, except the but the interface flips in a right-to-left environment like Hebrew or Arabic. - `NSLayoutAttributeTrailingMargin` – Similar to `NSLayoutAttributeRightMargin`, except the but the interface flips in a right-to-left environment like Hebrew or Arabic. - `NSLayoutAttributeCenterXWithinMargins` – This is similar to `NSLayoutAttributeCenterX`, but it takes into account the margin values that you have set. - `NSLayoutAttributeCenterYWithinMargins` – This is similar to `NSLayoutAttributeCenterY`, but it takes into account the margin values that you have set. If these all look familiar, they should. They are pretty much equivalent to the old attributes you used such as `NSLayoutAttributeLeft`, `NSLayoutAttributeRight`, and `NSLayoutAttributeCenterY`. The only difference is that these new methods take into account the layoutMargin values that you set. If you are targeting iOS 8, you should start adopting these new margin capabilities in your app, because it will lead to much cleaner code. Instead of having to use the `constant` value of your Auto Layout equation to insert padding, you can now just set the `layoutMargins` value specifically on the view, and let Auto Layout use those margins as part of its process. *If you’ve found this post useful, and want to learn more about how to best take advantage of Auto Layout in your OS X and iOS apps, be sure to purchase my new book [*Achieving Zen With Auto Layout*](http://gum.co/autolayout?ref=justinw.me)* ### Achieving Zen With Auto Layout - The Book URL: https://www.justinw.me/blog/achieving-zen-with-auto-layout-the-book/ Last updated: 2014-07-15T19:00:27.000Z **tl;dr** I am writing a book on Auto Layout. You can [purchase it now](http://gum.co/autolayout?ref=justinw.me). Over the last year I have been criss-crossing the country giving a talk called [Achieving Zen With Auto Layout](https://www.justinw.me/autolayout/) to any conference or user group that would host me. Speaking is not my primary goal. I am not an ex-developer. I just enjoy doing it a few times a year, especially since I spend so much time sitting in front of a computer in a solitary room typing. Even the most antisocial developers need a bit of human interaction. The talk has been well received far beyond my expectations. Everywhere I have presented has given it high marks and attributed it with helping them get over the hurdles of learning and using Auto Layout in their jobs. I have had it in the back of my head that I wanted to turn the talk into a book for a while. Every time I have thought about it, however, I have pushed the thought away. Writing a book is hard. Dealing with publishers is a pain. You don’t make much money doing it. Why bother? Despite all the reasons to not do the book, I kept coming back to the main reason I wanted to do it: I like helping people. I like when people tell me my talk has helped them learn a new technology. I enjoy having people say they learn new things from [CocoaRadio](http://cocoaradio.fm/?ref=justinw.me). So, I started writing. Not full-time. Not even part-time. I just started writing when I had time. Over the last few months, I have amassed enough content to generate what I consider to be the first 1/3 of the book. *[Achieving Zen With Auto Layout](http://gum.co/autolayout?ref=justinw.me)* is the eBook companion to my talk of the same name, but with the goal of being much more expanded than what I am able to do in a 45-60 minute on-stage presentation. This is a beta book right now. There are no screenshots (iOS 8 does still have a tiny bit of NDA that prevents those), copy editing hasn’t been done, and I still need to hire an illustrator to do a cover and some other things in the book for me. Content-wise though, I’m proud of what is there so far, and I’m excited to finish the rest of the book in time for the iOS 8 launch later this fall. You can purchase *[Achieving Zen With Auto Layout](http://gum.co/autolayout?ref=justinw.me)* today and get access to a PDF of the current state of the book, as well as a private GitHub repository where I am writing and storing all the sample code as I go. So far this has proven to be a wonderful way to write, because buyers of the book are able to provide direct feedback to me about the book so I can iron out any confusion or missing things I may not have thought of during my first draft. If you’ve struggled with Auto Layout in the past, I truly believe *[Achieving Zen With Auto Layout](http://gum.co/autolayout?ref=justinw.me)* can help you get over those hurdles. *[Purchase “Achieving Zen With Auto Layout”](http://gum.co/autolayout?ref=justinw.me)* ### Beta Testing A Book URL: https://www.justinw.me/blog/beta-testing-a-book/ Last updated: 2014-07-06T19:00:21.000Z When I decided to ship [Achieving Zen With Auto Layout](http://gum.co/autolayout?ref=justinw.me), I knew I didn’t want to wait until the book was completely done before unveiling it to the public. The old way of publishing involved writing a book in a vacuum, throwing it through a bit of tech editing and then putting it on the shelves at Barnes and Noble. I have a graveyard of books that are out of date or have a few technical inaccuracies, because they were printed to paper and unable to be updated without checking an Errata page on a publisher’s web site somewhere. Tech publishers have started doing an “early access” program with their digitally published books as soon as a few chapters are available, which allows early readers to provide feedback to the author along the way of writing. That seems like a much better way to write a tech book to me, so I shamelessly copied it. Of course, I don’t have a publisher, so I’m doing all of this on my own. Here’s a few of the tools I’m using and how they all piece together for running. ### Gumroad I am using [Gumroad](http://gumroad.com/?ref=justinw.me) to handle selling and distributing my book. There’s a few different vendors you can work with to do this sort of work, but I found the Gumroad interface to be incredibly easy to work with, and their analytics data is just enough to keep me interested, but not overwhelmed. It also doesn’t hurt that their fees aren’t too high, especially coming from an Apple world where they want 30% of everything. Gumroad collects the payments and then distributes a PDF of the current state of the book to people as soon as they purchase. They also support Webhooks, however, which I am taking advantage of. Each time a purchase is made, their WebHook fires an API I’ve set up on Azure. ### Azure Mobile Services [Azure Mobile Services](https://azure.microsoft.com/en-us/services/mobile-services/?ref=justinw.me) is the Backend-as-a-Service offering that Microsoft has for developers to easily integrate a server-side component into their iOS, Android, or Windows app. If you’ve ever messed with something like Parse or Stackmob, it’s similar vein to that complexity. You don’t need to provision servers or deal with a bunch of configuration. It handles most of the heavy lifting for you and provides an API for anything you want to get dirty with. I’m using [Azure Mobile Services](https://azure.microsoft.com/en-us/services/mobile-services/?ref=justinw.me) to host a small API with a single endpoint. To do this, I have a small Javascript…script…that takes the receipt data I get from Gumroad, validates it, and then fetches the purchaser’s GitHub username. Once I have the GitHub username, I make a call to their API to add that username to my private repository that contains the Markdown files of the manuscript as well as all the source code for any sample projects. In all, it’s maybe 15 lines of code tops. It’s likely not the traditional use case for Azure Mobile Services, but it was way easier to do this than provision a complete WebAPI or Node application and deploy it to a cloud service or virtual machine. ### GitHub Now that I have a [GitHub](http://github.com/?ref=justinw.me) repository with all my beta purchasers on board, they are able to do a few different things: 1. They can see my progress as I write on the book. I try to only submit chapters that are completed first drafts. 2. They can file Issues with either requests for topics to cover, or any technical issues they may find in the book. 3. They can fix my typos (I admittedly never expected anyone to do this, but a few have taken the time. Thanks!) The second one is the most useful to me. I’m now able to run this book like a semi-open source project and get instant, trackable feedback from the people who are invested in the project. There’s no middle man in between. It’s just me and the readers working together to make [Achieving Zen With Auto Layout](http://gum.co/autolayout?ref=justinw.me) the best book it can be. ### Thinking In Terms Of iOS 8 Size Classes URL: https://www.justinw.me/blog/thinking-in-terms-of-ios-8-size-classes/ Last updated: 2017-03-20T22:58:34.000Z One of the least sexy features of iOS 8’s new developer SDK may in fact be its most important: size classes. ### A History Lesson When iOS was first introduced, we had one device: the iPhone. It had a 320×480 pixel screen and it came in any color you liked, as long as it was black. Even in this single iteration, it supported two orientations: portrait and landscape. Designing an app that supports two orientations isn’t always as simple as letting views stretch and resize like Mobile Safari or Messages do. In a lot of cases, buttons and other controls need to be moved around to better take into account the altered sizing of landscape (480×320). Fast forward several years later and we’ve got retina displays, iPads, and 5″ iPhones. Oh and all those devices also support multiple orientations of course. The current/old way of solving this problem has been a mix of listening for orientation changes in your view controllers and custom views, as well as using multiple Xibs or Storyboards. Let’s say I was building a universal version of Glassboard that supported the iPad. With iOS 7 and older, I would need to create a secondary Storyboard that had each of my view controllers re-established, its outlets redone, and its target/action sequences reconnected. Duplicate work. Any seasoned programmer knows this isn’t ideal. Having to make the same change in two different places sucks. Now, let’s add in the areas where I wasn’t necessarily using a Storyboard or Xib. There are likely going to be checks in the code to detect orientation and device size so that I can adjust my constraints or frame-based layout code (like an animal) manually. Your code is likely littered with a lot of this: ### Size Classes Obviously the above is not ideal, and it’s likely only going to get worse as Apple introduces new devices going forward. WWDC is a wonderful opportunity to read tea leaves and see where Apple is going by their new APIs and how hard they are pounding concepts into your heads each year. In addition to pushing Auto Layout this year, you also saw many instances of a resizable iOS simulator and a new technology for handling all this crazy idiom and orientation stuff: size classes. A size class is a new technology used by iOS to allow you to custom your app for a given device class, based on its orientation and screen size. There are two goals with size classes: 1. To get developers and designers out of the habit of thinking in terms of specific devices, and instead thing of a more generalized approach. 2. To plan for the future. The first one obviously leads to the second. You’ve no doubt seen the countless rumors that the iPhone 6, 7 or whatever is going to be a larger device. You’ve probably heard that Apple is working on wearables. Guess what will make developing for these new devices easier? Size classes. There are presently four size classes. ![Size Class Chart](https://storage.ghost.io/c/93/30/93302d8c-df65-445d-9422-99c3d0ca0880/content/images/2017/03/size_class_chart.jpg) - Horizontal Regular - Horizontal Compact - Vertical Regular - Vertical Compact At any time your device is going to have a horizontal size class and a vertical size class. Together, those are what is used to define which set of layout attributes and traits to show the user on screen. ### Traits The horizontal and vertical size classes are considered traits. Together with the current interface idiom and the display scale they make up what is called a trait collection. This doesn’t just include where on screen specific controls should be placed. Traits can also be used for things like image assets, assuming you are using Asset Catalogs (remember when I said to use the new stuff Apple introduces?). Instead of just having a 1x and 2x version of your asset, you can specify different image assets for a horizontal and vertically compact size class, as well as one for horizontally regular and vertically compact. In code, it still looks like the same UIImage call. The Asset Catalog takes care of rendering the appropriate image basd on the current trait collection. ### Designing For Size Classes Size classes are a nice addition for developers because it helps simplify the development experience when we want to support multiple devices and orientations. By making our job easier, Apple can more easily introduce new device sizes *and* sell developers on making their apps universal rather than just being an iPhone only product. The biggest change for us developers is redoing our orientation code for the third or fourth time since iOS was created. We’re developers. We’re used to it. For designers, trait collections means thinking less about the *specific* device you are designing for and instead thinking about the *attributes* of that device. The biggest attribute designers think in terms of now is physical screen size. Their mockups are pixel perfect for 320×480, 480×960 and the like. Designing for those scenarios is no longer tenable as we move more towards a world where not every device is guaranteed to have the exact screen dimensions your Photoshop or Sketch mockups account for. Instead, the goal should be thinking about designing in the general sense for the class of device, which is presently: - Portrait Phone - Portrait Tablet - Landscape Phone - Landscape Tablet If an iPhone 6 comes along and it has a bigger screen, my guess is that it’s going to have the same trait collections as the existing iPhone 4s and 5\. Sure, the dimensions of the device will be bigger than the existing phones, but the UI should adaptively handle those changes based on your already defined interfaces for those specific trait collections. This is likely the point where the designers have flipped over their bamboo work benches, but it’s the reality. Just like software development, software design is about adapting to the constraints. The new constraint is that we no longer have a world where we’re building towards a specific screen size. We’re not approaching Android levels of craziness, but this absolutely preps us for where Apple is headed. ### Adopting Size Classes The good news is that Interface Builder makes working with size classes easy. The better news is these Interface Builder changes are backwards compatible so you can simplify and consolidate Storyboards and Xibs where appropriate without leaving behind any legacy users. The not so good news is that if you want to work with trait collections in code, it’s iOS 8 only. This shouldn’t come as a shock as Apple rarely backports new APIs to legacy versions of the OS. What it does mean is that you’re going to have to add some additional branching in your code to account for when you want to, for example, adjust the `intrinsicContentSize` of your custom `UIView`. If the device is on iOS 8, you can use the horizontal or vertical size class to help determine that value. If the device is still on iOS 7 or whatever, the existing code you’re using will have to remain deployed. Since I [use and recommend Interface Builder](https://www.justinw.me/2014/05/09/why-you-should-use-interface-builder-with-auto-layout/), my work load is significantly less than those that are still living by the “write everything in code” mantra. If you find yourself still in that camp, I’d *highly* recommend using iOS 8, Xcode 6, and trait collections as an opportunity to get on the Interface Builder bandwagon. It’s not only going to lessen the amount of boilerplate code you have to write, but it’s also going to simplify your code base by extracting out a lot of the trait handling into a visual UI. ### Learning How To Make Sausage URL: https://www.justinw.me/blog/learning-how-to-make-sausage/ Last updated: 2014-06-12T19:00:01.000Z Let’s imagine there is someone out there who watched last week’s WWDC keynote and thought to themselves, “This is it! Now! Now is the time for me to learn to program and build an iOS app!” Nevermind that they are about 6 years late to gold rush, it’s an exciting proposition. Programming is fun! I come from a family of builders. The only difference between my father and grandfathers is they built homes with hammers. I sit in front of a keyboard all day typing and looking at cat GIFs. I digress. You want to learn to be an iOS developer. What are you supposed to do? Aaron Hillegass (whose books I credit with teaching me this stuff way back when he was the *only* person writing about Cocoa development) says you should learn [Objective-C](http://www.bignerdranch.com/blog/ios-developers-need-to-know-objective-c/?ref=justinw.me). Ash Furrow and a few others say you should learn [Swift](http://ashfurrow.com/blog/objective-c-is-not-easy-to-learn?ref=justinw.me) because Objective-C is too hard. Guess what? It doesn’t matter what language you want to learn. If you want to be an iOS developer you realistically have four options: 1. Objective-C: old faithful. 2. Swift: New hotness. 3. Xamarin: The crazy kids in the corner who want to use C#. 4. RubyMotion: Know Ruby? Tired of arguing with DHH about whether tests are dead? You too can build an iOS app. I’d lean towards choosing one of the first two options because they are first-party solutions provided directly by Apple, but the language you choose to learn matters little compared to learning **the frameworks**. The Cocoa Touch frameworks have always been the secret sauce. Whether you’re using Objective-C, Swift, C#, or Ruby you’re still going to have to learn how to use a `UIButton` and a `UITableView`. Will you be more of an iOS developer because you took the time to learn Objective-C and it’s 20+ years of history versus Swift and its eleven days? Nope. Your customers care about what’s on the surface of your app: does it look, interact, and *feel* like an iOS app. If you can do that, the language doesn’t matter. There is no right answer to this question. Choose what the language that speaks to you and then go build something awesome. ### The Next Five Years URL: https://www.justinw.me/blog/the-next-five-years/ Last updated: 2014-06-08T19:00:39.000Z [Just when I thought I was out, they pulled me back in](https://www.youtube.com/watch?v=UPw-3e%5FpzqU&feature=kp&ref=justinw.me). My confidence in the iOS platform has been waning over the last 12 months. iOS 7 was a hard upgrade to swallow both in terms of the changes and the work it brought. A questionable visual refresh, but few improvements to a core experience that finally felt behind what the competition was offered. My time with C# and Azure showed me the sharp edges in Objective-C that I wasn’t fully aware of before. It’s not that Objective-C is a bad language (it’s pretty great), but it’s also built on a foundation that makes things that should be simple not so simple. Even the developer tools were lacking. The iOS publishing and beta experience has been laughably bad for years, especially compared to what Google offers Android developers. And then in two hours, Apple shut me up. They pretty much offered a solution for every single thing I have bitched about over the past five years. Extensions, CloudKit, a new iTunes Connect. And Swift, an entirely new programming language that will likely power the future of iOS and OS X development for years to come. I came into this years WWDC fairly mellow to what would or wouldn’t be announced. There wasn’t any anticipation or excitement the night before. Just a standard amount of curiousity. After the Keynote, I can’t remember being that excited since the announcement of the original iPhone. They blew the roof off Moscone. With my entire list of complaints about the Apple platform resolved, what am I supposed to complain about now? I have spent the better part of the last week thinking about an entirely new list of things for Apple to work on these next five years, so that I can both continue to have something to nitpick and because I truly believe they will enhance the platform in meaningful ways. - **A Global Accounts System**: Authenticating with your Facebook or Twitter account on iOS is as simple as accepting an alert view pop-up. Authenticating with Foursquare, Glassboard, or any other third-party auth provider requires either manually entering passwords or using a URI scheme to jump between apps. Being able to set any third-party service as an auth provider a la Twitter or Facebook would benefit all users of those services. (Radar: 17226236) - **async-await**: Swift is wonderful until you have to create a dispatch queue. Then you remember that concurrency is still way too hard on Apple’s platforms. C# has solved this in a meaningful way with their async-await keywords that make asynchronous programming incredibly simple. (Radar: 17226224) - **Better Refactoring Tools In Xcode**: Xcode 6 is a wonderful update, but its ability to refactor code in meaningful and reliable ways still lags severely behind Android Studio and Visual Studio. - **Token-Based APNS**: The certificate dance that you have to jump through to work with Apple’s Push Notification Server is horrendous when compared to other solutions. Being able to register for a secret token and use that to authenticate is far simpler to integrate than the certificates and provisioning profiles needed presently. (Radar: 17226189) - **CloudKit REST Endpoints**: CloudKit is designed to excel on iOS and OS X, but there are server-side scenarios where it would be beneficial to be able to hit a CloudKit end point and pass data to a user’s account, or register a silent push based on a third-party data source hosted remotely. (Radar: 17226182) - **Default Apps On iOS**: With great third-party apps that are offering full replacements for standard apps like Safari, Mail, and Calendar, it’d be ideal to be able to associate them with iOS so if I use Mail and tap a link I can have it open in Chrome, my preferred iOS browser. (Radar: 17226170) Here’s to the next five years. ### (no title) URL: https://www.justinw.me/blog/251/ Last updated: 2014-05-09T19:00:17.000Z The ski bum of the iOS development community Kirby Turner wrote up how he [using Auto Layout](http://www.thecave.com/2014/05/04/i-stopped-using-nibs-thanks-to-auto-layout/?ref=justinw.me) and was lucky enough to get a large audience for it through [iOS Dev Weekly](http://iosdevweekly.com/?ref=justinw.me). I’m happy to see that Kirby is embracing Auto Layout. I did take issue with the premise of his article though: that he is writing all of his constraints in code rather than using Interface Builder. It’s totally possible to do this, and there are situations where I do it as well. Small views with a few basic constraints are usually quicker and easier to write without a Xib. Insanely complex views such as the \[TED video player\] I wrote and maintain are also too heavy for a straight Xib implementation. For pretty much any situation outside of that? You are doing yourself a disservice avoiding Interface Builder now that we are switching to using Auto Layout rather than springs and struts. Why? Allow me to share a few reasons. ### Instant Ambiguity and Conflict Checking When you are defining the constraint-based relationships between your views in Interface Builder, you get real-time feedback in the Xib or Storyboard’s sidebar. If you see a yellow circle, there’s likely a misalignment. It’s a warning. If you see a red circle, there’s either a conflict, ambiguity, or some other issue that is going to cause pain when you build and run. If you write all your constraints in code, you don’t find out about these sorts of issues until you run the application and get hit with an exception. ### Code Is A Liability The less code I have to manage, the better. Not only do Xibs and Storyboards let me visually lay out the main components of my interface, I can also define the attributes on them without having to type out more code. That’s something we have always had. Now with Auto Layout, we can also define our constraints in the same Xib files rather than having to sprinkle bits of code all over our projects. Every line of code you write now is a line of code you have to manage six months from now. I’d rather have less management personally. ### You Suck At Typing One of Auto Layout’s best features is its ASCII syntax for defining multiple constraints quickly. There are legimitate times where you don’t want to or need to lay out your constraints in a Xib. It’s not without fault though. Let’s say you want to lay out a constraint with `NSLayoutConstraint`‘s `constraintsWithVisualFormat:options:metrics:views` method. Everything you type into the `constraintsWithVisualFormat` section has zero checking of its syntax. It’s just yet another string literal to Xcode. The only way you will know that you screwed it up is to run the app and see what crashed. Apple could theoretically fix this in the future, but as of Xcode 5.1 you have to be a perfect typist. I’m far from perfect. ### Visual Layout From a learning perspective, I truly believe the best way to begin to understand and use Auto Layout is through Interface Builder. I’m a visual learner, and being able to lay out my views and then see a visual representation of the constraint relationships between two views is killer for fully understanding what the new layout system is doing. By writing everything in code, you are putting yourself behind the eight ball before you have even gotten started. I’d put money on the fact that most people that try Auto Layout and then ditch it either haven’t touched Interface Builder since Xcode 4 (which sucked) or are trying to do all their Auto Layout work in code. ### Summary Interface Builder’s Auto Layout support isn’t perfect. There’s plenty of things I’d love to see Apple change, but writing all your constraints in code only should be the exception, not the norm. If you’re still struggling with Auto Layout, be sure to check out my [Auto Layout Resource](https://www.justinw.me/autolayout) page. : [https://itunes.apple.com/us/app/ted/id376183339?mt=8](https://itunes.apple.com/us/app/ted/id376183339?mt=8&ref=justinw.me) ### Going Against the Grain URL: https://www.justinw.me/blog/going-against-the-grain/ Last updated: 2014-05-06T19:00:52.000Z By now you may have heard that App.net, the upstart social network/platform/data layer, is entering [maintenance mode](http://blog.app.net/2014/05/06/app-net-state-of-the-union/?ref=justinw.me) after the company laid off their team when renewals weren’t as high as they’d hoped. I’ve been a founding member of the ADN movement since 2012 and have renewed each of my developer accounts without much hestitation. I’m abnormal however. I prefer paying for my products rather than being advertised to, want to pay higher air fares for better service, and prefer dot syntax to brackets when writing Objective-C. Running a niche social platform such as App.net is harder than I think most people realize. I gained a whole new respect for ADN after taking on [Glassboard](http://glassboard.com/?ref=justinw.me), a service that shares many similarities beyond just being “social”. Social services like Instagram, Twitter, and Facebook succeed because they are designed to reach the highest amount of people with the least amount of friction. The easiest way to remove friction for users is to make the product free and then figure out monetization down the road when you’ve (hopefully) gained a ton of users. Instagram and Facebook seem to be excelling at this. I can’t remember if Twitter is succeeding or miserably failing this week. Anyway, the point is that gaining a high amount of users by making your product free is enticing if you can afford to. Right there, App.net and Glassboard are at a disadvantage by being “freemium” rather than full-on free. Consumers have been trained by Facebook, Twitter and [Pied Piper](http://www.piedpiper.com/?ref=justinw.me) to not pay for the services they use. To combat this, we try to offer enough value for the free account to get people using the service, but not so much that they won’t pay. With App.net, accounts were limited by the amount of people you could follow on your timeline as well as storage for any files or media you wanted to put on the service. Glassboard limits the amount of boards you can create or the amount of storage you can upload. I’d argue that neither are successful. I don’t know App.net’s numbers, but I know Glassboard’s. Glassboard has been losing money its entire life. Last month it lost $1200\. The month before it lost about $1500\. The amount of premium subscriptions we convert is far too low to consider the product anywhere near a success. I knew this going into the acquisition, and have been working on changing that going forward, but pivoting a product used by tens of thousands of users daily is more like turning the Titanic than a speed boat. I have one advantage where I have never had employees with Glassboard, my payroll is pretty affordable as a party of 1, but it still doesn’t take away the fact that losing money is not the goal of any business, especially a bootstrapped one. ### Finding An Audience Even with an amazing business model, it’s just paper without an audience however. When you’re running a paid social platform, you’re looking for niches. Sure, you dream of having Twitter or Facebook user numbers, but the reality is that when your goal is to be funded directly by your users, you’re only getting a fraction of those numbers. My ADN stream was populated with iOS developers and [Bronies](https://alpha.app.net/stevestreza?ref=justinw.me). I’m sure Dalton or Bryan could list a few other groups that are popular on ADN. Glassboard has become fairly popular with gamers who organize their clans on the service in addition to small businesses and families who want a private way to communicate. I call this finding a niche. Silicon Valley calls this [product-market fit](http://www.stanford.edu/class/ee204/ProductMarketFit.html?ref=justinw.me). Finding an audience of people interested in your platform is challenging. This isn’t Field of Dreams where if you build it people will magically appear. Once you find that niche of users, you’ve got to ensure they’re also the type of folks that are willing to pay to support your platform. If they aren’t, you keep looking for a niche that will sustain your product. I have a few niches with Glassboard, but based on the numbers I shared above, they aren’t profitable niches. I’m hoping that can change as I change the product’s business model and pricing in the near future, but I won’t know for sure until I actually ship the code. ### Stigma The other thing going against ADN and Glassboard is stigma. So many people in my circle have said to me “oh, the conference app?” when I mention Glassboard. They see the product as something they install when they go to WWDC, 360iDev, or CocoaConf and not a part of their daily usage. Nevermind that people are using the product for a variety of different things outside of attending conferences, it will always be the conference app. For ADN, I believe that stigma is the “Twitter service that isn’t Twitter”. Nevermind that ADN tried to build more than a Twitter platform with their backer program, messaging platform, and authentication layer. Most people saw ADN for Alpha, the Twitter clone they shipped as part of their original funding model. Getting over a stigma is difficult, and I’m still trying to figure out how to do that with Glassboard, but I do believe that contributed to ADN’s lack of success. That stigma likely contributed to people questioning whether it was worth paying another $35 a year to “tweet” somewhere else. ### What’s Next I’m willing to guess that most of the folks reading this post are the types that are willing to pay for the products they use. Unfortunately, you and I are a minority compared to the rest of the Internet using public. ADN’s fight may be in maintenance mode, but I’m still pushing forward with my [moonshot](https://www.justinw.me/2014/04/17/moonshots/) of turning Glassboard into a profitable endeavour. People may write off ADN as a failed experiment and maybe it technically is, but it was always a risky proposition. They always were going against the grain and seemed like a longshot to succeed. We need more people to take risks like that. It’s still too early to tell if Glassboard is going to be a financial success or failure. There’s nights that I go to bed questioning everything I’ve done this year. This is the life you choose if you go against the grain and building a platform that isn’t just another ad-based clone funded by venture capitalists. Back to work. ### Combatting Kryptonite URL: https://www.justinw.me/blog/combatting-kryptonite/ Last updated: 2014-04-29T19:00:39.000Z One of the Twitter searches I check every few days is for [“Auto Layout”](https://twitter.com/search?f=realtime&q=%22Auto%20Layout%22&src=typd&ref=justinw.me). Twitter is a wonderful place to find people complaining about technologies, and pretty much the only information you’ll see on the Auto Layout search for Twitter is complaints and confusion. Recently, I read an article from [Brent Simmons](http://inessential.com/2014/04/27/green%5Frocks%5Ffrom%5Fspace?ref=justinw.me) on his struggles with adopting Auto Layout in Vesper. He claims its kryptonite in a lot of ways and causes more struggle than it’s worth sometimes. Brent is a smart guy, so seeing him fighting the technology isn’t a good sign for others who are just coming to iOS or OS X having much better luck. Maybe I can help a bit. ### Why Auto Layout Exists Springs and struts has existed nearly as long as I have been alive, so why did Apple even bother doing something like Auto Layout? Springs, struts, and auto resizing masks weren’t necessarily broken, so no need to fix it, right? Ultimately, Apple believed they were building something better in Auto Layout. Auto Layout offers a lot more functionality and power when building complex layouts in exchange for changing how you think about building your interfaces. Rather than placing your views on the screen, Auto Layout is about *describing* the relationships between each of the views and how they relate to either its superview or adjacent views. On the surface, it’s far easier to say that you want to center a button vertically and horizontally in its parent view with an NSLayoutConstraint call than it is to do the math to calculate the exact `CGPoint` you want to place the button on screen. From a fussy developer perspective, Auto Layout also helps alleviate some of the *Massive View Controller* problems that have plagued developers over recent years. Things such as the intrinsic content size and alignment rects allow us to do a lot of view sizing calculations in the view subclass where it belongs rather than in your controllers. Finally, Auto Layout also enhances the usefulness of Interface Builder, a tool that has been around for decades and is one of the major selling points Apple has when showcasing their developer platform. It got off to a rocky start with Xcode 4’s frustrating Auto Layout implementation, but Xcode 5 has been great. ### Debugging Constraints While the learning curve of Auto Layout isn’t as bad as it once was thanks to the vastly improved support in Xcode 5 and 5.1, there’s still plenty of issues you run into when you are coding up and debugging your constraints-based layouts. In Interface Builder, debugging constraints is nicely done. If you’ve got misalignment, conflicting constraints, ambiguous layout, or a variety of other issues that could plague your UI, Xcode will instantly warn you and offer ways to resolve the issue. I believe this has helped people immensely understand Auto Layout better. If you need to work outside of Interface Builder, Apple’s [debugging advice for constraints](https://developer.apple.com/library/ios/documentation/userexperience/conceptual/AutolayoutPG/ResolvingIssues/ResolvingIssues.html?ref=justinw.me) is fairly caveman. There are a few lldb commands such as `_autolayoutTrace` and `exerciseAmbiguityInLayout` that can help you figure out how to resolve your issue. One thing that I don’t think too many people know is that there is an Auto Layout instrument in the Instruments app that you can use to observe what is happening to your layouts in real-time. There are a few caveats to using it on iOS, however. 1. It only works in the Simulator. 2. You’ll need to manually add it to a blank Instruments document from the tools library. Finally, one of my favorite tricks is to set a `restorationIdentifier` for every view in an iOS view and then using that to help visualize and understand constraints when printing them out in lldb. Here’s a debugging category I use to accomplish this. With this in your project and your restoration identifiers set, the values output by `po self.view.constraints` becomes a lot easier to read and understand as well. ### It’s Apple’s Turn Again I was hoping that almost a year after I started pushing the gospel of Auto Layout that we’d be past the point where people are still fighting the technology, but sadly we’ve reached the point where I believe it is on Apple to improve the tools and documentation for Auto Layout if they want to continue to see its adoption grow. My biggest request? `NSWindow` on the Mac has a [visualizeConstraints](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindow%5FClass/Reference/Reference.html?ref=justinw.me#//apple%5Fref/occ/instm/NSWindow/visualizeConstraints:) method that makes it easy to see what each of your constraints is doing in a running app. Having something like that that applies to any `UIView` would be immensely useful. On top of that, the ASCII language, while powerful, offers no real-time syntax checking which leads to a lot of cavemen build/run/check scenarios when you forget a bracket or mislabel something. And finally? A less verbose syntax. I’ve watched more than a few eyes glaze over when I try to verbally read out “constraint with item attribute related by to item attribute multiplier constant”. There’s opportunities to shrink and simplify that syntax for a variety of common scenarios such as vertically or horizontally centering a view with another view. In fact, if you search GitHub you’ll likely find a dozen different short-hand projects that do just that. WWDC is just around the corner. Auto Layout isn’t the sexiest technology Apple can highlight during its keynote, but it’s one of their most important going forward. It’s true you don’t [*need*](http://inessential.com/2014/04/29/layout%5Fcode%5Fand%5Fscreen%5Fsizes?ref=justinw.me) Auto Layout to deal with different screen sizes and orientations, but I sure don’t want to go back to doing it the old way. As Apple starts dealing with different screens in the future, making sure that Auto Layout is at the forefront as an accessible and understandable foundation for layout is essential. ### Fighting Your Tools URL: https://www.justinw.me/blog/fighting-your-tools/ Last updated: 2014-04-22T19:00:17.000Z As I [mentioned recently](https://www.justinw.me/2014/04/16/refactoring-in-the-cloud-notifications/), I am working on a refactoring of how Glassboard handles its push notifications system. The short-version is that the current incarnation uses an Azure Worker Role to handle messages of a Storage Queue via C# and a lot of custom written code for tying into each push notification provider we use. When we last spoke, I was pretty convinced with throwing out the C# code in favor of a Node and TypeScript flavored solution. I was also debating using Azure’s Notification Hub service for delivering the pushes to further lessen my code liability. I have been working on this for the past few days, but it hasn’t been going exactly as I had hoped. For those that don’t know, [TypeScript](http://www.typescriptlang.org/?ref=justinw.me) is a language layer similar to Coffeescript that compiles down to plain old Javascript. It’s got a great syntax that allows you to have typed variables, and just hit 1.0\. TypeScript also allows me to be a lazy developer because it integrates natively with Visual Studio’s intellisense. Given that I’m spending most of my time in Visual Studio working on this backend provider, it made sense to give TypeScript a whirl. If you’re interested in seeing some sample TypeScript, here’s a [snippet from Glassboard](https://gist.github.com/justin/11191090?ref=justinw.me). I really like the syntax, though having to write my own accessor methods is very cave man. Microsoft also recently went to a [1.0 beta with their NodeJS tools](https://nodejstools.codeplex.com/?ref=justinw.me) for Visual Studio that make it super easy to build and deploy Node to Azure. Since I am working with Azure’s storage and CPU emulators in Windows already, using these tools made sense too. I’ve never had much luck bridging the emulators from my VMWare instance to my Mac’s network stack anyway. The Node tools also have built-in support for debugging Node both locally and remotely, which is super awesome. So, good language. Good toolchain. What’s the matter? It turns out that Windows has a really annoying problem with long file directory paths. In short, a file name must be less than 260 characters, and a directory path must be less than 248 characters. Otherwise, you get this error *constantly*. ``` Unable to copy file ".node_modulesazurenode_modulesrequestnode_modulesform-datanode_modulescombined-streamnode_modulesdelayed-streamtestintegrationtest-handle-source-errors.js" to "objDebug.node_modulesazurenode_modulesrequestnode_modulesform-datanode_modulescombined-streamnode_modulesdelayed-streamtestintegrationtest-handle-source-errors.js". The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. C:Program Files (x86)MSBuildMicrosoftVisualStudiov12.0Node.js ToolsMicrosoft.NodejsTools.targets 74 5 Cloud ``` Now, imagine you are working with a framework like Node that relies heavily on package modules, which also rely on package modules, which also rely on package modules. You’re going to run into this pretty much every time you build. I tried working around it at first by mapping a virtual drive for my Development projects, but the nested node modules still became too much for Windows 8 to cope with. This is a bummer for a variety of reasons. For one, using the Node tools for Visual Studio is nearly impossible for any development situation that relies on a suite of npm modules. As you can see from the error above, I’m trying to use Microsoft’s own Azure module and running into the issue. It pretty much prevents me from building my project and testing it locally in Visual Studio. And as a developer, I’m bummed for the people working on the Visual Studio Node Tools project. They’ve built something really great, but I’m struggling to use it because of a long-time Windows bug (yes, this is a bug). I will never complain about HFS+ again. I have a few options to deal with this issue. 1. Keep going ahead with what I’m doing and hope that one day Windows stops being Windows. 2. Work on getting the Azure Emulator to work through VMWare to my host Mac so that I can write the TypeScript code in Sublime Text natively on my Mac. 3. Throw away two or three days worth of work and go back to a C# solution that likely won’t run into this issue since its dependency model relies on namespaces rather than directory structure. I’m leaning towards option 2 or 3 even though the Stubborn Developer wants to take option 1. Option 2 is nice because I can still use TypeScript and Node to manage this portion of the project. I’m pretty sure I can figure out the VMWare issues I’ve had if I sit down for a few hours and tackle it. The tradeoff is that Sublime’s TypeScript support isn’t nearly as powerful as Visual Studio. I’m a lazy developer. I like my tools to enable me to be as lazy as possible. Option 3 is appealing because I have a good chunk of the code already written in the legacy system. Since I’m switching to Notification Hubs, I can trash a good chunk of the existing code base and wrap it in the Azure SDK’s handling library. Thanks to an [Azure Friday](http://channel9.msdn.com/Shows/Azure-Friday/Azure-Queues-101-Basics-of-Queues-with-Mark-Simms?ref=justinw.me) series of videos I’ve got a better understanding of how to handle not using threads to manage the processing on the Worker Role as well. I’m taking a day to weigh the pros and cons so I can choose which route I want to take. Until then, the lesson learned from this is that new and shiny doesn’t always mean better. Now I’m behind on my ship goal by several days. Back to work. ### Moonshots URL: https://www.justinw.me/blog/moonshots/ Last updated: 2014-04-17T19:00:13.000Z *tl;dr — Photos+ has a new home at [Silver Pine Software](http://www.silverpinesoftware.com/photos.html?ref=justinw.me). Elements has been discontinued due to lack of sales and so I can focus on [Glassboard](http://glassboard.com/?ref=justinw.me).* When I decided to take over [Glassboard](http://glassboard.com/?ref=justinw.me), I knew I was at the time biting off more than I could chew as a sole developer. Balancing a product that has three front-end clients, an API server, and tens of thousands of users while also working almost full-time as an iOS and Android contractor isn’t easy. Add on top of that, my existing suite of products and it’s a bit insane. One of the things I said I would do when I decided to take on this adventure was to simplify and focus my work. I’ve always had a bit of ADD, which is why my suite of apps has ranged from text editors to GitHub clients to photo galleries. In late 2013, none of these apps were necessarily setting the world on fire financially, but they had users that I wanted to try and do right by. I have spent the past several months working on finding new homes for each of them. #### Committed We announced that The Magical Panda acquired [Committed](http://www.magicalpanda.com/committed/?ref=justinw.me) a few months ago. Since the acquisition, Saul and friends have been hard at work squashing bugs and adding new features such as 2-factor authentication support for a more secure GitHub login experience. #### Photos+ As of today, [Silver Pine Software](http://www.silverpinesoftware.com/photos.html?ref=justinw.me) is the new home for Photos+, the pro’s photo browsing app I released back in December of last year. Photos+ is an app I always wanted personally. I had a pretty large roadmap for where I wanted to take Photos+ in terms of functionality, but being able to realize that feature set and work on Glassboard simultaneously is nearly impossible. I handed Silver Pine my roadmap as a source of feedback on where I think they should take the product, but it’s totally theirs to do as they see fit. I am happy, however, that their 1.1 release includes support for browsing your Dropbox photo library: by far the biggest thing I wanted to add from day one. #### Elements I was unable to secure a buyer for Elements unfortunately, so it has been discontinued. Sales of Elements have not been more than lunch money and enough to cover paying my support minions for almost a year. As much as I enjoyed working on it, the market for a paid Dropbox text editor has passed. It’s become too saturated and too mature to reasonably think you can make a decent living from it. To the Elements fans still using the app, my apologies, but I’m a firm believer in not keeping an app around to rot over time. The good news is that there are dozens of great competitors out there you can choose from. ### Focusing On Glassboard This is it. I’m all in on Glassboard. I don’t have any other products to fall back on or bring in supplemental income. Google is big on talking about taking [moonshots](http://www.google.com/about/careers/lifeatgoogle/thinking-big-larry-page.html?ref=justinw.me) with their self-driving cars, Glass, and [terrifying life like robots](https://www.youtube.com/watch?v=wE3fmFTtP9g&ref=justinw.me). These are big ideas, but I wouldn’t say they are moonshots because the company is still almost entirely funded by their insane ad revenue. If self-driving cars or evil robots don’t pan out, they’re going to be fine. I’m taking a moonshot. Glassboard is a giant undertaking and the biggest risk of my career. It’s a make or break decision that will likely shape the next decade of my career. I’m working full-time right now to try and launch the first piece of my Glassboard overhaul this summer. At that point, I’ll start to have a pretty good idea whether this was a good idea, or whether I’m going to be heading to the local McDonalds looking for a job. Wish me luck. ### Refactoring in the Cloud - Notifications URL: https://www.justinw.me/blog/refactoring-in-the-cloud-notifications/ Last updated: 2014-04-16T19:00:24.000Z One of the things I have been thinking about a lot recently is the architecture of Glassboard. Now that I have everything mapped out for where I want to take Glassboard’s direction going forward both financially and functionally, it’s the time to look at how to actually build that functionality into the existing code base. ### The Current Glassboard Architecture Glassboard’s backend is powered by [Microsoft Azure](http://azure.com/?ref=justinw.me). In terms of computing, there are three main components: two worker roles and one web role. Azure defines a Web Role as a server that has a running copy of the IIS web server on it, so that users can connect to it. A worker role doesn’t run IIS, but is still a Windows Server instance that you can use to do things like background processing on it and offload some of the heavy activities from your main server role. This is a rudimentary diagram of the Glassboard architecture as of April 2014. ![Glassboard's Architecture](https://i1.wp.com/cdn.carpeaqua.com.s3.amazonaws.com/images/notifications-role-arch/glassboard_architecture.png) - **The Kitchen Sink Web Role**: I currently deploy a single web role that autoscales between 2 and 4 instances based on user traffic. This single web role does a lot. It handles all user authentication and signups as well as managing and distributing the Glassboard JSON API (through WCF god help me). In addition, it also has a few web hooks connected to it, and the Glassboard web app which is a rudimentary ASP.net MVC application with a Backbone.js exterior. It’s a beast. - **Attachment Processor Role**: When you upload a photo or video to Glassboard, it’s thrown into this role to do some post-processing like rotating it to the proper orientation and compressing to save us some server side bandwidth. Right now it’s using ffmpeg, Handbrake and a bunch of scripts to accomplish this. It’s more brittle than [Greg Oden’s knees](https://www.google.com/search?q=greg+oden+knee+problems&es%5Fsm=91&tbm=isch&tbo=u&source=univ&sa=X&ei=U5hOU8nxAYqryATC6oDYBQ&ved=0CCoQsAQ&biw=1150&bih=929). We’ll get to refactoring it eventually. - **Notifications Role**: The Notifications Role handles distributing all the push notifications and emails that are sent out through Glassboard. Currently it supports Apple’s Push Notification Service, Google Cloud Messaging, Google’s legacy Cloud to Device Messaging, and Microsoft’s legacy Windows Phone Notification Service. Email is distributed via Sendgrid. Everything in the current Glassboard architecture is housed in a single Visual Studio solution with about 36 C# projects in it. It’s *a lot* of code to manage. Luckily it’s also well tested, which makes it easier to manage. ### Current Notification Role Issues There are a few technical and ideological issues I have with the current notification architecture. To send messages between the web role and the attachment processor and notifications roles, I use [Azure’s Storage Queue](http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-queues-20/?ref=justinw.me#what-is) mechanism to pass messages. When you post a message to one of your boards, the web role generates a new XML payload in one of our storage queues that the Notification Role listens for to handle the processing. Sometimes this queue and the processing gets extremely backed up. Usually the CPU usage spikes to around 90% or higher for long periods of times which can lead to message postings being delayed for several minutes (in some cases I’ve seen hours) at a time. This is no good, especially when building a messaging service. I’m not sure what the cause is for the spiking CPU other than a lot of delicate C# threading issues which I’m guessing are running amok. The other issue I have with the notification role is how much of the code for things push notification services is in-house built. At the time Glassboard was originally built a few years ago, there weren’t too many open source solutions for handling push in C# I’d imagine. I’m [fairly conservative](https://www.justinw.me/2014/03/21/how-i-evaluate-third-party-dependencies/) when it comes to third-party dependencies, but for things like push notification services there’s not much sense in maintaining your own code library to connect to the service when there are a few good solutions out there used by hundreds (thousands?) of startups and businesses around the world. They’re well implemented, battle tested, and code that is maintained by the community. Being on C#, that limits the amount of options I have for dealing with push providers. [PushSharp](https://github.com/Redth/PushSharp?ref=justinw.me) seems to be the main provider out there. ### The New Notifications Role Given that I’m not a fan of the C# threading model currently implemented, the amount of code used to power something that’s relatively simple, and the homegrown nature of many of the push wrappers we’re using, I made the decision to rewrite this portion of Glassboard’s architecture using [Node](http://nodejs.org/?ref=justinw.me). Hang on. Put those Buzzword Bingo cards away. I’m not a fan of rewriting for the sake of rewriting either. Ultimately, my decision to switch to Node is all about code management. I’m confident I can accomplish the goals of my notification roles with a lot less code using Node than C# thanks to it being a bit less verbose of a language and a variety of NPM packages I can take advantage of for handling APNS, SendGrid, and GCM. The less code I have to manage and maintain, the easier my job is as the sole developer of Glassboard. I don’t believe I will have any performance degradation in switching from C# to Node for this portion of the code either, though it’s hard to tell before actually writing the code. If anything, I’m optimistic that performance will improve. ### A Fork In The Road There’s two different ways I can approach handling push notifications being distributed through my new worker role. The first is to use these npm packages like [node-gcm](https://github.com/ToothlessGear/node-gcm?ref=justinw.me) and its similar ilk to distribute the messages myself like I have always done. The difference being mostly in the language being used (Javascript versus C#). The other option is to take advantage of Azure’s [Notification Hubs](http://msdn.microsoft.com/en-us/library/jj927170.aspx?ref=justinw.me) which will handle distributing the messages to devices for me. Notification Hub has some advantages that stand out to me: - It works with all the platforms I care about: APNS, GCM, and WNS. - It handles platforms I don’t care about, but might again someday: Kindle. - It does all the device feedback management for me so I don’t have to keep track of which devices I should be adding or removing (such as when a user installs or uninstalls Glassboard). - Tagging devices based on certain features seems appealing. For instance, I could tag all of a user’s devices by their UUID and then easily distribute a message to all their devices in one message. This all sounds great. Why not just do this? [Cost](http://azure.microsoft.com/en-us/pricing/details/notification-hubs/?ref=justinw.me). Notification Hubs are another cost layer on top of the existing charges I’m paying Microsoft for my cloud instances and storage. I’m still in ‘losing money’ mode with Glassboard, so I’m trying to be fairly conservative with my spending. Glassboard currently sends around 150,000 emails a day according to Sendgrid, but I have no idea how many push messages it sends because it has never had a way to track that sort of information. If I opt into Notifications Hub, I’m likely going to be out at least $200 extra a month, but that could also sky rocket to an even higher amount. Now you understand why I am giving so much important to [data and analytics](https://www.justinw.me/2014/04/08/data-analytics-that-matter/) these days. My gut says use Notification Hubs. My wallet says roll my own. ### Service Bus vs Storage Queues One last thing I’m still debating is whether to keep using Azure’s Storage Queues for managing the messaging between the different components in my cloud stack or to use the new-to-me [Service Bus](http://azure.microsoft.com/en-us/services/messaging/?ref=justinw.me) functionality, which looks to offer a few more features. The Notification Hub functionality Microsoft offers is powered by the Service Bus, which has me considering the switch. There are plenty of decent articles out there comparing [Service Bus vs Storage Queues](http://msdn.microsoft.com/en-us/library/hh767287.aspx?ref=justinw.me), but from a more abstracted level that leaves me still questioning which way to go. The conservative developer in me says keep using what I’ve already got because no major Service Bus feature stands out to me as a must-have right now. The liberal developer in me sees Service Bus as the more modern architecture that will likely be able to grow with me as Glassboard (hopefully) expands in years to come. Feedback certainly welcomed. ### Writing The Code Even though the core architecture of two worker roles and a single web role won’t change with this refactoring of Glassboard’s notification architecture, hopefully this has been at least a little eye opening in terms of how Glassboard is built, and how I envision it being built going forward. The obvious next step is to write the code, which I started earlier this week by writing the unit and integration tests for the new Node code base. Since I spend so much time in Visual Studio these days, I thought I’d give the [Node tools](https://nodejstools.codeplex.com/?ref=justinw.me) that Microsoft released a try. Then I remembered that while I love what Microsoft is doing with the cloud and Azure, Windows is still Windows. > Never stop being Windows, Windows. [pic.twitter.com/33NI4UsLHZ](http://t.co/33NI4UsLHZ?ref=justinw.me) > > — Justin Williams (@justin) [April 16, 2014](https://twitter.com/justin/statuses/456269015917133824?ref=justinw.me) ### Data Analytics That Matter URL: https://www.justinw.me/blog/data-analytics-that-matter/ Last updated: 2014-04-08T19:00:02.000Z Data analytics gets unnecessary grief. When most people think of analytics, they envision Google or Facebook following your every move on the web to figure out what sort of ads to show you while you are browsing. This is pretty creepy. Admittedly, it’s pretty easy to shift over to the creepy side of analyzing user data, but that doesn’t mean that all data analysis is bad. In fact, it is essential if you want to run a successful product. When I took over [Glassboard](http://glassboard.com/?ref=justinw.me), there wasn’t that much data on how the service was being used. None of the apps used analytics, and the server side generated a basic report that contained some basic vanity analytics such as user signups, boards created, statuses posted, and the like. This is interesting information to notice from high-level analytics like user signups growing or dropping off, but it doesn’t tell us *who* is using the service or *how* they are using it. ### Why Analytics Matters *Who*, *how* and *why* are the most important questions you want to answer when you are starting to work with data analytics in your mobile products. - **Who** answers what the current audience for your product is. Your audience dictates how you should charge, what features you should add, and what marketing opportunities you may have as well. If you don’t understand who your audience is, pricing and targeting becomes really difficult. - **How** answers what ways users are using the product. Are you primarily getting users on Android? iOS? What’s the breakdown of iPhone vs iPad? How’s the web app doing? You want to put most of your attention on the platforms people are using, so knowing how people are using is important. - **Why** answers the reasons that someone is actually using your service. This one is a bit more difficult to gather without crossing the creepy line, and I’d argue its less important than the first two. There’s ways to gather this information without crossing the creepy line, which I’ll cover later on. ### Choosing an Analytics Provider Choosing an analytics provider is important. I have two rules for it: 1. You should be paying them money. 2. They shouldn’t be using your data for other things like selling ads. Since Glassboard is an inherently private service by default both of these are essential. All of our board information is encrypted on the servers so that prying eyes can’t pry. I want to understand my user base (in an anonymous fashion), but I don’t want those users to be pawns to be used for a marketing company to sell ads off of. Right now I am using Localytics, but I’m in the process of switching to [Keen](https://keen.io/?ref=justinw.me), because I haven’t been getting the value out of Localytics to justify its $500 price tag. Keen’s pricing and feature set seems much more promising to me. Mixpanel is probably the other major player in the mobile analytics game. They offer some powerful functionality as well. Each of these services is going to likely run you into the hundreds of dollars range if you have a marginally successful application. The obvious goal is to be able to use the information you garner from these analytics providers to make informed decisions to help you grow your app’s reach and in turn drive more revenue your way. ### Vanity vs Useful Analytics If you’re just focusing on the vanity analytics such as how many users you have, it’s very unlikely that you’re going to get your money’s worth out of any third-party service. What do I consider vanity analytics? - Active users - Usage regions - Amount of a certain type of data created daily - Device breakdowns between iPhone and iPad This is useful information, but it’s also pretty easily to generate yourself for much cheaper. Alternatively, it’s something you can just check periodically rather than something that needs care and attention on a constant basis. The real power of analytics comes when you start to understand how your customers are using your app. - How long are they staying in it? - How many people are viewing your upsell prompts? How many are converting? - What’s the average time between a new user signup and the time they start paying for the product or service? You get the idea. These are hard questions to ask and creating the tools to generate that sort of data is non-trivial. But, when you can start to understand how long someone is staying in your app, you can start to adjust the design of the app to either increase or decrease that engagement. If you aren’t getting a high enough conversion rate on your premium upgrades, you can start tinkering with the wording or page layouts to see if that will either increase or decrease your conversions. If you’re getting a bunch of non-paying free users, you can use data to start to understand why they aren’t paying. Maybe your free plan is too generous? Maybe they are just downloading the app and never using it after that first launch? Maybe they are just cheap? ### Analytics Through Customer Feedback Automated usage analytics is a useful metric to have, but far more useful is understanding your user base personally. When I first took over Glassboard, I didn’t really understand who the user base was. I knew how big the active base was, but in terms of who was using the product? It was just guesses and assumptions. The first thing I did when Sepia Labs handed over the keys was to send out a short user survey using [Survey.io](http://survey.io/?ref=justinw.me) to all of the existing premium users to introduce myself as the new owner of the service and to get an understanding of how they were using the product. Glassboard’s premium user base is far smaller than our free customers, but since this is a bootstrapped company, they are the more important customers during the acquisition. I wanted to understand how the people who supported the service in the past were using it so I can continue keeping them happy going forward. Our premium user survey had a 70% response rate, which was insanely high. It shared with us a lot of useful information about how Glassboard is being used (many ways I didn’t even imagine!) as well as what alternatives people would consider, which is a pretty good way to learn about some different competitors you may not have heard of. Another thing I implemented when I took over Glassboard was a ‘personal’ email that is sent out to users a few days after they sign up. It comes from my email address and is basically a prompt to gather direct feedback from our newest users. > Hi \[John Doe\], > > I’m Justin Williams, the CEO and lead developer of Glassboard. I wanted to see how things are going so far. > > If you have any questions, feedback or need help with anything at all, reply to this email and I will get back to you with a personal reply. > > Thanks again for using Glassboard! I receive a few responses a day from this, which has been really useful for understanding who is signing up for the service, how they are using it, and (most importantly) what they are finding confusing or hard to grok about Glassboard. By far the biggest source of frustration these new users have is the onboarding experience. When you sign up for a new Glassboard account through the apps, it creates your account and your first board called “\[Justin’s\] Board”. It then drops you into an empty news feed. Hardly ideal. The feedback I’ve received from many users is that they are confused at this point, which is really good personal data. It shows that I have an opportunity to improve the onboarding experience to hopefully receive a more positive response about functionality in the future. We’re working on it now. ### Always Keep Tweaking I’ve been sending the email above for the last few months, and the value from it has diminishing returns at this point. I’ve recently noticed a pretty major influx of new users coming onto the service, but I don’t really have a good idea *where* they are coming from right now. I’m thinking my next goal for these new user signup emails will be to just plainly ask users to tell me where they heard about Glassboard and what they are using it for. I may get less of a response back, but the data that does come in will be interesting to see if the understanding I have of my audience from earlier this year still matches the new users signing up as of April 2014. Data is only as useful as it is current. Long-term trends are meaningful in some use cases, but when you’re in the middle of trying to turn around a ship as big as Glassboard, the past isn’t nearly as important as the present. Understanding your current users is essential to being able to build and sustain a successful product in this new app economy. ### Build 2014 URL: https://www.justinw.me/blog/build-2014/ Last updated: 2014-04-07T19:00:42.000Z I spent last week in San Francisco at [Microsoft’s Build](http://www.buildwindows.com/?ref=justinw.me) conference. Build is an annual (at least I think it’s going to be) event the company holds at Moscone West to share their latest offerings for Windows, mobile, and Azure. I’m not a developer for any of the Windows platforms. Glassboard, however, runs on Microsoft Azure so I was interested in attending both to learn about the new offerings and to put some names and faces together with people I’ve started interacting with recently. Overall it was a positive experience as someone who only recently dipped his toes back into what Microsoft is doing recently. The last time I used (or even cared) about Microsoft technology was the late 90’s when they were a giant, evil corporation who was charged with being a monopoly. I switched to the Mac when OS X was announced in 2000 and hadn’t really touched since. Fast forward 14 years later and Microsoft seems to be a whole new company. New products. New CEO. New development offerings. And less of a focus on Windows, Windows, Windows. Sure, Windows is a key part of the Microsoft ecosystem (and rightly so), but it also no longer seems to be the central focus that directs everything they do. I sat through two **THREE HOUR** (emphasis mine because oh my god so long) keynotes that prominently featured iOS devices, the Apple logo, iPads, Androids, and even Linux. A few years ago this was the company that dismissed iOS as a failure to launch and instead focused on how they could go from a Windows computer on every desk to a Windows Phone in every pocket. Windows Phone is still a key piece of technology for them (and 8.1 looks great), but they realize that integrating their *services* into the other platforms as first-class citizens is [best for business](https://www.youtube.com/watch?v=EpO-IOrIQbY&ref=justinw.me). Whether this was a plan set in place by Ballmer before he left, or new under new CEO Satya Nadella’s watch I don’t know. As an outside just starting to look in, however, it’s refreshing. ### A True Partner One of the biggest differences I noticed between an event like Build and WWDC was in the subtle messaging. Both Apple and Microsoft are massive companies that make billions of dollars and answer to their shareholders. Both companies also offer development platforms for third-parties to integrate with. What’s different though is that it feels like Microsoft is more interested in *working* with us as a partner whereas Apple has always given off a vibe of just sort of dealing with us because they have to. Maybe that’s a little sour grapes, but as a developer it was a nice change. Build was announced far in advance allowing people ample time to schedule and book their travel. Microsoft released the full schedule of the event the night before so you could plan your week out in advance (or just decide to wait for the videos later on). They even provided previews (and access) to upcoming technologies that aren’t ready just yet, but to give us an eye on where they see things going. It was cool to get a free Xbox One to play Titanfall on, but they also had several sessions during Build that talked about how to actually build an application that can run on that Xbox so that when the time comes that they release a full SDK and support for that, developers will be ready. They provided that to *everyone*, not just a few select partners that also share a stock ticker symbol. ### Open Source Microsoft isn’t exactly a showman company. The keynotes were well presented, but they also lacked the pizazz of an Apple event where everything feels as cool as a night out with [Frank and Dean](http://en.wikipedia.org/wiki/Rat%5FPack?ref=justinw.me). The one area where I sat up and thought “OK, that was cool” was when [Anders Hejlsberg](http://en.wikipedia.org/wiki/Anders%5FHejlsberg?ref=justinw.me) publicly open sourced the new Roslyn C# compiler platform on the Keynote stage at the end of his demo. [Roslyn](http://roslyn.codeplex.com/?ref=justinw.me) is a key piece of technology for the future of Microsoft and they’re now managing it as an open source project. This allows for a few things: outside contributions and feedback on the platform from fellow developers for one. More importantly, it allows the Xamarin folks who had implemented their own C# compiler to work on [MonoTouch](http://xamarin.com/ios?ref=justinw.me). It’s now possible for Microsoft and Xamarin to collaborate together on a single compiler rather than both building in parallel. Apple has the LLVM project, which is similar in many ways, but I also can’t imagine them working with a third-party vendor such as RubyMotion (for lack of a better example) to make their jobs easier. I still hope that some day Apple will open source the core iOS and OS X frameworks the same way Microsoft does with .Net and Google does with Android. I’m not holding my breath, but I can dream. Overall though, Microsoft seems to be embracing open source in new and interesting ways that the old Microsoft never seemed to care about. Previously when they open sourced a piece of technology it’s because they were no longer interested in it. Now, key pieces of functionality that the future of the company is based on are out in the open. ### Bizarro WWDC A week or two before Build, I received a text message from [Dave Wiskus](http://betterelevation.com/?ref=justinw.me) of Q Branch/Vesper asking if I was still attending Build. He then informed me that he, [Gruber](http://daringfireball.net/?ref=justinw.me) and [Brent](http://inessential.com/?ref=justinw.me) would be attending the conference as well as part of the keynote. 2.5 hours into the second day keynote, lo and behold my long-time Mac and iOS development friends [showed up on a Microsoft stage](http://channel9.msdn.com/Blogs/Windows-Azure/Learn-how-Vesper-built-offline-sync-using-Azure-Mobile-Services-?ref=justinw.me) talking about how Vesper’s sync services are powered by Microsoft Azure. None of those guys are Windows users. None of them are Windows Phone users either. They’re happily using Microsoft’s cloud services platform to power the backend of their iOS only app. It was a bit surreal to experience Moscone West with a few other long-time WWDC attendees and compare how similar (and positive) our experiences seemed to be. Outside of there being a DJ spinning house beats above a sea of coding nerds on level 2, we came away impressed. ### Showing The Other Side > Kind of excited that [@justin](https://twitter.com/justin?ref=justinw.me) and [@gruber](https://twitter.com/gruber?ref=justinw.me) and [@brentsimmons](https://twitter.com/brentsimmons?ref=justinw.me) are all doing high-visibility Microsoft stuff. Competition is good. > > — Michael Yacavone (@notio) [April 4, 2014](https://twitter.com/notio/statuses/451904583166857216?ref=justinw.me) If you follow me on [Twitter](https://twitter.com/justin?ref=justinw.me), you were probably pretty tired of seeing me tweet things with hashtag *#bldwin* (you’re lucky I was kind enough to hash them so you could mute if desired). The reason for the excess tweeting was twofold: First, I tweet a lot anyway. Second, and more importantly, I know my audience is primarily filled with Mac and iOS developers. We’re all fairly busy people and may not always look up to see what is happening outside of the Apple ecosystem. Build allowed me three days to immerse myself in technologies that I know almost nothing about. I came away impressed with it too. For all its past faults, the *New Microsoft* is doing things that are on the cutting edge of technology. Their [Rx extensions](https://rx.codeplex.com/?ref=justinw.me) library is everything I hope ReactiveCocoa could be: a fully functional extension to the core C# language built and maintained by Microsoft. Their unit and integration testing story for Windows Phone is light years beyond what either Apple or Google offer for their respective mobile platforms. ### Avoiding Longhorn 2015 John Siracusa has a famous article called [Copland 2010](http://arstechnica.com/staff/2005/09/1372/?ref=justinw.me) where he talks about Apple’s need to begin looking for a replacement for Objective-C and the Cocoa frameworks before they get to the point where it’s too late and they’re in for several years of hurt much like the transition from Classic Mac OS to OS X. I still love Objective-C and the Cocoa frameworks, but having worked on Glassboard’s Azure backend and Android app in parallel, I’ve seen a different world outside of the Apple prism. What we have is good, but there’s so much more potential to be *great* with the emerging and more modern development technologies out there. With things like C#, the Roslyn compiler/frameworks, and the modern WinRT runtime, it feels like Microsoft is way ahead of Apple in the future looking regard. As a developer, I’m jealous of a lot of the technologies coming out of Microsoft. As a user? They’ve got a long ways to go before I consider using Windows over a Mac. That said, this is the new Microsoft. They don’t *need* me to use Windows or Windows Phone as long as I use Microsoft *services* like Azure, Office 365 and the like. I can’t believe I’m excited about and interested in working with so many Microsoft technologies. The times are a changin’. ### The Parts of Your Platform URL: https://www.justinw.me/blog/the-parts-of-your-platform/ Last updated: 2014-03-26T19:00:29.000Z The simpler devices get, the more complex our jobs as developers becomes it seems. When I first started my independent developer career way back in the dark ages of 2006, building an app usually meant building a desktop product that persisted data locally. In some cases there was an Internet backed service tied to it, but it wasn’t the norm. This was before Dropbox, people. If you truly wanted Internet connected services, you built web apps. Using a mix of HTML, CSS and a sprinkling of Javascript you could build web pages that could replace your desktop apps with something that could run on any device and any browser. Once mobile came on the scene, web apps weren’t as ‘sweet’ a solution as some would have liked us to believe. The pendulum swung back towards native app development, but with the added bonus of being network connected at all times. For an app that connects to a third-party service such as Dropbox or Twitter, always-on connectivity means implementing a third-party API in your app and using that as the foundation for your data access. It’s a little more work than our desktop days, but certainly not that big of a hassle. Fast forward to 2014 and you’re starting to see convergence of mobile and those web technologies. Mobile apps from smaller developers are starting to offer online services either as a value add (such as the wonderful [Day One](http://dayoneapp.com/?ref=justinw.me) app) or as the foundation of the service (such as [Glassboard](http://glassboard.com/?ref=justinw.me) or soon-to-be from [Vesper](http://vesperapp.co/?ref=justinw.me)). Mobile apps requiring their own custom backend data isn’t new for many operations, especially those with a large staff and a bankroll of venture capital money to burn. For the mom-and-pop shops like Second Gear and Q Branch, it’s a whole new world that just became more feasible just recently. So, what changed? #### App Pricing And Expectations When I released Photos+ last year, one of the biggest sources of feedback I received was “where is the iPad version?” Nevermind that I just spent several months perfecting the iPhone version, consumers expected that the app would be run on all their iOS devices. Beyond just expecting your app to run on both an iPad and iPhone, users also expect that data to sync effortlessly between those devices. Implementing that amount of functionality isn’t impossible, but at $2.99 per app or so it becomes really hard to make the economics work in your favor. If you can instead sell a service for a monthly or yearly fee, however, and then give the apps away for free it becomes a bit more feasible to make the economics work. Still difficult, but at least less of a crapshoot. #### The Cloud! Everything is in the magical Cloud now. All your files are on Dropbox. All your photos in Photo Stream. Everything else in Evernote. Cloud computing has eliminated the need to be a sysadmin and host your own server hardware in favor of *renting* resources in the cloud. Amazon, Microsoft, and Google are the big three and are all jockeying to lay claim to all the CPU and storage on the web. Glassboard runs on exclusively [Microsoft Azure](http://windowsazure.com/?ref=justinw.me). All user data is encrypted and stored in Azure Table Storage. Images and videos live in Azure Blob Storage. The actual platform app itself runs on an Azure Cloud Service, which makes scaling as easy as adjusting a few sliders on the Azure web site. #### Backend as a Service Take the cloud computing paradigm, and simplify it even further and you get Backend as a Service. With a BaaS provider such as Parse, Google App Engine, or Azure Mobile Services, you don’t even have to worry about provisioning resources on the cloud. Instead you just import an API wrapper into your mobile app and configure a few cookie cutter options on the BaaS provider’s web site. These providers make cloud-enabling your product incredibly simple. The tradeoff of using one versus the more traditional ‘cloud’ is that costs rise exponentially much quicker. It’s a tradeoff that many are willing to make, plus competition has made pricing a bit more competitive than it was even just a year ago. ### The Parts of a Platform We’ve accepted that running our own server-side resources is becoming a reality, we should analyze what that really means. And more importantly, understand what is involved. ### 1\. The API The brain of that powers any cloud-enabled service is its API. It doesn’t matter what language you write it in as long as its secure, stable, and reliable. Glassboard started out as a full C# product, but I’ve been rewriting parts of it in Node where it makes sense. Most of the time your users won’t see your API firsthand, unless you offer it publicly as a value add to your customers. Whether it’s a public API or not, versioning from the start is always a good idea. You’ll inevitably get to the point where you want to add or change your API’s functionality. By versioning your API from the start, you can ensure that legacy clients aren’t immediately cut off as you improve your product. If you’re running a marginally successful service on an API, it’s worth your financial and time investment to look into services like [New Relic](http://newrelic.com/?ref=justinw.me) and [Runscope](http://runscope.com/?ref=justinw.me). New Relic does magic things to figure out bottlenecks and other slowdowns in your API clients. Runscope is an API monitoring service that lets you test the health of your API as you run a suite of tests against it. ### 2\. The App(s) Whether its iOS, Android, Windows Phone, or OS X, the app is the nut of any platform. It’s what your consumers will predominantly use to interface with your service and will shape their opinion on it. This is likely going to be where most of your time is spent, assuming you want to build something that stands out in such a crowded market. There are plenty of hybrid app solutions that can get you on all platforms quickly, but quick doesn’t necessarily mean quality. Glassboard has native [Android](https://play.google.com/store/apps/details?id=com.sepialabs.glassboard&ref=justinw.me) and [iOS](https://itunes.apple.com/us/app/glassboard/id453661198?ls=1&mt=8&ref=justinw.me) clients. Each one is built using the system-specific APIs and designed to look and behave like a first class citizen on their respective platform. It’s far more work (and cost) than the hybrid approach, but I believe a better app experience in turn leads to a better conversion rate to paying customers of the service. ### 3\. The Management Backend This is the one most people forget. Once you’ve developed your API and built the app(s) to consume it, you likely have a user base that is going to be emailing in support requests and bug reports. Those requests likely mean you need to look into the data stored on your backend. You aren’t an animal. Running raw SQL queries from the Terminal is neither safe, nor ideal. You need yet another app for your platform. The only difference is that this one is for internal use only. The admin portal is the piece that most developers forget about until after they’ve shipped, but it can also be one of the most important part of your product once you reach a level of success. Let’s imagine you outsource your support to a third-party company (I recommend and use AptFolk). Ash and crew are a smart group, but they don’t know the internals of your product or how to connect to your servers. Nor should they need to. By offering a web or mobile app that allows them to look up and adjust account information or whatever else is relevant, you’re making your job easier. Beyond just support, metrics are essential to measuring success or failure. There are simple vanity metrics that are useful for showing on an app like Status Board: - Daily signups - Active users - \[Your Specific Data\] created - Daily/Weekly/Monthly Revenue For more advanced metrics, I recommend a third-party provider that specializes in things like customer segmentation, funnels, and other more advanced functionality. I use [Localytics](http://localytics.com/?ref=justinw.me), but I’m actively shopping for an alternative. [Mixpanel](http://mixpanel.com/?ref=justinw.me) is also a nice service, but gets expensive real quick. ### Every Piece Matters The good news is that even though our jobs as app developers is becoming more all-consuming, the tools that enable us to do this are becoming far easier to use. I couldn’t imagine running my own servers back in 2008, and now I don’t have to. Cloud computing takes care of the heavy lifting and let’s me focus on the product itself. Just because I don’t have to worry about imaging and provisioning servers doesn’t mean I can slack on other parts of my product’s development cycle. The API, apps, and backend platform are all equally important pieces of the puzzle that defines your product. The app may be the only public facing one, but without the API it doesn’t exist. Without the backend management portal, supporting your user base becomes a nightmare that impedes development. Treat each piece of your product’s stack like it’s the most important, user facing portion bit. Quality isn’t just mean for the surface. ### The Full Stack App Developer Whenever I look at job boards, I notice that a lot of web development jobs are wanting someone who is a ‘full stack’ web developer. To me, that means someone who can build the front end of the application using HTML, CSS, and Javascript as well as the backend using whatever server-side framework is in there. To top it off, sprinkle in a bit of knowledge on cloud computing. The ‘full stack’ paradigm is starting to make its way to app development going forward as well. It’s no longer enough to just know how to write code for a single platform. To be truly relevant and valuable you need to have an understanding of API design and implementation and cloud computing as well. Ignoring the cloud or web services because they are out of your comfort zone is no longer an option. The app economy is shifting. Adapt or die. ### How I Evaluate Third-Party Dependencies URL: https://www.justinw.me/blog/how-i-evaluate-third-party-dependencies/ Last updated: 2014-03-21T19:00:36.000Z > How do you manage your iOS app dependencies? This is a question I’ve answered more than a few times the past few months. Answer: **with as few third-party dependencies as possible.** A bit cheeky, yes, but there’s truth in it. As I’ve matured as a professional developer, I’ve learned to understand that a dependency and liability are many times interchangeable. In general most of the projects I work on have as few third-party dependencies as possible. I do my best to work with what is provided by Apple’s frameworks, as well as my own suite of categories and subclasses I’ve accumulated over my years as a developer. When something new and shiny comes along that I’m thinking about using, I have a few questions I ask before making a decision. #### 1\. How long would it take me to write my own version of this? Are we talking about a single class and header file that does something fairly basic that I could churn out in a few hours, or something more feature-filled and complex that is represents weeks or months of work. Single classes I am more than likely to write on my own. Something heavier like [CocoaLumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack?ref=justinw.me) (which is awesome) I am likely to include as a dependency. #### 2\. How well maintained and supported is the codebase? Is the project actively maintained by a developer, or are we just talking about a code dump that’s just been thrown on GitHub? Is there documentation? At a minimum, is there header docs? Open source contributors are under no obligation to provide support for their projects, but at the same time, I’m less comfortable basing a major part of my project on something that’s just out there on the web without any direction. Projects like [AFNetworking](https://github.com/AFNetworking/AFNetworking?ref=justinw.me) and [ReactiveCocoa](https://github.com/ReactiveCocoa/ReactiveCocoa?ref=justinw.me) come to mind as good, well moderated open source projects. Sidenote: It bugs me when people look at a codebase that hasn’t been updated in a year and claim it’s been *abandoned*. Projects can be *completed* without being considered abandoned. #### 3\. Can I understand the code base enough that I’m comfortable patching/contributing to it? All software has bugs. Even yours. With a third-party code base that you don’t manage, you are likely going to run into a situation where there are bugs that need to be fixed and patched. How comfortable am I reading and understanding the code base that I am thinking about adding as a dependency? If it’s not comfortable enough that I’d be willing to patch it, I’m may not be willing to include it. One exception to this is the HockeySDK and PLCrashReporter. I have zero idea how that stuff works because I am not [Landon Fuller](http://landonf.bikemonkey.org/?ref=justinw.me) or [Mike Ash](https://www.mikeash.com/pyblog/?ref=justinw.me). I think they actually speak binary as a first language. Even thought I don’t understand the internals, I depend on Hockey for managing my betas and crash reports. Wonderful service. #### 4\. How much of this code will I actually be using? A lot of developers have the tendency to instantly import [AFNetworking](https://github.com/AFNetworking/AFNetworking?ref=justinw.me) into their project without a second thought. It’s a wonderful resource for the community and something I have used in my own projects. At the same time, it’s a fairly heavy library that does a lot. If you’re building an API wrapper for a third-party web service, do you really need all that AFNetworking offers or are you just using maybe 10% of its features to accomplish your goal? More importantly, if you are offering the API wrapper for consumption by the open source community, do you really want to force another third-party dependency on them? With [OvershareKit](https://github.com/overshare/overshare-kit?ref=justinw.me), Jared and I try to err on the side of conservative when it comes to adding external dependencies to the library. As is, it’s a pretty heavy amount of code to ingest in your project. But, most of it is self-contained which we see as a feature, not a bug. ### So….about Cocoapods I have been hesitant to adopt [Cocoapods](http://cocoapods.org/?ref=justinw.me) in any of my iOS projects these past few years. I’ve also been pretty vocal about this, but without much explanation. If you look at any other major platform in play today, they have some sort of dependency management story: - Node has npm - .Net has NuGet - Ruby has Gems - Android has Maven and Gradle Dependency management is admittedly a problem that OS X and iOS have dealt with for years. So, Cocoapods comes along and offers a solution for the problem, but I don’t want to jump on it. Why? For one, stability and predictability. The dependency systems for every other platform are for all intents and purposes the “official” solution. In some cases such as NuGet, they’re even baked into the IDE. Cocoapods, on the other hand, is developed outside of Apple by the community and hacked into the current Xcode workflows. That’s not to insult the developers of the project. It’s pretty impressive what they’ve made from a technical standpoint. But as cool as a project is, that doesn’t eliminate the inherent risk with using it. Let’s assume that Apple releases an amazing new Xcode 6 this summer. It has all these amazing features that you absolutely have to use. The tradeoff is that because of so many changes under the hood of Xcode, Cocoapods is now broken and your app is no longer capable of building with the new toolset without a lot of surgery. On a lesser level, let’s say Cocoapods switches from Ruby based spec files to another format (JSON?). Now I’ve got to spend client time just fixing my build system, which isn’t adding much value to their product. Are these scenarios this likely to happen? I hover somewhere between ‘maybe’ and ‘probably not’. ### Contracting vs Personal Projects Having described how I analyze third-party dependencies and my thoughts on Cocoapods in general, I will say that I am now using it in [Glassboard](http://glassboard.com/?ref=justinw.me). Wait. Didn’t I just say it’s risky to use? Well, yeah. But dealing with risk is a key part of software development. You have to find your personal threshold and work with it. In my case, I’m not willing to stake the dependency management of a project I’ve been contracted to build by a client on a third-party platform that generates Xcode workspace and project files on the fly and may prevent the app from building cleanly without a 5+ step setup process. For my own projects, however, I’m much more liberal in my choices. Let’s say the mythical Xcode 6 build breakage occurs in Glassboard. It will suck, but it’s a problem to resolve in my own product, on my own dime rather than someone else’s. My personal projects likely also have a longer shelf-live than most client engagements where the codebase evolves over time. Glassboard’s code base is over three years old and is still evolving. Many of my client engagements are to build a shippable version and then move on to the next thing. There’s likely to be a lot of built up bit-rot after a project sits dormant for an extended period of time. Dealing with that rot is part of contracting as much as it is your own projects, but I do my best to limit the amount of rot I put on myself in those client engagements. I apply the same ‘client vs personal projects’ principle to third-party code dependencies as well. I’ve taken to using the *#GlassboardNext* codebase as my playground for experimenting with new third-party projects like Cocoapods, ReactiveCocoa, and [Mantle](https://github.com/MantleFramework/Mantle?ref=justinw.me) even though I can’t imagine a scenario where I’d currently use them a client project (well, maybe Mantle. It’s pretty isolated.) It’s possible these choices will come to bite me in the ass eventually, but they’re risks I’m willing to take. *I’m assuming this post will get my invitation into the “Old Guy Coders Club” where you hate anything you aren’t used to. I’ll be waiting for my coffee mug and membership card in the mail.* ### The Auteur Theory URL: https://www.justinw.me/blog/the-auteur-theory/ Last updated: 2014-03-13T19:00:14.000Z You’re likely sick of hearing about the show “True Detective” by now. Like millions of others, I became engulfed in HBO’s latest 8 hour masterpiece over the last few months. Plenty has been written about the [Yellow King](http://en.wikipedia.org/wiki/The%5FKing%5Fin%5FYellow?ref=justinw.me), Big Hug Mugs, and Matthew McConaughey’s amazing performance as Rust Cohle. What I haven’t seen get nearly as much play is how the show is actually created. It wasn’t fully aware to me until the 4th episode’s 6 minute [long take scene](http://log.carpeaqua.com/post/76304206721/willw-true-detective-who-goes-there-long?ref=justinw.me) (Spoilers behind that link). It was riveting the first time I saw it. It was even more amazing when I discovered it was done in a single take. As I read up on the show I learned that the entire eight episode season was written by a sole writer (show creator Nic Pizzolatto) and directed by a single director (Cary Fukunaga). Traditionally TV shows are helmed by a cast of behind the scenes folks who take turns at writing and directing different episodes. With True Detective, a true auteur theory was allowed to play out on screen. One writer. One director. Eight hours of the best television I’ve seen in a long time. The best creative works, whether they be TV shows, books, or apps, are the products of focus and vision. At Apple that was Steve Jobs and Jony Ive. WebOS had Matias Duarte, who has been doing wonders cleaning up the mess that was the Android experience. [James Dyson](http://en.wikipedia.org/wiki/James%5FDyson?ref=justinw.me) does it for vacuums. I just bought a Dyson and it’s a fantastic product. As I look at my iPhone I can name the person in charge of the vision for most of the apps on my home screen. Here’s a hint: most aren’t from large corporations that include the marketing folks and bean counters as part of the development process. They are from small development shops run by just a few people who have an idea of what their product should be and how it can impact the world. There are no focus groups or A/B testing. It’s just gut reactions and validating it with user response. Everyone has a role in the creation of a product (even the bean counters), but having one or two talented people charged with shaping the direction of the product results in something that people actually enjoy using and, more importantly, championing to others. Who knows? You might even make something that puts a smile on Rust Cohle’s face. OK, maybe not. ### The Profitability Test URL: https://www.justinw.me/blog/the-profitability-test/ Last updated: 2014-03-05T19:00:13.000Z Last week at Mobile World Congress Nokia unveiled the Nokia X, their first foray into the wild world of Android devices. On the consumer side, the sales pitch has been an affordable phone with all the great Android apps you love, just with Nokia and Microsoft services rather than Google’s. On the developer side, which was the obvious target of announcing this devices at MWC, the pitch was that it should take less than a day to port an Android app from using Google’s services for things like push and in-app purchase to Nokia’s. On the surface, expanding your product into a new market with minimal effort seems like a great idea. Once you dig a bit deeper, it may not be so easy to justify. Let’s say you have a product like [Glassboard](http://glassboard.com/?ref=justinw.me). Its core functionality is wrapped in a server-side component that you manage. The API is the key to everything else. It handles accounts, billing, data access, and all the notifications you need to send out. The other parts of the Glassboard platform are the client apps. In my case, there are currently three: iOS, Android, and the web. I ran Glassboard’s Android app through the [Nokia X Analyzer](http://developer.nokia.com/nokia-x/analyse/?ref=justinw.me) and had a pretty clean sheet. My biggest issues was replacing Google’s Cloud Messaging with Nokia’s offering. Here’s where we run into issues. Building a version of Glassboard that uses Nokia’s jars instead of Google Play Services likely isn’t that big of a hassle. The much bigger hassle is then adding support on the server-side to handle the [Nokia services](http://developer.nokia.com/resources/library/nokia-x/nokia-notifications/nokia-notifications-developer-guide/nokia-notifications-service-api-guide.html?ref=justinw.me). Now, the “just a day” pitch becomes much harder to justify. Not only do I need to update the Android app, I also now have a slew of C# tests and code to write so that I can pass notifications from Glassboard to Nokia’s servers in additions to Google, Apple, and Sendgrid (our email provider). ### Who Is The Market? Any time I have to add another code path to the API and server components of Glassboard I have to really justify the work that’s involved. There’s usually four things I consider: 1. Who is the target market? 2. What’s the current install base? 3. What’s the potential installed base? 4. Would you use this thing? The target market of the Nokia X is what the industry considers “developing nations”. The politically correct term is emerging nations because there’s plenty of room to grow, but the main point is that the Nokia X isn’t going to be on the store shelves in the US, UK, or Germany. With a brand new platform, the current install base is zero. That’s not necessarily a bad thing as every platform starts from nothing at one point. In many cases, there’s a first movers advantage you can take advantage of. That first movers advantage depends of course, on the potential installed base. This one was a toss-up for me. On one hand, Nokia is poised to put this in dozens of markets with millions of potential customers at an affordable price. On the other hand, Nokia is about to get sucked up by Microsoft who could snap their fingers and kill this project pretty easily. That’s a big risk. The final question is more personal than business. I have always built software for myself, so asking if I would use a Nokia X is an important question. I’m curious about the device and would like to give it a shot. Would it be my main Android device? I’m not sure. I marked this one as a “maybe” rather than a hard yes or no. ### Can You Make Money? Once you’ve answered those four questions, you should be able to answer the most important question pretty easily: can you make money on the platform? More importantly, can you make enough money to justify the extra investment of time and resources in supporting it. With Glassboard, my current belief is that no, I can’t. Glassboard lives and dies by the amount of people that pay for some sort of premium subscription through the service. Since we have zero outside funding, the amount of users we gain isn’t an important metric. I’m confident that I could add several thousand free customers to Glassboard’s active user base by porting to the Nokia X. I’m much less confident that I can convert a decent percentage of those into folks that would be willing to pay for the service on a monthly or yearly basis. That’s one of the key differences in running your company as a traditional business. Being on every platform is great if you’re a venture funded startup. If you’re bootstrapping, however, growth isn’t necessarily a good thing unless the financials are there to back it up. You have to analyze each different platform as a liability and justify whether its worth pursuing. ### Simplifying Towards Profitability This isn’t the first time I’ve had to do this sort of liability analysis with Glassboard. When I acquired the service, it was available on two additional platforms: the Kindle Fire and Windows Phone. I made the decision to kill both of these products for many similar reasons that I’ve opted not to tackle a Nokia X version at this time. In the case of the Kindle Fire, the active user base wasn’t nearly enough to justify the continued investment. None of our premium customers were using the Fire version and that version also wasn’t equipped with any existing in-app purchase functionality, which meant I’d need to write more code myself. That decision turned out to be the right one. I believe we’ve gotten maybe two total complaints about pulling the Fire version in the three months since it occurred. The Windows Phone version of Glassboard was similar to the Fire in some aspects. The active user base wasn’t anywhere near the iOS or Android apps, but a decent chunk of the server components were already there. I’d have just need to add support for in-app purchasing to start upselling users to premium, which wouldn’t have been that much effort. Ultimately the decision to kill the Windows Phone version came down to quality. It was not a good app. Given the small user base and the amount of time I felt it would take to make it an app I would be proud to showcase, pulling it from the shelves was the right move. We get a few requests for a Windows Phone version a week still, so I believe there is some sort of market there. Whether they’re willing to convert to paid customers remains up in the air. ### Focus on the Financials As enthusiasts, it’s hard to avoid to allure of the new shiny. Updating an years old app to look and feel like an iOS 7 app makes sense as someone who loves to play with the latest stuff. Spending those days or weeks doing that conversion may not make financial sense if the product isn’t making enough money to justify the development time. The same can be said for services such as Glassboard, and perhaps at an even higher level. With a freemium model, you have to think about every move in terms of its ability to convert free customers to paying ones. Free users are loss-leaders. If you have too many of those loss-leaders, you may have a popular product, but you don’t have a successful business. ### Getting Good At Making Money URL: https://www.justinw.me/blog/getting-good-at-making-money/ Last updated: 2014-02-26T19:00:44.000Z If there is one thing I don’t think I excel at as a business man, it is making money. That’s probably not a good thing to admit publicly, but it’s reality. In fact, I’d argue that I’ve gotten *worse* at making money in the past several years as the third-party software market has bottomed out. Making money was hard enough selling $25-$40 products. Try doing it when your most expensive app is $4.99. The first step towards recovery is admitting you have a problem, and this is one that I am working on this year as I am steering [Glassboard](http://glassboard.com/?ref=justinw.me) towards its next phase of life. I have to. This was December and January’s membership revenue and operating expenses: ![Revenue vs Operating Expenses](https://i1.wp.com/cdn.carpeaqua.com/images/making-money/chart.png) I won’t share the exact dollar amounts, but yikes, right? If there’s any solace in those numbers, I was able to make a decent amount of progress between December and January in cutting costs and raising revenues. Making money is harder than it seems. Most people assume you put a product out and people instantly find and support it. The reality is that for most products, they first struggle to find an audience, and secondly struggle to find an audience that’s willing to pay. I have an inherent advantage by having a decent online following, which gives me nice starting ground of users to sell my wares to, but that’s by no means a guarantee of success. The goal of making money is to convert people outside of that base into paying customers. That is a problem I’m hoping to solve sooner rather than later. So, how do I get good at making money? There’s a few different ways I can approach it. ### Use Someone Else’s Money This is what I’d argue is the ‘standard’ way of doing things when you are running a multi-platform service such as Glassboard. You spend a decent amount of time building a pitch deck and shopping it around to a variety of venture capitalists who will hopefully provide you with enough money to give you the resources you need to grow. This is the least appealing to me for a variety of reasons. For one, raising money is a full-time job and any time I spend running around begging people to write me checks is time I’m not spending on the product. Second, I don’t see it as a good fit for the type of business I want to run. Venture capital is for people who want to grow something to Instagram or Tumblr levels. Getting funding for something that VC typically (and insultingly) refers to as a “lifestyle business” is far harder. Glassboard, by design, isn’t designed for those insane levels of scale. And finally, I’m personally averse to the whole racket of venture capital. [Entrepreneurs are the new labor](http://www.forbes.com/sites/venkateshrao/2012/09/03/entrepreneurs-are-the-new-labor-part-i/?ref=justinw.me), especially when old guys with money are funding the sweat of someone who gets to put “founder” on their business card. I’d rather not participate in that. VC is a nonstarter. ### Cutting Costs The easiest way to make money is to spend less of it so that your monthly profit-loss is heading in the right direction. By cutting costs, it’s easier to approach the break-even or profitable point. This is the way I have been approaching Glassboard so far into my tenure. The existing service had quite a bit of fat on the edges that could be cut without impacting the service in a negative way. Some of the things I did were: 1. Negotiate a new plan with [Sendgrid](http://sendgrid.com/?ref=justinw.me) to account for how much email Glassboard sends on a daily basis (well into six figures). This 30 minute meeting shaved over $1000 a month off my monthly expenses. 2. Disable email on any board that has over 200 members on it. There are not many of these high traffic boards, but they accounted for a heavy portion of our email traffic. I’ve had maybe 2 complaints about this since I changed it six weeks ago. 3. Optimize Glassboard’s [Azure Cloud Services](http://www.windowsazure.com/en-us/services/cloud-services/?ref=justinw.me) to dynamically scale the amount of instances it needs based on how much traffic is coming in. This shaved about 40% off the CPU costs on my monthly Azure bill. There’s still plenty I can do to cut costs, but that only solves a small portion of the equation. None of the remaining items on that list are on the low-hanging fruit/quick win list. The far more interesting opportunities are actually increasing the monthly revenue. ### Increase Revenue Duh, right? For apps increasing revenue can be done by raising your app’s cost, adding advertisements, or inserting some sort of in-app purchases. Every app is different, so it’s hard to offer a single prescription for success to everyone. I can only speak to my use case. For Glassboard, this is the hard nut to track because I’ve got tens of thousands of users who have been using a service for free that I have to figure out how to bring revenue in from. One of the first things I did was lower the cost of a Glassboard Premium subscription from $50 a year to $25\. There was no science behind this decision other than me personally not being willing to pay $50 a year for the service. $25 sounded much more reasonable for the existing offerings. I also added the yearly premium subscription to the iOS app as an in-app subscription, so that it’s easier for people to support the service. Neither of these changes set the world on fire. I sold more Premium subscriptions in two months than Glassboard sold in its previous two years of existence, but it was also at half the price. The more interesting metric I discovered was how many people weren’t even aware Glassboard had a paid offering. Since people primarily access it through the iOS and Android apps, they had never been prompted to pay for the service. I had more than a few complaints from people about adding the premium subscription as an option in-app. These are the folks I assume will never be customers. There’s still plenty of existing users to try and convert to paid, but $25 a year is a hard sell in 2014 when $1 apps are seen as the new Premium. The next phase is experimenting with different business models and ideas as I try to get better at making money. I’ve got a few ideas. Now to just build them out and measure the results. ### Handling Freemium Customer Support URL: https://www.justinw.me/blog/handling-freemium-customer-support/ Last updated: 2014-02-16T19:00:20.000Z One of the challenges of taking over a service as large as [Glassboard](http://glassboard.com/?ref=justinw.me) is handling the support load that comes with it. Since 2010, I have had [Aptfolk](http://aptfolk.com/?ref=justinw.me) on the payroll to handle the majority of Second Gear’s support load. I’ve long believed that my time is best spent invested in improving the products versus answering the same emails over and over again. If there’s an issue that requires my attention as the developer, Jason or Ash would escalate the ticket to me, but the vast majority could be handled as “tier 1” support. Since every Second Gear customer was a paying customer it was an expense that made sense. With Glassboard, that dynamic has shifted as the vast majority of our users are free, non-paying customers. The ultimate goal is to convert a good chunk of these users into paying customers (while also bringing in new customers at the same time hopefully), but there’s a lot of work to do before we get to that point. As it stands today, I am paying the Aptfolks to help users who are not currently paying for the product and (being realistic) may never be paying customers. When you are a company backed by a big wad of venture capital cash this isn’t that big of an issue and can be chalked up as a cost of successful user acquisition. When you’re a small company like Second Gear that is 100% funded by our customers (and my personal bank account sometimes!) this can be a costly problem. Free support isn’t something new. When you offer a free trial, you want to offer support and answer any questions potential customers have while they are evaluating the product. With the freemium model where there is always a level of users who will never pay for the service. Answering the question about how to handle support for these users in a way that doesn’t break the bank is something that has been on my mind lately. As one of the ways of cutting down on the support cost and load, we recently switched to [Zendesk](http://zendesk.com/?ref=justinw.me) for managing support. Yes, we switched to a *paid* service. Previously everything was handled by a mix of FogBugz tickets and TextExpander snippets. It worked well for several years, but dealing with a service that spreads across multiple platforms (iOS, Android, and the web) was making it difficult to track cases, analyze support trends, and burn through tickets quickly. FogBugz is great, but as a primary support tool we were hitting the pain points more than ever. Moreover, the macro support in Zendesk sold me on paying $50 a month as it allows us to quickly automate frequent questions and inquiries. If the service allows either me or the Aptfolks to iterate through our inbound support tickets quicker and saves us a few hours a month, the monthly Zendesk fee is worth it. ### Free Support Is No Support? When you’re dealing with a customer base that isn’t paying for the product, the goal is to offer as much self-service support as possible. You want customers to be able to find the answers to their questions either via a knowledge base, blog posts, or user-to-user support. As a last resort they should email you for an answer. I’ve seen quite a few SaaS companies only offering direct support via email or phone for certain tiers of customers. For free customers, the only support options is the automated knowledge base or user-to-user support. This is tempting, but I also can’t help but wonder how many potential customers aren’t converted to paying because they couldn’t have one of their questions answered. Obviously, I need some sort of data to measure this, but my current hypothesis is that it could be an issue. To achieve the “No Support” option also requires a substantial amount of self-service support. This is admittedly an area that needs a lot of improvement for us, and another reason for the Zendesk switch. While we have the Glassboard Help board (Invite Code: HELP) that lets users help each other, the vast majority of support still comes through our Zendesk email address. On the todo list is to begin working on a knowledge base that answers frequently asked questions. We’re also working with some lovely people to help with general product education that will highlight how to get the most out of Glassboard. The hope with the product education is to help alleviate the “why should I use this?” questions better. ### Automating Support There are some support tasks that aren’t as easy as pressing a button. Glassboard currently has no ability to automatically delete your account or change your email address. Why? I’m not entirely sure what the thought process was behind that when it was built by the Sepia Labs folks. What I do know is that these are the two biggest support requests we receive and that each time we have to handle one of these tasks for a customer, we lose money. When the request comes in, we have to: 1. Go into Glassboard and find the user’s account 2. Update their email address (or delete the account) 3. Go back to Zendesk and email them about the change. 4. Possibly handle any responses that come in. It’s not a difficult task, but it is tedious and something that we shouldn’t have to deal with manually. Any support inquiry that comes in more than once, be it a bug users are hitting or a question, is an opportunity to automate and solve a problem with technology. In the case of changing an account’s email address or deleting the account entirely, the solution is to write code so that users can handle these tasks themselves either via the web or mobile apps. Given that these are two areas that we are getting multiple requests for daily, it is high on my development timeline because it’s not only a better customer experience, but it’s also an opportunity for us to cut down on support costs by letting users handle these tasks themselves. ### Support Driven Development Support has long been one of the key metrics I have used when prioritizing bugs. The more a bug is reported, the more likely it is to move to the top of my development timeline because I want to make it so that we no longer have to answer emails related to the problem. Support questions have also been a good eye opener for figuring out the most confusing areas of Glassboard as a product. Our first line of defense for these sorts of issues is to improve product education so we can refer customers to a web page or video that explains some function of the product. In some cases, education may not be the proper solution, and is just putting a band-aid on an implementation issue. In those cases, it is worth investing the time in analyzing the user experience and seeing if there are ways to improve that. Glassboard has quite a few of these pain points that we are looking to resolve in the coming months. The biggest issue on our list is the onboarding experience of Glassboard, which I hope to share more about in a future post. If you’re answering the same support questions over and over, take a few hours to highlight the issues that are repeatedly being hit upon. Once you have those, work on a plan to alleviate them and in turn, lower your support costs. ### On Glassboard & Windows Azure URL: https://www.justinw.me/blog/on-glassboard-windows-azure/ Last updated: 2014-02-11T19:00:00.000Z Stackmob announced it is [shutting down](http://pastebin.com/B6RiEqev?ref=justinw.me) this afternoon. I know a few folks that are using their services and are now going to be forced to look for a new provider for their backend services. I thought I’d share my experiences. It has been nearly two months since I [took over](http://www.secondgearsoftware.com/blog/glassboard-acquired-by-second-gear/?ref=justinw.me) operations of Glassboard. The experience has been interesting, enlightening, challenging, and fun all at once. I’m hoping to talk about these lessons and experiences more here both as a way of documenting my progress and to hopefully garner feedback as I go forward. I had an eye on last week’s announcement of Microsoft’s new CEO. Obviously because I follow the technology industry, but also because I now have a vested interest in Microsoft going forward. You see, Glassboard’s entire backend is powered by Microsoft technologies: Windows Azure to be specific. Satya Nadella, the new CEO at Microsoft, was the head of the Azure side of MIcrosoft’s business before ascending to the top of the food chain, which is why I’m optimistic about the company’s future. I truly believe Azure is the best thing the company is doing right now. Most people are surprised when I tell them that since I inherited an Azure backend rather than choosing it on my own accord, but I think that is what makes my thoughts more interesting. If I thought it wasn’t on-par with what Amazon is doing, I’d take the time to migrate off the platform over time. At this time, there are zero plans for that. I’m extremely happy. ### The Glassboard API Architecture Glassboard’s Android and iOS apps, like most mobile apps, are powered by a REST API. The API app is an ASP project that uses WCF to distribute the JSON payloads. If there’s one thing I hate, it is WCF. A lot. My next big backend project is converting from WCF to the new [Web API 2](http://www.asp.net/vnext/overview/aspnet-web-api?ref=justinw.me) technology that is a lot easier to work with. It’s all written in C#, which I have found to be a pretty nice language. The API is deployed to a [Cloud Service](http://www.windowsazure.com/en-us/documentation/services/cloud-services/?ref=justinw.me), which is similar to a virtual machine but with less of an administration headache. I have the Glassboard Cloud Service set up to automatically scale between 2 and 4 Cloud Service instances depending on how much of a load is on the service at any given time. Your messages are encrypted and stored using [Azure Table Storage](http://www.windowsazure.com/en-us/documentation/articles/storage-dotnet-how-to-use-table-storage-20/?ref=justinw.me). Your photos, videos, and files are stored in [Azure Blob Storage](http://www.windowsazure.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs-20/?ref=justinw.me). Azure’s storage system is familiar to anyone who has used NoSQL. There’s also a little bit of SQL Server mixed in there for some stuff where a relational database made sense. This is by far the biggest cost point of my monthly bill, but it’s also pretty close to what [Amazon is offering](http://techcrunch.com/2014/01/24/microsoft-azure-drops-storage-prices-to-match-amazons-latest-price-reduction/?ref=justinw.me). I also am using [storage queues](http://www.windowsazure.com/en-us/documentation/articles/storage-dotnet-how-to-use-queues-20/?ref=justinw.me) to communicate with Glassboard’s attachment processor and notifications cloud services. This works pretty well, but the [Service Bus](http://www.windowsazure.com/en-us/services/messaging/?ref=justinw.me) may be a better choice going forward. I’m honestly not sure yet. I need to read into it more. Oh, and I also deploy the [Glassboard marketing site](http://glassboard.com/?ref=justinw.me) to an [Azure Web Sites](http://www.windowsazure.com/en-us/services/web-sites/?ref=justinw.me) instance through [GitHub](https://github.com/glassboardapp/glassboard.com?ref=justinw.me). Whenever I push an update to my web site to its public GitHub repository it instantly deploys the new version to Azure. Other than the Glassboard marketing site, I manage all of this and deploy it through Visual Studio 2013 on a Windows 8 VMWare instance on my Mac. I came into it with zero experience and in two months have gotten to the point where I am comfortable with nearly every aspect of it. Is it the right tool for you? That’s up to you, but [like Brent](http://inessential.com/2014/02/04/azure%5Ftakes%5Fover?ref=justinw.me) I am a fan and am glad to see Amazon have a legit competitor in the cloud services area. With [Stackmob shutting down](http://pastebin.com/B6RiEqev?ref=justinw.me), I know a lot of developers are looking for a new backend as a service. If you’re doing Node, Azure is worth looking at as it is a first class citizen. If you’re looking at [Parse](http://parse.com/?ref=justinw.me) as a Backend as a Service replacement, Azure is worth looking at too. Their [Mobile Services](http://www.windowsazure.com/en-us/services/mobile-services/?ref=justinw.me) product is a direct competitor. I haven’t used that portion of the platform personally, but I am happy enough with the Azure offerings I already use to recommend it. As more apps are requiring a server-side component, cloud service providers are becoming more important. My hope is that Microsoft’s Nadella continues to recognize that as CEO and keeps funding the best product (and only product I regularly use) they have going today. ### What I'm Doing With Glassboard URL: https://www.justinw.me/blog/what-im-doing-with-glassboard/ Last updated: 2014-01-14T19:00:57.000Z A few months ago I wrote a post titled *[What I’d Do With Glassboard](https://www.justinw.me/2013/08/22/what-i-d-do-with-glassboard/)* that outlined what I thought the potential buyer of the service should do with it going forward. Funnily enough, this post put me in touch with the NewsGator folks and I [acquired Glassboard](http://www.secondgearsoftware.com/blog/glassboard-acquired-by-second-gear/?ref=justinw.me) from them last fall. In the time since, I have been working nearly nonstop to get the acquisition and transfer completed on the business and technical side, while also working on a complete refresh of the iPhone app for iOS 7. Today marks the day that I dub Glassboard to be a [minimum viable product](http://en.wikipedia.org/wiki/Minimum%5Fviable%5Fproduct?ref=justinw.me). What the Sepia Labs team built is a fantastic foundation for a slew of amazing ideas and opportunities I hope to build on in 2014 and beyond. A lot of that first blog post remains true today, though I won’t be killing the web app. In fact, it’s getting a fresh coat of paint thanks to a [good friend](http://alexking.org/?ref=justinw.me) and [his team](http://crowdfavorite.com/?ref=justinw.me). In the short-term you’ll continue to see more updates to the iPhone app as well as bringing the Android app up to the same level of quality. The Android refresh is entering beta in the next few days even. I’m excited about the future of Glassboard. I hope you’ll come along for the ride. [Download Glassboard 3.0](https://itunes.apple.com/us/app/glassboard/id453661198?ls=1&mt=8&ref=justinw.me) ### My Ultimate Developer and Power Users Tool List for OS X (2013 Edition) URL: https://www.justinw.me/blog/my-ultimate-developer-and-power-users-tool-list-for-os-x-2013-edition/ Last updated: 2013-10-27T19:00:49.000Z This is the fifth installment of my must have must have list of tools and utilities as a Mac and iOS developer ([2009](https://www.justinw.me/2009/10/15/my-ultimate-developer-and-power-users-tool-list-for-mac-os-x/), [2010](https://www.justinw.me/2010/10/25/my-2010-ultimate-developer-and-power-users-tool-list-for-mac-os-x-2010-edition/), [2011](https://www.justinw.me/2011/12/19/my-ultimate-developer-and-power-users-tool-list-for-mac-os-x-2011-edition-/), [2012](https://www.justinw.me/2012/10/15/my-ultimate-developer-and-power-users-tool-list-for-mac-os-x-2012-edition-/)). This year’s edition of the list takes into account the new tools I am using as part of my transition to working exclusively on iOS 7 and OS X Mavericks, as well as an amateur designer. The idea for this list was shamelessly ripped off from Windows developer [Scott Hanselman](http://www.hanselman.com/blog/ScottHanselmans2011UltimateDeveloperAndPowerUsersToolListForWindows.aspx?ref=justinw.me) whose list has long been an enjoyable read when he updates it. Many of the products you will recognize from previous years’ lists. I’ll outline new additions to the list as I go by marking them in bold. ### Hardware My hardware is mostly the same as last year. I am still maintaining a dual Mac setup. My daily driver is a 27″ i7 iMac with a 256GB SSD, 2TB spinning disc and 16GB of RAM. There is absolutely no reason for me to have 16GB of RAM other than to brag about the fact that I have such a ridiculous amount of memory. After almost four years, this machine is still humming along like a champ. The only reason I would consider upgrading to a new one is aesthetics at this point. At home I am using my 15″ Retina MacBook Pro with a 512GB SSD and 8GB of RAM. This is the first revision of the Retina MacBook Pro and it’s probably one of my favorite Macs ever assembled. My only request going forward is a much higher retina resolution. It’s really a challenge to jump between the massive amount of pixels that a 27″ iMac affords you and then head back to a 1440×900 display at home. I am using Dropbox more than ever to keep everything between the two machines in sync. I symlink Documents, Downloads, Movies, and Sites to point to those respective directories on Dropbox. I am also using shared Dropbox folders for Second Gear projects that require collaboration with a designer. I’m still using GitHub for storing all of my code. In terms of accessories and upgrades: - I use a [**Das Keyboard**](http://www.amazon.com/dp/B003ZG9T62/?tag=carpeaqua-20&ref=justinw.me). I [love it](https://www.justinw.me/2012/04/15/a-review-of-the-das-keyboard-for-mac/). The Das Keyboard doesn’t make me a better developer, writer or person. It just feels satisfying to use. - On the left side of my iMac I use a [Magic Trackpad](http://www.amazon.com/dp/B003XIJ3MW/?tag=carpeaqua-20&ref=justinw.me) for swiping and gesturing between full-screen apps and Mission Control. I am a big user of multitouch gestures in Mavericks, so I am incredibly comfortable using the trackpad. - On the right side of my iMac I use a [**Razer Mamba 2012 Elite Ergonomic Wireless Gaming Mouse**](http://www.amazon.com/dp/B0054JGGGY/?tag=carpeaqua-20&ref=justinw.me) to do all my pointing and clicking. The Razer mouse is far more comfortable to use and is wired, which was useful for that month I was obsessed with playing [Quake 4](https://itunes.apple.com/us/app/quake-4/id492135099?mt=12&uo=4&at=11l7mT&ref=justinw.me). - Time Machine backups are handled by a [2TB Western Digital MyBook](http://www.amazon.com/gp/product/B004QGXOOI/?tag=carpeaqua-20&ref=justinw.me) connected via Firewire 800\. It’s fairly quiet and is one of the few external drives I’ve found that doesn’t have a horrific design. Last year I had the 1TB version, but it finally met its demise after years of faithful service. It was a no brainer to upgrade to the new one. - I am a completely paperless office thanks to my [**Fujitsu ScanSnap iX500**](http://www.amazon.com/dp/B00ATZ9QMO/?tag=carpeaqua-20&ref=justinw.me). I usually scan all my receipts, bills and invoices once a month and then run them through OCR so I have a searchable archive on my Mac. - I connect to the Internet through my [Airport Extreme Base Station](http://www.amazon.com/dp/B0057AVXJA/?tag=carpeaqua-20&ref=justinw.me). It cost more than a Linksys but it’s super reliable and the management software is much more pleasant to use. ### Software I am really hard on software. This is for a variety of reasons, but I think it is because I build it myself. I have always envisioned that directors and actors can sometimes lose focus during a movie as they judge the decisions others made in their productions. I feel like I do the same thing with software. I loathe poor and/or non-native user interfaces and cherish simple tools. These are applications I constantly rely on. #### The Essential Five - [**Dash**](https://itunes.apple.com/us/app/dash-docs-snippets/id458034879?mt=12&uo=4&at=11l7mT&ref=justinw.me) – The new documentation viewer in Xcode 5 is better, but I have found Dash to be a must-have utility, especially if you are targeting platforms beyond just OS X and iOS. Dash imports and formats documentation for OS X, iOS, Android, web frameworks, and more. It’s amazing. - [Dropbox](https://www.dropbox.com/?ref=justinw.me) – Dropbox is the secret sauce for a variety of reasons. It makes it easy to share files between machines as well as with colleagues. Beyond that, maybe you’ve heard of [Elements](http://www.secondgearsoftware.com/elements/?ref=justinw.me) and the many other great iPhone apps that sync data using Dropbox? - [OmniFocus](https://itunes.apple.com/us/app/omnifocus/id402835630?mt=12&uo=4&at=11l7mT&ref=justinw.me) – I don’t know how I ever stayed organized before OmniFocus on my three screens. It’s my brain. - [Sublime Text 3](http://www.sublimetext.com/3/?ref=justinw.me) – I am a big fan of Sublime Text and am still using it as a replacement for BBEdit. It’s not the prettiest girl at the dance, but its powerful text editing features and the ability to customize the interface however I see fit ultimately made me make the switch. It also handles Ruby development a bit nicer than I found from BBEdit. We’ll always have Paris, Bare Bones. - [xScope](https://itunes.apple.com/us/app/xscope/id447661441?mt=12&uo=4&at=11l7mT&ref=justinw.me) – I use xScope to detect colors on various UI elements, check alignment of controls and to measure the distance between objects. If you are meticulous about your UI, it’s an essential utility. #### Developer Tools - [Xcode](https://itunes.apple.com/us/app/xcode/id497799835?mt=12&uo=4&at=11l7mT&ref=justinw.me) – If you write Mac or iOS applications, you spend most of your life in Xcode and Instruments. I am no different. - [**Android Studio**](http://developer.android.com/sdk/installing/studio.html?ref=justinw.me) – I have been doing a bit of Android development the past few months and have found Android Studio, while still an early preview, to be a very nice IDE to use. It’s based off IntelliJ IDEA and has a lot of nice editor and refactoring features I’d love to see make it to Xcode some day. - [**Anvil**](http://anvilformac.com/?ref=justinw.me) – If you use [Pow](http://pow.cx/?ref=justinw.me) for running your Rails or Rack-based apps locally, Anvil makes it really easy to manage and restart them from your menu bar. Bonus: it’s free. - [Appfigures](http://www.appfigures.com/?ref=justinw.me) – Manually fetching iTunes sales reports is tedious. Appfigures is a low-cost Web service that will import your reports and send you a daily sales email. You can also do a lot of other analysis on your sales to find trends, but I generally use it for the daily email. - [Base](https://itunes.apple.com/us/app/base/id402383384?mt=12&uo=4&at=11l7mT&ref=justinw.me) – Elements has a SQLite database behind it. I’m constantly inspecting the database contents using this application. It’s lightweight and easy to use. - [Charles](http://www.charlesproxy.com/?ref=justinw.me) – Sometimes I want to snoop the traffic that is going through an iPhone app. Setting up Charles makes it pretty easy to do just that. - [CodeRunner](https://itunes.apple.com/us/app/coderunner/id433335799?mt=12&uo=4&at=11l7mT&ref=justinw.me): There are times I am writing a small snippet of code to share with someone or just to test an idea on my own. I don’t necessarily need the full power of Xcode, so CodeRunner comes in quite handy. It’s even more useful in its support of other languages like Ruby and JavaScript. - [Committed](https://itunes.apple.com/us/app/committed/id560767719?mt=12&uo=4&at=11l7mT&ref=justinw.me) – Shameless plug for my GitHub to Notification Center app. I built it because I needed it. I use it everyday. - [Cornerstone](https://itunes.apple.com/us/app/cornerstone/id404789253?mt=12&uo=4&at=11l7mT&ref=justinw.me) – For those few times a year I need to work with Subversion, Cornerstone is the best desktop client I’ve found for it. - [**Deploymate**](http://www.deploymateapp.com/?ref=justinw.me) – If you’re still supporting iOS 5 or iOS 6, you want to make sure that you’re not calling APIs not supported on those platforms before shipping to the App Store. Crashes are bad. Deploymate does just that. It saved my bacon once already which made it worth every penny I paid for it. - [Dev Color Picker](http://panic.com/~wade/picker/?ref=justinw.me): Must have. Choose whatever color you want and then it will output a UIColor or NSColor for you. - [**Ember**](https://itunes.apple.com/us/app/ember/id402456742?mt=12&uo=4&at=11l7mT&ref=justinw.me) – I used to use LittleSnapper, Ember’s predecessor, to capture screenshots and inspiration for design years ago but got out of the habit as the app languished and didn’t sync. Ember uses iCloud to sync your snapshot library between Macs, which is great. The RSS subscriptions feature is great too for tracking design trends on [Dribbble](http://dribbble.com/?ref=justinw.me). I keep feeds for each mobile and desktop platform. - [FogBugz](http://www.fogcreek.com/fogbugz/?ref=justinw.me) – I have been using FogBugz to manage Second Gear’s support inbox and bug database for almost five years. People complain that it is an unattractive app. I disagree. It’s not flashy and instead just disappears so that I can actually focus on using it for its intended purpose: managing my software projects. - [**Genymotion**](http://www.genymotion.com/?ref=justinw.me) – You know how the Android emulator is really slow and generally sucks? Genymotion doesn’t. It’s faster, more powerful, and works better in almost every way. If you’re doing Android development, you owe it to yourself to give it a whirl. - [Git](http://git-scm.com/?ref=justinw.me): I am now exclusively on Git for Second Gear projects. Thanks, GitHub. - [**GitHub for Mac**](http://mac.github.com/?ref=justinw.me) – GitHub’s official Mac client isn’t the most feature-filled Git client on the market, but it accomplishes everything I need it to as a sole developer: sync, commit, branch. If you haven’t given it a shot in a few months, do yourself a favor and try again. It’s gotten really good. - [Go2Shell](https://itunes.apple.com/us/app/go2shell/id445770608?mt=12&uo=4&at=11l7mT&ref=justinw.me): A small utility app that I keep in my Finder toolbar to open a Terminal window in whatever folder I am currently looking at. - [HockeyApp](http://www.hockeyapp.net/?ref=justinw.me) – I am using Hockey for distributing betas and handling crash reports. Whenever I archive a build, I use HockeyApp’s OS X app to upload the binary and dSYM as part of the build process. - [**HockeyCoach**](http://hockeyapp.net/releases/hockeycoach/?ref=justinw.me) – HockeyCoach is a new app from the Hockey folks I mentioned above that lets you manage your crash reports in a native Mac app with a few additional features over the web app. - [Hex Color Picker](http://wafflesoftware.net/hexpicker/?ref=justinw.me): My designer sometimes sends me hex values for colors I need in my user interfaces. This coupled with my next pick makes it easy for me to grab an NSColor or UIColor value. - [Hues](https://itunes.apple.com/us/app/hues/id411811718?mt=12&at=11l7mT&ref=justinw.me) – Combined with Hex and Dev Color Pickers, Hues is one of my most used apps. All it is is the OS X Color Picker in a full application that is accessible via the Dock and command-tab switcher. Awesome. - [IconSlate](https://itunes.apple.com/us/app/icon-slate/id439697913?mt=12&at=11l7mT&ref=justinw.me) – When I was putting together [Committed’s icon](https://itunes.apple.com/us/app/committed/id560767719?mt=12&at=11l7mT&ref=justinw.me), IconSlate was the best way to drag-and-drop the different sizes and get an icns file. It’s also what I use whenever I need a new favicon in the ICO format. - [ImageOptim](http://imageoptim.com/?ref=justinw.me) – When you add up the kilobytes of non-retina and retina assets for both the iPhone and iPad, app binaries are getting bigger. ImageOptim has a better compression algorithm than the one built into Xcode, so I will sometimes run images through it to get smaller sizes. - [iPhone Backup Extractor](http://supercrazyawesome.com/?ref=justinw.me) – When doing iPhone support, it is sometimes beneficial to get a copy of the user’s data and preferences. Using this application, it’s fairly easy for the user to handle on their end. - [**Kaleidoscope**](http://www.kaleidoscopeapp.com/?ref=justinw.me) – I have never been a fan of the bundled merging tools with Xcode. Kaleidoscope is vital to my workflow when running diffs on my Git commits. The new version of Kaleidoscope that was released by Black Pixel last year is fantastic. - [Library Inspector](http://www.oriontransfer.co.nz/software/library-inspector/index?ref=justinw.me) – There have been a few times I’ve wanted to see what was in a static library. - [Patterns](https://itunes.apple.com/us/app/patterns-the-regex-app/id429449079?mt=12&at=11l7mT&ref=justinw.me): I don’t think I will ever fully grasp Regular Expression syntax. Patterns makes it easier for me to fumble around trying to build and test a regex compared to doing sample finds in Sublime Text. - [**QuickRadar**](http://www.quickradar.com/?ref=justinw.me) – The RadarWeb UI still sucks. QuickRadar makes me more likely to file bugs because it is in my Dock, it can cross-post to [OpenRadar](http://openradar.appspot.com/?ref=justinw.me), and it has never crashed or lost a bug report while I was trying to submit it. - [RESTed](https://itunes.apple.com/us/app/rested-simple-http-requests/id421879749?mt=12&at=11l7mT&ref=justinw.me): When building or testing an API, RESTed comes in handy to see raw JSON output and quickly test input parameters. I also tend to keep a couple RESTed documents in my source repos so I can quickly test the API. - [Screentaker](https://itunes.apple.com/us/app/screentaker/id460043075?mt=12&at=11l7mT&ref=justinw.me) – Screentaker is the fastest way I have found to go from an iOS device screenshot to something wrapped in a device shell. - [**Sketch**](https://itunes.apple.com/us/app/sketch/id402476602?mt=12&uo=4&at=11l7mT&ref=justinw.me) – Finding design talent with availability or that hasn’t been acquired by Facebook is difficult sometimes. That’s why I have tried to dabble with doing my own design for the low-hanging fruit things like toolbar icons and whatnot. Sketch is amazingly great if you want to do any sort of mobile or web interface design. I’ve tried to use Photoshop for this stuff so many times and failed. I picked up Sketch after a few days. Best $50 I spent in 2013. - [**Slender**](https://itunes.apple.com/us/app/slender/id493656257?mt=12&uo=4&at=11l7mT&ref=justinw.me) – If you’re using Xcode I bet you have a few assets in your Xcode project that are no longer in use. Those kilobytes are wasting your customers’ bandwidth and yours. Slender analyzes your Xcode project and finds those assets that are no longer in use so you can safely delete them. - [**Status Magic**](https://itunes.apple.com/us/app/status-magic/id547920381?mt=12&uo=4&at=11l7mT&ref=justinw.me) – Before I send screenshots to iTunes Connect, I run them through Status Magic to add a proper status bar to it. It’s a small thing, but I think it looks more professional than the current status bar that my device screenshot gives me. - [Trello](https://trello.com/?ref=justinw.me) – While I use FogBugz for customer support and bug tracking, I am using Trello for the high level management of Second Gear Projects. It’s where I can get a quick overview of what my release plans are and adjust them if necessary. I also put all feature requests and ideas here instead of the bug tracker since they may never be actionable. #### User Tools - [1Password](https://itunes.apple.com/us/app/1password-password-manager/id443987910?mt=12&at=11l7mT&ref=justinw.me) – One of the first tools I install. Its Dropbox over-the-air syncing makes using it on my iPhone and iPad even easier. It also has made me use better passwords because I no longer have to remember them. 1Password does that for me. - [Acorn](https://itunes.apple.com/us/app/acorn-4-image-editor-for-humans/id634108295?mt=12&at=11l7mT&ref=justinw.me) – Acorn is my favorite image editor for the Mac. It’s fast, intuitive and looks pretty neat too. - [Backblaze](http://backblaze.com/?ref=justinw.me) – While I primarily rely on Time Machine for my backups, I also subscribe to Backblaze to offload the contents of my hard drive to the Internet. - [**Chatology**](http://flexibits.com/chatology?ref=justinw.me) – You know how iMessage is unreliable, doesn’t send messages sometimes, and just sucks? So does search in the Messages app. Chatology solves that by making it way easier to search your chat logs for that screenshot or link that you know you sent a few days ago. - [Cloak](https://www.getcloak.com/accounts/sign-up/?i=7E5C53B980CB&ref=justinw.me): If you connect to any shady or insecure networks, Cloak is a super easy VPN service to secure your traffic. On my Mac, I like it because it will automatically connect when I join an insecure network. Even better, it’s just a tap away from toggling on my iPhone and iPad. - [CloudApp](https://itunes.apple.com/us/app/cloud/id417602904?mt=12&uo=4&at=11l7mT&ref=justinw.me) – Whether it’s sharing screenshots, beta releases or small snippets of text, Cloud has become an essential tool for me. Its automatic screenshot uploading feature solved the problem I always had with figuring out how to successfully share screenshots without having to rely on AIM’s flaky servers or uploading them somewhere with Transmit. - [Feeder](https://itunes.apple.com/us/app/feeder/id405949153?mt=12&uo=4&at=11l7mT&ref=justinw.me) – I use Feeder to update the IRQ Conflict podcast as well as several different Sparkle AppCast feeds. It’s one of the best user experiences I’ve found on the Mac. - [**GIFBrewery**](https://itunes.apple.com/us/app/gif-brewery/id435989461?mt=12&uo=4&at=11l7mT&ref=justinw.me) – You like GIFs. I like GIFs. Let’s make GIFs. - [Labelist](https://itunes.apple.com/us/app/labelist/id530284072?mt=12&at=11l7mT&ref=justinw.me) – I have horrible penmanship. I have had letters returned by the USPS for illegible addresses. I bought a label maker and use Labelist to generate all of my address labels now. - [Launchbar](http://www.obdev.at/launchbar/?ref=justinw.me) – I use Launchbar primarily as an app launcher, but I also am a big fan of version 5’s [clipboard history feature](https://www.justinw.me/2011/03/22/my-favorite-launchbar-feature/). - [**Marked 2**](http://marked2app.com/?ref=justinw.me) As I am writing this blog post in Markdown using Sublime Text 3, I have Marked 2 open as well doing a live-preview of the post so I can quickly see if I have any of my Markdown showing. - [Napkin](https://itunes.apple.com/us/app/napkin-concise-image-annotation/id581789185?mt=12&uo=4&at=11l7mT&ref=justinw.me) – Need to annotate a screenshot or point out a specific portion of it? Napkin does that better than any other app I have found. - [OmniOutliner Pro](https://itunes.apple.com/us/app/omnioutliner-pro/id404647179?mt=12&uo=4&at=11l7mT&ref=justinw.me) – When I am doing more complex writing projects than a blog post, I outline the entire thing in OmniOutliner. The ability to have drop-down fields is one of my secret weapons. Love that. - [PDFpenPro](https://itunes.apple.com/us/app/pdfpenpro-6/id609313570?mt=12&at=11l7mT&ref=justinw.me) – Preview is a fine PDF viewer, but if you need to sign contracts, make edits to PDFs or create new forms, PDFpenPro is top notch. Bonus: it’s a lot cheaper than Adobe Acrobat. - [Photoshop CC](http://www.adobe.com/products/photoshop?ref=justinw.me): When Adobe switched to its Creative Cloud pricing, I decided to jump back on the Adobe bandwagon. I don’t really have a system for when I use Acorn and when I use Photoshop. It usually just ends up depending on what I decide to type into Launchbar on a given day. - [RCDefaultApp](http://www.rubicode.com/Software/RCDefaultApp/?ref=justinw.me) – RCDefaultApp is one of those applications that has been on my Mac for so long, I take it for granted. For those times when you want to force a file extension to open in a specific application, it’s great. - [Rdio](https://www.rdio.com/?ref=justinw.me): Last year I made my transition away from a local iTunes music library in favor of iTunes Match and Spotify. This year, I am 100% on Rdio. I no longer have any music stored locally on my Mac or any of my iOS devices. Instead, I am syncing albums from my Rdio collection to my iPhone for offline listening. It’s been working great and I can’t imagine going back to the traditional ‘purchase’ model for music. - [Soulver](https://itunes.apple.com/us/app/soulver/id413965349?mt=12&at=11l7mT&ref=justinw.me): [Marco](http://www.marco.org/2010/01/04/soulver-for-iphone-the-iphone-port-of-my-favorite?ref=justinw.me) turned me onto the iPhone version of Soulver and now I am a convert on the Mac too. It really is a much better interface for doing quick (or complex) numeric calculations. - [The Unarchiver](https://itunes.apple.com/us/app/the-unarchiver/id425424353?mt=12&at=11l7mT&ref=justinw.me) – A file extraction utility is somewhat of an unsung hero, but when you need it, it’s good to have a utility that is robust and can fit almost any bill. The Unarchiver does that and does it well. - [Twitter for Mac](https://itunes.apple.com/us/app/twitter/id409789998?mt=12&uo=4&at=11l7mT&ref=justinw.me) – You probably use Tweetbot, but I actually prefer the official Twitter client for desktop tweeting solely because its scrolling performance is acceptable. - [Wedge](http://wedge.natestedman.com/?ref=justinw.me) – If you use App.net, you probably want a desktop client. Wedge is the best one I’ve found. ### Audio Production Outside of doing software development, I talk about software development and technology in general with my Windows development buddy, Mikel Berger on [IRQ Conflict](http://irqconflict.net/?ref=justinw.me). These are the tools used to produce the show and some other audio gimmickry I pursue: - [Blue Blubird](http://www.amazon.com/dp/B000RLI76G/?tag=carpeaqua-20&ref=justinw.me) – I chose to buy an XLR mic because I could easily upgrade to a mixer someday without having to also buy another mic. Choosing a microphone is a personal thing, but this one had the right amount of audio quality and style for me. - [Icicle](http://www.amazon.com/dp/B001EW5YQS/?tag=carpeaqua-20&ref=justinw.me) – I’m still not ready to commit to putting a mixing board on my desk, so I am using this XLR to USB adapter also from Blue to connect to my Mac. I’ve noticed no real downsides to it other than it sometimes loses connection with the USB hub I have it plugged into. Just make sure it shows up as an input source before recording and you’re good to go. - [Adobe Audition CC](http://www.adobe.com/products/audition/?ref=justinw.me) – Last year I was still using the Windows version of Audition in VMWare. The Mac version finally shipped and it is great. It’s got those typical weird Adobe interface issues, but I wouldn’t recommend another multitrack editor over this one. It’s a great workflow. - [Skype](http://skype.com/?ref=justinw.me) – Mikel and I use Skype to record IRQ Conflict. - [Call Recorder](http://www.ecamm.com/mac/callrecorder/?ref=justinw.me) – Call Recorder is the least hassle for recording the audio of a Skype conversation. - [AudialHub](http://www.techspansion.com/?ref=justinw.me) – AudialHub is a dead app. It hasn’t been under active development for years. Sadly, it’s still the best for converting between a variety of different audio formats. ### Stop "Sherlocking" Yourself URL: https://www.justinw.me/blog/stop-sherlocking-yourself/ Last updated: 2013-10-18T19:00:37.000Z Back in the early days of OS X, Karelia Software had a product called [Watson](http://www.karelia.com/watson/?ref=justinw.me). At its time, it was one of the best apps for the new Apple OS and really showed the power of what was possible using the Cocoa frameworks and the new Aqua design language. It was so good in fact that when Apple introduced OS X Jaguar the new version of their Sherlock app looked to be an exact clone of Watson’s functionality. And now you know where the phrase “Sherlocking” comes from. Independent software developers can be both the smartest and dumbest people in their profession simultaneously. For some reason, developers are almost universally fascinated by building yet another todo list, notes app, weather app, or (most recently) a podcasting client. And what do all of these have in common? If you’re answer is “Apple ships them with iOS” or “there is a ton of competition already” then give yourself a cookie. You are correct I’m guilty of it too. My first OS X app was a todo list. My second a calendaring app. My main product on iOS has been a Markdown text editor since 2010\. In my defense, the text editor market in 2010 was wide open. Today, I wouldn’t even consider trying to enter the market unless I was completely confident that I was building something that was lightyears ahead of the best product already in the market. When dealing with such mature product bases, that’s really hard to accomplish for a 1.0\. Add onto the fact that you’re also competing with free and bundled with the iOS device in the case of Reminders, Notes, and Calendar. It still drives me nuts to this day to see family and friends using the bundled Notes app over [Elements](http://bit.ly/elements20?ref=justinw.me), but it accomplishes 90% of what they want and is free. Hard to compete with that. In this modern App economy, stop sherlocking yourself out of the gate and focus on harder problems than just another version of Elements or Clear with a different interface skin. Those markets are saturated to the point where you’re betting against yourself before you even ship 1.0\. Look to emerging markets that have a need ready to be filled, or even existing niche markets that have a few products poorly executed. There are still plenty of products to be made on iOS and OS X and plenty of money to be made from them. The todo app market is not one of them. *This post is a part of a series based on my keynote presentation at CocoaConf Columbus 2012.* ### Don't Fight the Future URL: https://www.justinw.me/blog/dont-fight-the-future/ Last updated: 2013-09-28T19:00:05.000Z Last week at [CocoaConf Columbus](http://cococaconf.com/?ref=justinw.me) I was given the privilege of offering up a keynote address to kick off the event. This is the first time I’ve ever been asked to do something like this, which sparked both excitement and horror simultaneously. Excitement because it was an honor to be asked to do something that’s designed to set the tone of the event. Horrified because I have no earthly idea what I’m supposed to talk about. A good keynote speech has three qualities: 1. It sets the tone for the conference. 2. It offers a message that may be rooted in something technical, but isn’t a technical talk. 3. It leaves you thinking, inspired or (hopefully) both. With that in mind I decided the best course of action for my talk was to crib something from Sports Illustrated’s [Peter King](http://mmqb.si.com/?ref=justinw.me). King’s weekly Monday Morning Quarterback Column always has a section called “10 Things I Think I Think”. I decided to take that idea and create 10 slides with different thoughts and ideas I had as they pertained to the current state of iOS development. The slides for the talk aren’t much use out of context, but sharing that information in the coming weeks as a series of posts on this site will hopefully allow it to reach a wider audience. Hopefully they’ll even find it beneficial. And now with the exposition out of the way… ### Don’t Fight The Future Apple is a company that doesn’t spend much time looking back. Just try compiling an app for the iOS 5 SDK using the latest version of Xcode. It’s not exactly something the company cares to support going forward. Apple is always coming out with new products and technologies that it believes are superior to what was available before. The iPhone 5s is a better device than the 5, which was a better device than the 4s, and so on. By the same token, SDK advances are treated the same way. The overarching theme of the year is usually outlined through Apple’s WWDC sessions. You can get a pretty good idea what technologies the company is very high on and looking for developer’s to embrace. With iOS 7, I’d argue that they’re main focus is on: - The new visual language of iOS 7 - UIKit Dynamics - Text handling These are all new technologies that are a core of iOS 7 and had multiple sessions dedicated to them at Apple’s major developer event. You can be damn sure that the company is proud of them, and looking for developer’s to highlight who have integrated them into their apps. It’s completely possible to keep building apps without supporting any of these features today, but your code (and in this case visual style) quickly begins to show its age the longer you delay embracing it. Take Auto Layout for instance. Apple has been pushing Auto Layout on the Mac for three years now and now two years on iOS. What seems like a very large majority of people have struggled with the technology and stuck with springs and struts in its place. Springs and Struts are fine, but don’t think they’re going to keep getting improved going forward with Auto Layout now reaching maturity. That’s where Apple is focusing its efforts on layout technology. You’d be wise to get on board. Similarly, as much as it frustrates me Storyboards continue to be a key focus of Apple each year with them adding additional improvements that *almost* make them not suck. Admittedly, each year I try to give Storyboards another chance and end up punting back to standard Xibs, but I’m aware that there are times where Apple does focus their Interface Builder improvements to features that are only available for Storyboards. That’s the way they are. Apple dictates the direction fo the platform with their yearly OS X and iOS releases. Your skillset is only as useful as your ability to adapt to these emerging frameworks and new functionalities. ### Trials And Upgrades Are Still Dead URL: https://www.justinw.me/blog/trials-and-upgrades-are-still-dead/ Last updated: 2013-09-05T19:00:14.000Z Here we go again. ### On Free Trials First up, the [Dark Sky guy](http://blog.forecast.io/the-app-store-free-trial/?ref=justinw.me): > The solution is so simple, so easy, and so full-proof that I’m confident it would, if implemented, at least double our revenue practically overnight: Give people the option of a free monthly trial. > > If users could download and use Dark Sky for free for a limited time, their hesitation at spending $3.99 would disappear. It’s either worth it or it isn’t, and they’d get to decide for themselves rather than take someone’s word for it. Next up, the far too nice [Shawn Blanc](http://shawnblanc.net/2013/09/on-free-trials-for-ios-apps/?ref=justinw.me): > While I do believe having free trials in the iOS and Mac app stores would be beneficial for developers, because it would likely increase revenue as Grossman states above, I also see it as being beneficial for users. Both upgrade pricing and trials are popular with developers because they’re ‘the way things have always been done’. Dating back to the shareware days, you could try a product and then, if you enjoyed it, you could pay for it. If the developer upgraded to version 2.0, existing customers were either given the update for free or for a discounted rate for being loyal customers. The App Store turned ‘the way things have always been done’ on its head. Instead of having third-party software sold either in boxes or at hundreds (thousands?) of different boutique storefronts, Apple manages the entire store and purchase process for both users and developers. If you want to run third-party software from outside of the App Store, your options are to jailbreak your phone or buy an Android. Every year, there is an uproar from developers who lament the loss of trials and upgrade pricing because they believe they will bring an increase in sales that for many (myself included) is sorely needed. That people aren’t buying software because there’s no trial is flawed notion. People aren’t refusing to buy paid apps because they are cheap or don’t trust these unknown apps. They’re just different customers than traditional software shops are used to working with. My parents never downloaded software on their home PC. If they needed a new piece of software at work, that was something that would magically appear thanks to the “IT guy” (likely you if it’s Thanksgiving or Christmas). Even though they never downloaded software, my parents were well versed at using technology thanks to the ubiquity of the web. That would be the World Wide Web, where nearly everything is given away for “free”. Developers are now trying to target this new breed of software consumers who are for the first time empowered to download apps onto their iPhone or Android. There are thousands of free apps to keep them occupied and happy. When they encounter a paid product, they are likely doing the same thing they do when they encounter the paywall on a web site: find a free alternative. I don’t have a solution to the problem, but I know that trials won’t transition customers who have grown up in the age of free into people willing to part with money for software. A martini may be $10 whereas your app is a mere $2.99, but people are conditioned to always pay for their liquor as food and drink has always been a pay-for product. ### On Upgrade Pricing Somewhat related, OmniGroup’s [Ken Case](http://www.omnigroup.com/blog/entry/update-no-upgrade-pricing-for-mac-app-store-purchases?ref=justinw.me): > We still feel upgrade pricing is important for customers purchasing serious productivity software, since the initial value received from purchasing an app like OmniGraffle or OmniPlan is much different from the incremental value of upgrading that app from version 5.0 to version 6.0. This comes after the OmniGroup released a product that allowed customers who purchased Omni products from the Mac App Store to purchase new versions of the software on Omni’s own store at a discounted/upgrade price point. Apple scoffed at this because they don’t want developers to shift their shared customer base outside of Apple’s safe and secure App Store and back into the Wild West of third-party software sites. Scary? Absolutely. Surprising? Not really. Apple is the company that dictates that all digital products and services sold through iOS apps use Apple’s in-app purchasing system. You’re not even allowed to link to a web site such as the Kindle Book Store because that would bypass Apple’s 30% cut. Every year, we have another dust up about developers and power users wishing for the return of upgrade pricing in the App Store age. And every year, it becomes even more obvious that upgrade pricing is another relic of the past. Apple is more interested in developers either offering free updates indefinitely, or offering a completely new SKU at the same price for every user: old or new. Given that pricing in this new App Store age have hit rock bottom, on iOS that usually means somewhere under $4.99 and OS X somewhere under $29.99. One price for all. Is that a raw deal for existing customers? If you’re comparing it to the way software used to be sold, yes, but not in a lot of other industries. I’m not getting a discount on FIFA from EA each year just because I bought it last year. I’m going to drop another $60 on the new version. I just bought a new TiVo Roamio to replace my existing TiVo Premiere. It cost me the retail price of $299\. There was no discount for upgrading to the new version, even though I owned the previous one. The sooner developers accept this, the less painful it’s going to be. We’ve spent half a decade debating the merits of trials and upgrade pricing, and every year Apple remains silent. If you still believe it’s in Apple’s playbook to offer, I’ve got a bridge to sell you. Transitioning power users and the subset of the population that is willing to pay for software in the old, traditional way is going to be painful for a while, but the pain will subside. Offering two stores with two different pricing models only extends that painful transition phase even longer. It’s noble to want to offer a discount to your loyal customers, but if Apple’s not going to allow it in their store, segregating your users based on which store they purchased in turns out to be confusing and frustrating. What the lack of upgrade pricing means is that software is being priced at a lower, base price. A $50 app for new users that is $30 for upgraded users is now being offered somewhere around $25 for everyone. Whether that makes good financial sense is up to your company’s bean counters, but that’s what Apple’s pushing toward and resistance is only causing developers to lose more hair. It’s time to adapt. Will you? If not, I’ll see you next year when we have this discussion again. ### What I'd Do With Glassboard URL: https://www.justinw.me/blog/what-id-do-with-glassboard/ Last updated: 2013-08-22T19:00:50.000Z [Glassboard](http://glassboard.com/blog/2013/08/22/big-changes-coming-for-glassboard/?ref=justinw.me) is for sale. If you want to get past all the businessy corporate speak of the official blog, here’s the main nugget: > We want Glassboard to not only continue running but also to evolve and flourish. So we’re looking for a good home for Glassboard. The backend service for Glassboard runs in Azure, and it has wonderful iOS and Android clients. It took a team of talented people to create it, so we want Glassboard to go somewhere that has enough resources. [Brent Simmons](http://inessential.com/2013/08/22/glassboard%5Fseeks%5Fnew%5Fhome?ref=justinw.me) has a pretty good summary of what it is and why it’s worth saving: > The problem of persistent, private, and trustworthy group sharing is still an open problem. Glassboard represents a couple years of work by a six-person team, and it’s a great start. I believe that it can be very successful, given the right home, given resources and commitment. Brent has a bias in this since he was the former iOS developer over there, but there’s little doubt that the team that did work on it cared about it. Glassboard has become the ‘conference’ app for better or worse. Every Macworld, WWDC, and independent conference seems to set up a board for evening activities. I’m also using it for other things such running betas for [Second Gear](http://www.secondgearsoftware.com/?ref=justinw.me) apps. I doubt Second Gear has the resources to acquire Glassboard, but if I were the one to acquire it, here’s everything I’d do: ### Change The App’s Mission Brent said this: > The problem of persistent, private, and trustworthy group sharing is still an open problem. It’s not a problem that needs solving, at least not in the way they are marketing it. Nerds care about privacy. Users care about reliability, features and usefulness. Privacy isn’t a feature. It’s an expectation. Market it like this: > Glassboard enables you to connect, coordinate, and collaborate with a group of people independent of platform or location. That’s the usefulness. ### Annotations As part of that new mission statement, I’d put way more focus on collaboration and coordination. Add support for annotated messages beyond just images and video. Make it easy to embed a Google/iOS map with a specific place or your current location. Allow the user to link to a file that’s stored on his or her Dropbox account. If you want to be super trendy, add some fun stickers that can spice up a conversation. There are a million apps out there that do group chat already. None of them really do collaboration on mobile that well. ### Rewrite the iOS app The iOS app is serviceable, but not great. With iOS 7, I’d argue it needs a complete overhaul. Hire a designer, get to work and crank out a 1.0 visual refresh in 30-45 days after acquisition that targets iOS 7 and breathes fresh air into the product. Once you have the new visual design out there, focus on adding in the features like annotations or other metadata. The Android app is pretty good. I don’t think it needs much of a visual refresh other than to sync up with visual identity. ### Kill The Web App The Glassboard web app is atrociously bad. They “needed” it, but the product they gave users was half baked at best. Kill it with fire and then bring it back when it’s fully baked. ### Change the Business Model I have been using Glassboard since it was first released and I have given them zero dollars. They came out with a “pro” plan, but the boundaries on it are all wrong. Unless you are a heavy Glassboard user, you will never hit the limits set. Good for users. Bad for business. I’d charge a flat monthly fee per board. Base it on how many active users there are in that board on a given month and charge $x per head. Give away the first three users for free as the ‘trial’. In the conference model that Glassboard is traditionally used for, the boards are throwaway so it’d be a yearly cost of $10 or $20 (I’m making up numbers). For people like me who use it for a beta with 25 or so people, I am putting money into the business on a monthly basis to keep it afloat. ### Change the Name For an app that touted itself as being heavily into privacy it was always curious to me that the name was prefixed with a see-through object like glass. I’d instantly rename it Backchannel, but you could name it whatever you wanted. Glassboard doesn’t have enough of a following that you lose much awareness with the rename, but it does give you a fresh start out of the gate. ### Android@3x URL: https://www.justinw.me/blog/android3x/ Last updated: 2013-07-30T19:00:48.000Z A post has been [making the rounds](http://daringfireball.net/linked/2013/07/30/bbc-android?ref=justinw.me) today from the [BBC iPlayer team](http://www.bbc.co.uk/blogs/internet/posts/Video-on-Android-Devices-Update?ref=justinw.me) where they point out that they have a team triple the size on Android as they do on iOS. Here’s the relevant paragraph: > Prior to delivering mobile downloads, we felt it was critical to put these two building blocks of quality playback and support for larger tablets in place. Today we have an Android development team that is almost 3 times the size of the iOS team. Over the past months this team has made excellent progress building the downloads feature, and with 100% of the team now entirely focused on downloads we’re looking forward to accelerating the delivery and launching asap. Gruber, the Tweet-o-sphere, and other members of the iOS Echo Chamber have read this to mean that it’s impossible to build an Android app without triple the development team of iOS. To me, it reads like a delayed project that needs some extra resources on it. Is it not plausible that iPlayer shifted engineers off of their already released and stable iOS project and onto the still baking Android variation? It’s not dissimilar to what Apple does with iOS and OS X. OS X Leopard was delayed in 2007 as Apple [shifted engineers](http://www.tuaw.com/2007/04/12/apple-announces-leopard-delays-due-to-the-iphone/?ref=justinw.me) from that project to the iPhone to ensure that it could be released on-time. I’m not an Android developer beyond reading all of ten chapters of [Big Nerd Ranch’s Android Book](http://www.amazon.com/books/dp/0321804333/tag=carpeaqua-20?ref=justinw.me), and my vibe so far is that it isn’t much more complex of a platform than iOS. Different? Absolutely. But, it’s just programming. Android is fragmented? I believe it. There’s a million devices? Sure. None of them look or function the same? No doubt. Needing three Android developers for every one on iOS? I don’t buy it. ### Shooting the Messenger URL: https://www.justinw.me/blog/shooting-the-messenger/ Last updated: 2013-07-22T19:32:37.000Z We now supposedly know who is responsible for the Apple Developer Portal being down for the past four days. Security researcher [Ibrahim Baliç](https://twitter.com/ibrahimbalic?ref=justinw.me) has [revealed himself](http://thenextweb.com/apple/2013/07/22/researcher-claims-he-told-apple-of-developer-center-vulnerability-but-didnt-maliciously-steal-data/?fromcat=all&ref=justinw.me) as the source behind what Apple is calling an “intrusion” into their systems. Baliç discovered a vulnerability, among 12 other security issues, that allowed him to access details on over 100,000 Apple developer accounts including their email addresses and names. To see the hack in action, check out his [YouTube video](http://www.youtube.com/watch?v=q000%5FEOWy80&feature=youtu.be&ref=justinw.me). ### Why 100,000 Records? I’m not a security researcher, but my guess is that he accessed that many records to see how deep he could go when reporting the vulnerability. The more data you can access, the bigger an issue it is. Could he have stopped at 100 records and reported the issue? Probably, but we don’t know if Apple would have been so quick to react to it. ### Why the Video? If you look at Apple’s statement they put out on Sunday it reads as if they are the victim of a malicious hacker that broke into their systems and stole information. Here’s the actual wording: > Last Thursday, an intruder attempted to secure personal information of our registered developers from our developer website. Sensitive personal information was encrypted and cannot be accessed, however, we have not been able to rule out the possibility that some developers’ names, mailing addresses, and/or email addresses may have been accessed. In the spirit of transparency, we want to inform you of the issue. We took the site down immediately on Thursday and have been working around the clock since then. In reality (assuming that Baliç is indeed the source for this downtime), a security researcher with a [proven track record](https://www.facebook.com/whitehat/thanks/) of being a white hat hacker discovered the vulnerability and reported it to Apple through their official channels: RadarWeb. ### But That Video Shows Personal Information! Indeed, his biggest crime is posting the personal information of five people in a YouTube video to prove the vulnerability. The irony of a security researcher being so personally insecure about how he is labeled that he goes to YouTube isn’t lost on me. And there are likely better ways he could have proven the hack to the media such as with technical details, but the video is 2 minutes of absolute proof that the issue is there and far easier to understand than technical jargon. Baliç’s biggest crime is having an ego and not wanting his work misrepresented. I don’t approve of the way he went about it, but I’m not going to vilify him over showing five or so email addresses when the good he’s done in helping Apple secure their stuff far outweighs the bad. It will be unfortunate if the only thing people focus on is this video rather than the fact that Apple had a serious vulnerability in their system that left all of our personal information at risk. ### How Do Other Companies Handle This? A lot of tech companies have dedicated pages where they highlight the channels for responsibly reporting security issues. They also give public acknowledgement to the folks who have reported the biggest vulnerabilities. Here are just a few: - [Google](http://www.google.com/about/appsecurity/hall-of-fame/?ref=justinw.me) - [Facebook](https://www.facebook.com/whitehat) - [Twitter](https://twitter.com/about/security?ref=justinw.me) Baliç is listed on Facebook’s list of white hat reporters so I’m willing to give him the benefit of the doubt as doing this work for good rather than nefarious purposes. I’m not a security researcher, but I’ve watched [Hackers](http://www.imdb.com/title/tt0113243/?ref=justinw.me) enough to know that one of the big reasons for exploring these sorts of cracks in systems like Apple’s is for the recognition amongst your peers and other companies. To a white hat hacker, being listed on Google or Twitter’s list of people who have reported major vulnerabilities is not only validation for your work, but also likely money in your pocket as others will hire you to break into their systems. Apple is a culture built around secrecy so I highly doubt they’d set up a public page that championed folks like this, but they have long listed reporters in their [Security Update knowledge base articles](http://support.apple.com/kb/HT5806?ref=justinw.me). ### Someone Must Take The Blame! The vulnerability isn’t Baliç’s. It’s Apple’s. He just discovered it and Apple deemed it severe enough that their response was to take down their entire developer program until they can close the hole. I’ve been [incredibly](https://twitter.com/justin/status/358688240556969984?ref=justinw.me) [vocal](https://twitter.com/justin/status/358987931949608960?ref=justinw.me) about the inconvenience that the downtime has caused me, but knowing how big of an issue it is, I’m fine with Apple taking their time to get the fix right. I am not fine, however, with them trying to paint themselves the victim of malicious intent when in reality it looks as though someone properly reported a vulnerability in their code to them. No one comes out of this looking clean, but it could have been a lot worse if a more dark hacker discovered the vulnerability before Baliç. ### Purging the Back Catalog URL: https://www.justinw.me/blog/purging-the-back-catalog/ Last updated: 2013-03-22T19:00:47.000Z David Smith, creator of personal favorite [Check The Weather](http://click.linksynergy.com/fs-bin/stat?id=5J6ygNnQgI4&offerid=146261&type=3&subid=0&tmpid=1826&RD%5FPARM1=https%253A%252F%252Fitunes.apple.com%252Fus%252Fapp%252Fcheck-the-weather%252Fid557872119%253Fmt%253D8%2526uo%253D4%2526partnerId%253D30&ref=justinw.me), [wrote](http://david-smith.org/blog/2013/03/21/purging-the-back-catalog/?ref=justinw.me) a piece about how he wishes Apple would begin [culling the “back catalog”](http://david-smith.org/blog/2013/03/21/purging-the-back-catalog/?ref=justinw.me) of apps that that are no longer actively being developed. > The App Store currently has around 800k active apps listed. I suspect a significant number of these haven’t been updated in more than 12 months. An app that is listed for sale but is no longer under active development creates the possibility for bad user experience. It is like a grocery store that leaves expired produce on its shelves. The best situation for customers is a marketplace where whichever choice they make results in a great experience. The idea of expiring apps is centered on Apple’s recent announcement that they will no longer accept apps in the App Store that are not retina ready and updated to support the 4″ screen of the iPhone 5 and latest generation iPod touch. I can only think of one app on my phone still not updated for the latest devices[1](#fn-691-1), but I am not as heavy an app shopper as many. While I don’t believe Apple will likely do this because the app count metric is still worth something, it is something I believe is a positive both for the ecosystem itself, as well as independent developers personally. Back in August of 2012, I [killed](https://www.justinw.me/2012/08/20/a-therapeutic-killing/) both MarkdownMail and the elder statesman of the Second Gear catalog, Today. Both were still bringing in a small amount of sales, but the emotional burden of having apps in the store that I know could use improvements, but have zero interest in working on anymore is heavy. It’s also difficult for me to get over the gross feeling that I would be taking someones $3 – $10 for an app that worked, but really wasn’t actively supported going forward. Financially, it wasn’t my wisest move, but I’ve done way dumber things with money. This is also why I was more understanding of Google’s decision to axe its Reader project in favor of focusing on other projects. While I sympathize with the people losing a utility they were fond of, tossing rotting software in the dumpster makes room for future innovations from other developers in that space, and allows Google to focus on the things it’s most interested in. \- - - - - - 1. Looking at you, Boxcar. [↩](#fnref-691-1) ### 30 URL: https://www.justinw.me/blog/30/ Last updated: 2012-11-10T19:00:05.000Z - Born - Crawled - Walked - Nearly died - Lost my tonsils - Lost my baby teeth - Moved to Indiana - Went to elementary school - Won the spelling bee three times - Discovered the Internet - Went to junior high - Had my first kiss - Taught myself Visual Basic - Met my high school sweetheart - Grew my hair to my shoulders - Almost got expelled, multiple times - Went to high school - Met the girl I would marry - Switched to Linux - Spent far too much time switching between Debian, Slackware and Red Hat - Learned to drive - Graduated from high school - Switched to a Mac - Went to Purdue - Experienced my first heartbreak - Failed out of Computer Science after 1 semester - Went to the University of Southern Indiana - Went back to Purdue - Graduated Purdue (but not for Computer Science!) - Started Second Gear - Learned Objective-C - Released [Today for OS X](http://www.macworld.com/article/1133435/today.html?ref=justinw.me) - Got an iPhone - Built [PocketTweets](http://www.tuaw.com/2007/07/09/pockettweets-twitter-for-iphone/?ref=justinw.me) with Robert Andersen - Released [a native iOS app](https://www.justinw.me/2009/05/05/fitnesstrack-10/) - Started FuckingNDA.com - [Quit the App Store](https://www.justinw.me/2009/10/16/back-to-the-mac/) - Did a radio show for a year - Did a radio segment for two years after that - Got married - Moved back to Central Indiana - Organized [Indie+Relief](http://www.indierelief.com/?ref=justinw.me) with Garrett Murray and raised $143,872 for charity - Started public speaking - Went back to the App Store with Elements - Dealt with a lot of health stuff - Got a divorce - Sold everything and moved to San Francisco - Shipped HotelTonight’s iPad app - Went to Hipstamatic - Became an uncle - Made some great friends - Got laid off at Hipstamatic before I could ship anything - Sold everything that didn’t fit into [four boxes](http://instagram.com/p/P7S1xCGkpz/?ref=justinw.me) and drove to Colorado - Turned 30 Here’s to another thirty years. ### Issues With Achieving Auto Layout Zen URL: https://www.justinw.me/blog/issues-with-achieving-auto-layout-zen/ Last updated: 2012-11-02T19:00:45.000Z All of the projects I am currently working on are targeting iOS 6, so I have used it as an opportunity to finally dive into the deep end with Auto Layout. [Committed](http://bit.ly/committed10?ref=justinw.me) was my first foray with the technology on the Mac this summer when I laid out the preferences window using constraints rather than traditional springs and struts. On a simple window like that with just a few tables views and buttons the experience is pretty straight forward. As I don’t have much experience with anything more complex on the Mac, I’ll refrain from commenting on that experience much more. My focus the past few months has been on iOS where Apple introduced Auto Layout as part of the iOS 6 launch. Auto Layout is touted as being superior to the old springs and struts based layout styles because it allows building layouts that can scale to a variety of different screen sizes. Working on a platform with 3.5″, 4″, 7.9″ and 9.7″ devices? Sounds like a great technology to adopt! ### The Learning Curve Auto Layout has one of the steepest learning curves of any new technology I’ve worked with. There are at least three different things you need to keep track of on the basic level. Step one is wrapping your head around working with constraints in Interface Builder. Step two involves using the code-based NSLayoutConstraint, which includes the visual formatting language. Step three revolves around debugging and dealing with more advanced things like animation. Even after a few months of using Auto Layout, I still don’t feel the level off comfort using the technology as I would with any previous ramp up I have had. ### Interface Builder Is The New HAL 9000 Apple tends to recommend laying out constraints using Interface Builder whenever possible because it’s a bit easier to visualize what you are doing. Plus, who doesn’t prefer clicking buttons instead of typing more code? What frustrates me about setting constraints with Interface Builder is its instance on adding more constraints automatically for me, even if I don’t want/need them. I’d love some sort of button or setting I can click to tell Interface Builder to back off and just let me handle everything. The workaround I tend to have for these constraints I don’t really want or need is to set them with a lower priority (*Radar: 12625299*). ### Debugging Ambiguous I’ve had better luck trying to read women in my failed relationships than trying to debug why my constraints aren’t working out. When working with a view in Interface Builder, I’d hope that it would be able to tell me that my layout was ambiguous before I went through the process of recompiling and running my application. In the case of the primary project I’m working on right now, all the constraints are written in code, so the only recourse for debugging really is calling `[self.view _autolayoutTrace]`[1](#fn-731-1) from LLDB. Calling `_autolayoutTrace` will give a breakdown of the hierarchy of your views and list any of them that have ambiguous constraints, but that’s it. Great. I have view that’s ambiguous. Now what? A lot of trial, error, and tears usually. There’s a category on `UIView` called `UIConstraintBasedLayoutDebugging` that has three methods for trying to debug constraints, but it’s still far more trial and error debugging than was ever necessary with springs and struts. OS X has an Instrument tool for working with constraints, but it’s not available for iOS. I’ve never used it, so I can’t speak to its benefits but in general any tool that makes debugging easier would be a win. (*Radar: 12625327*) Ideally there would be a way to visualize constraints either on device or in the iOS simulator so see what constraints are affecting a specific view. `NSWindow` has something similar to its `visualizeConstraints:` call. I’d love to see that for iOS. (*Radar: 12625312*) ### Documentation? When something has such a steep learning curve as Auto Layout, you want to provide as much documentation and help as possible, especially if you want developers to adopt the technology. In the case of Auto Layout, the best documentation isn’t in Apple’s official documentation. It isn’t in a book. It’s in three hours of WWDC 2012 videos. Seriously, if you are going to work with Auto Layout you should watch sessions 202, 228 and 232\. And then watch them again. The problem is that a lot of the information I find in these three hours of videos isn’t really replicated in the documentation. Like a lot of Apple documentation, it highlights the happy path of what you can do with Auto Layout, but leaves you to sink or swim once you get beyond that. The WWDC videos, on the other hand, handle a lot of those hairy edge cases and complexities you may run into when working on a product that is larger than demo size. Sample code on Apple’s side related to Auto Layout is also pretty sparse. Again, I’m a visual learner. (*Radar: 12625370*) ### Animation Animation is a core component of a modern OS X or iOS application. At a basic level, animation revolves around adjusting the frame of a view or adjusting its transform. With Auto Layout, the recommended way to do any sort of animation is to animate the constraints. Animating constraints is a bigger pain in the ass than animating frames. You have to keep a strong reference to each constraint that you want to animate and usually either re-set the constraint or adjust its constant value depending on what you’re doing. I recently was trying to figure out how to zoom an Auto Layout-based view to fill the entire parent view that contains it. I uploaded a [sample project](https://github.com/justin/Auto-Layout-Zooming-Example/?ref=justinw.me) to iOS with a solution to the problem, but I can’t help but feel like I had to write way more code to accomplish this than I ever would have the old way I don’t really have a suggestion for a way to improve this. I just think it’s a pain point. Despite the learning curve and the frustrations I have with Auto Layout in its current incarnation, I plan to continue to use it. Unlike something like bindings on OS X, I think they are a fundamental aspect of development going forward that will be difficult to avoid using. \- - - - - - 1. Eat it, dot syntax haters. [↩](#fnref-731-1) ### (no title) URL: https://www.justinw.me/blog/751/ Last updated: 2012-09-10T19:00:34.000Z Four weeks ago this Thursday myself and four other ridiculously talented people were [laid off](http://pinboard.in/u:justin/t:hipstadramatic/?ref=justinw.me) from our jobs at Hipstamatic. In the time since then we have all been trying to figure out what was next. I personally took several coffees and interviews with companies in the Bay Area as well as other cities around the country. Many of the opportunities would be lucrative. Some would be interesting. Others had a high probability of seeing an excellent payday if I stayed around long enough. None were exciting though. Nothing I heard or saw really got my mind racing with ideas and excitement about what I could accomplish there. In the end, I kept coming back to what I used to do full-time: [Second Gear](http://www.secondgearsoftware.com/?ref=justinw.me). I started Second Gear the day after I graduated college and it was my full-time job for six years, up until January when I packed up and moved across the country to the Bay area to try out startup life and see what life was like outside of my Indiana bubble. What I learned is it’s not for me. So, I’m back full-time at Second Gear. Reviving my company and focusing on products of my own is what gets me excited and what I love doing. It may not be as lucrative or sexy, but it’s far more rewarding in other ways. I’ll be splitting my time between doing my own products and contracting work [1](#fn-751-1) for the time being while I replenish the coffers. Updates to [Elements](http://bit.ly/n3UP7b?ref=justinw.me) are in the works and I’ve already submitted a new app to Apple for review that I’ve been working on over the past few weeks. While I’m returning to the job I left at the end of 2011, I’ll also be saying goodbye to the city I left it for: San Francisco. In three weeks time, I’ll be loading up a rental car and driving what remains of my belongings to Denver, Colorado to start an all new adventure in an all new city. I don’t regret my excursion West to get something that has been in the back of my head for so long out of my system. In the end, it was what I needed to realize what I’m best at doing: my own thing. Back to work. \- - - - - - 1. Hire me! [↩](#fnref-751-1) ### A Therapeutic Killing URL: https://www.justinw.me/blog/a-therapeutic-killing/ Last updated: 2012-08-20T19:00:10.000Z A few months ago I started to have that itch again. You know it. You’re happy with what you’re doing at your day job, but the prospects of your own ideas are starting to take over a larger part of your brain. Knowing how I am, this was something that was only going to grow. I started to think about what I wanted to do with the next steps of Second Gear. I told myself I was going to put into place a 12 month plan where by this time next summer I would have a new product or two out that would hopefully be bringing in enough income to sustain me going back as a full-time independent.[1](#fn-771-1) Part of that plan was deciding the fate of existing [Second Gear](http://www.secondgearsoftware.com/?ref=justinw.me) products. Each product was bringing in revenue, but none of them are exactly setting the charts on fire for a variety of reasons. Namely, my full-time employment these past eight months has meant neglecting doing updates in favor of actually getting a good night’s sleep or relaxing after a long day of writing code. There are some people who eat, breathe and sleep code. I’m not one of them. I’ve got about 6 good hours a day in me and then my brain turns to mush. Even though each product was bringing in revenue, not all of them were getting me excited about the prospects of what is next. In fact, they were occupying a portion of my brain that was constantly nagging me with ideas about the things I knew I should update, fix or add to make them better products. None of that seemed like exciting work. When I was in Melbourne a few months ago for One More Thing, I remember having a conversation with [Loren Brichter](http://twitter.com/lorenb?ref=justinw.me) about products like this. He said he would kill anything he wasn’t interested in working on anymore, because it seemed like the right thing to do. I agree. That’s why I recently decided to kill both MarkdownMail and Today. Financially, it may not have made much sense to cut off the revenue streams, but therapeutically I’m freeing up that portion of my brain to focus my full attention on the next version of Elements and the dozens of other ideas that that are circling in my head. Full speed ahead. \- - - - - - 1. Little did I know that my 12 month plan would [turn into](https://www.justinw.me/2012/08/17/thank-you/) a 12 minute plan, but that’s the cards you’re dealt sometimes. [↩](#fnref-771-1) ### Thank You URL: https://www.justinw.me/blog/thank-you/ Last updated: 2012-08-17T19:00:36.000Z Eight months ago I decided I needed a change. I wasn’t sure what I wanted to do next in with my life or career. Six years of running Second Gear was rewarding personally, but financially it was a life of constant worry and living paycheck to paycheck. Coupled with complications in my personal life, I decided the best course of action was to put my life in reset, pack up my belongings and move to San Francisco. San Francisco is a technology enthusiast’s wet dream. Everywhere you turn there are people building things. Some things will change your life. Others will change the world. Many are dumb. Many more will fail. But above all else, everyone is working towards a common goal of exploring technology and what we can do with it. Yesterday, I experienced my first layoff as myself and many of the other talented people at Hipstamatic were let go as part of a downsizing. In retrospect it wasn’t that shocking. When you play back things in your mind, the signs become more obvious. It doesn’t make it any less frustrating knowing that yesterday you thought you had job security and today you’re sitting and writing this article in your gym’s cafe area. Yesterday was unlike anything I have experienced before. From a [single tweet](https://twitter.com/justin/status/236134448792481792?ref=justinw.me) spawned several more [tweets](https://twitter.com/schwa/status/236155846680260608?ref=justinw.me), [articles](http://thenextweb.com/insider/2012/08/16/hipsta-dramatic-hipstamatic-lays-core-employees-including-designers-engineers/?ref=justinw.me), [blog posts](http://www.theverge.com/2012/8/16/3247801/hipstamatic-layoffs-synthetic?ref=justinw.me) and [reactions](http://daringfireball.net/linked/2012/08/16/hipstamatic?ref=justinw.me) around not just the iOS developer community, but also the technology community at large. My inbox is now filled with job inquiries, nice notes from people I don’t even know and even a photo of a puppy. I don’t know what I’m going to do next. I could walk into any startup in this city and have a job by the afternoon, but that’s [not what I want](https://www.justinw.me/2012/08/12/the-stages-of-startup-life/). Whether I take another full-time position, go back to Second Gear full-time or chase one of the crazy life changing ideas circling in my mind, I’ll always remember the support that friends, colleagues and strangers were there to give. Thank you. ### Directing User Feedback URL: https://www.justinw.me/blog/directing-user-feedback/ Last updated: 2011-04-01T19:00:21.000Z I received a bit of feedback on [‘Useless’ Is a Loaded Word](https://www.justinw.me/2011/03/28/useless-is-a-loaded-word/) and [Why I Don’t Do Sales on the App Store](https://www.justinw.me/2011/03/23/why-i-dont-do-sales-on-the-app-store/) where some misunderstood and assumed I completely ignore user feedback. That could not be further from the truth. In fact, I do my best to make sure I am accessible in as many venues as I can be comfortably as a one man development shop. The problem with leaving feedback and bug reports on the App Store is that developers have no way to respond or followup on the reviews. Apple holds on to customer data with a an incredibly tight grip. This is a good thing for those paranoid about their email and name getting out to a variety of small companies, but when it comes to supporting users it makes it nearly impossible. Trying to identify an App Store reviewer named ‘crazyfun666’ and getting in touch with them to try and work with them through a problem is an exercise in frustration. [1](#fn-811-1) Instead of focusing on a channel of feedback that is toned towards negativity and impossible for me to have a conversion, I choose to shift my customers to other avenues for submitting their support requests. ### App Store At the bottom of each product description on the App Store and every release notes screen that appears in the App Store app I append the following: > SUPPORT > > Please refrain from sending your bug reports or feature requests using the App Store. Instead, to ensure a direct response from us send them to [support@secondgearsoftware.com](mailto:support@secondgearsoftware.com). You can also tweet us at [http://twitter.com/secondgear](http://twitter.com/secondgear?ref=justinw.me) or Like us at . We’re always happy to help our users and receive their comments! It is not an original idea. I believe the first person I saw do it was [Edovia](http://www.edovia.com/?ref=justinw.me), but it is a brilliant piece of marketing. 1. It informs the user of the proper methods for sending support and guaranteeing a response to the inquiry. In this case **not** the App Store. 2. It offers a support email address for the user. 3. It offers the user a link to your company Twitter account, which is a decent avenue for support and a great way to get product news out rapidly. 4. It offers a link to the company Facebook Page for those that aren’t into Twitter. What’s better is that if the user is viewing this information on the updates screen in the App Store app, the links to Facebook and Twitter are clickable so the user’s browser will launch and take them directly to the page to follow or subscribe. ### In App Support Asking users to not use the App Store as a venue for support is one thing, but you need to ensure that it is easy for them to get in touch with you. Most people seek out the App Store as a venue to vent frustrations and submit feature requests because there is no easy and obvious way to get in touch with the developer. ![Send Feedback](https://i2.wp.com/cdn.carpeaqua.com/uploads/2011/04/elements_send_feedback.png?resize=266%2C400) In Elements I have “Send Feedback” prominently displayed on the Settings screen inside the app. Tapping the button will launch an email sheet that sends an email directly to me where we can have a dialog about what features you would like to see in the app, or what issues you may be running into. In addition, I also have a longstanding habit of putting an About screen inside the app that contains more company information including another link to email support, the physical Second Gear homepage and a link to our social media pages. If you tap the Twitter or Facebook buttons, Elements checks to see if you have a native app installed on your device and then launches the respective native app and takes you directly to the profile page.[2](#fn-811-2) If there is no native app installed, it defaults back to launching MobileSafari so you can follow or Like in the traditional way. ![About Elements](https://i0.wp.com/cdn.carpeaqua.com/uploads/2011/04/elements_about_screen.png?resize=266%2C399) ### Twitter The [@secondgear](http://twitter.com/secondgear/?ref=justinw.me) Twitter account is a great first method of contact with users. I use it often to do release announcements as well as to gauge customer interest in potential features or changes in an app. For instance, I recently asked my Twitter followers whether they used Elements in portrait or landscape primarily and what was their primary font. It is a small subset of my user base, but it gave me more than enough data to use in deciding the direction I am taking the application going forward. I try not to use Twitter for anything more than basic support. It is hard to debug complex issues in 140 character increments. If a customer asks me a general question that can be answered in a single tweet, I will most likely answer it right there. If it is something that is going to require a bit of back and forth, I ask them to email me the request in so I can more easily track it and take the time to offer a more complete response. ### Facebook I don’t do much support with the [Second Gear Facebook page](http://www.facebook.com/secondgearsoftware) mostly because not that many people who use Elements are Facebook junkies. In fact, up until recently it was impossible as far as I could tell to be notified when a customer posted on a comment or status message on your Facebook wall. There was an instance where a customer left a comment on a several week old post asking a pre-sales question that I didn’t see. I felt terrible about it and send him a private message apologizing for the issue. Facebook now will email you when a comment is left on your Facebook page which makes it easier to use as a support venue, but I still prefer Twitter for social media interaction. ### Potential For Improvement If Apple did a single thing to improve the App Store experience for developers and users alike, it would be to allow us to respond directly to an App Store review either in the store itself or via a private email send through iTunes Connect. Being able to interact with customers through the App Store would make me much more open to reading reviews because it would become a legitimate support channel. As it stands App Store reviews are just anonymous graffiti left on the iTunes wall as a user passes through. \- - - - - - 1. Because of the contact difficulties associated with App Store reviews, I have my name set to ‘Justin Williams (@justinw)’ on my reviews. It is a bit of a helpful hint for the developer who reads them. More than a few have contacted me via Twitter to thank me for the feedback. [↩](#fnref-811-1) 2. This trick doesn’t seem to work on the iPad version of Twitter. [↩](#fnref-811-2) ### 'Useless' Is A Loaded Word URL: https://www.justinw.me/blog/useless-is-a-loaded-word/ Last updated: 2011-03-29T19:00:15.000Z Here is a tip for all the non-developers out there. When you email your favorite developer with a feature request or bug report never, ever, ever use the word *useless* to describe their product. *Useless* is kryptonite to developers and puts us on the defensive instantly. In most cases *useless* is used as because of a bug impacting a user’s experience or a pet feature is missing from an app that makes it absolutely perfect in this use case. To trump up the importance of the issue, the user tosses a loaded word into the email to improve the chances of getting it resolved. That’s probably not the case though because we are grumbling under our breath what a jerk you are for insulting our baby. In the case of independent developers like myself, my products are my livelihood and when you describe them with such venomous words you are attacking my way of life. Even most mid-size to large companies have the same sort of pride in their work and don’t want some angry Internet dork to spout off via email about why it is the worst thing to happen to humanity in a decade solely because it doesn’t work how he expected. The Internet makes it really easy to be a jerk to someone because you don’t have to insult their product to their face and can instead shoot it off to an email address in the sky without any idea or care about who is on the other end. Let’s imagine typical Internet behavior from a few different scenarios: You go to a gourmet restaurant in town that opened a few months ago. The chef makes great food and also makes himself available to you during the course of the meal. He comes to see how things are going and you inform him that your potatoes are cold which makes the entire meal pretty much useless. You order a custom built desk from a local craftsman. This guy is the best. He builds everything with his bare hands in his shop and then sells it to local folks for a fair price. He is the quality alternative to the crummy sawdust and plastic desks that you see sold at the office supplies stores. The craftsman delivers your brand new desk to your home and believes it’s one of his best works yet. You look at the desk and notice it doesn’t have castors on the legs and tell him the desk is all but useless since you can’t easily slide it around the room. Your sister has a baby. You visit the hospital to see what all the hubbub us about. When you realize that infant doesn’t even know how to flush the DNS cache on a Mac, you say, “That thing is all but useless!” There are some seriously awkward holidays in your future. [1](#fn-831-1) In almost any life situation where you need to get something out of another person, being a dick is never the right method to go about it. Using loaded words like ‘useless’ or ‘worthless’ is being a dick. We will listen to your feedback and thank you for it, but unless it is some urgent issue that will affect every user, it’s most likely getting shoved to the bottom of the pile in favor of doing things to make the friendly customers happy. I have developed a mildly thicker skin in the nearly five years I have been in business, but I doubt I will ever develop the tortoise shell I truly need to interact with the angry typing guys of the world. I don’t plan to either. I would rather put that effort towards improving my products for the people who have requests or issue that need a resolution, but are courteous. Be nice. Don’t use loaded words to try and get what you want. You’ll get a lot farther with me and the other developers out there who think like me. \- - - - - - 1. Ok. I’m reaching on this one. I just envision this is how a typical Internet commenter interacts in real life. [↩](#fnref-831-1) ### Is It More Interesting To Code Or Drink & Talk About Code? URL: https://www.justinw.me/blog/is-it-more-interesting-to-code-or-drink-talk-about-code/ Last updated: 2010-11-06T19:00:04.000Z When I first got interested in the Mac platform and Cocoa development, it was a small victory if I walked into a Borders or Barnes & Noble and saw Aaron Hillegass’s [Cocoa Programming](http://www.amazon.com/exec/obidos/ASIN/0321503619/carpeaqua-20?ref=justinw.me) book. Back then computer section bookshelves were filled with books on .Net, Java and Microsoft Office. Mac related conferences were also few and far between. MacHack existed and Apple held WWDC each year, but beyond those meetups, the Cocoa platform was relatively quiet. Fast forward almost a decade and Apple has its own section at your local Barnes & Noble with many of those books being dedicated to building iPhone apps[1](#fn-851-1). It also seems like there is a Mac or iOS related conference every month where developers flock to meet, discuss code and share their thoughts on the current state of the industry. I’m writing this post 30,000 in the air on my way to Austin for one of those conferences: [360iDev](http://360idev.com/?ref=justinw.me). This is my second conference this year after making the trip to Atlanta for NSConference earlier this year and pretty much fills my quota for outside events.[2](#fn-851-2) Conferences like 360, WWDC and Voices That Matter are great events to refuel your Kool-Aid repositories, but I can’t help but wonder when the bubble is going to burst. As with any hot technology, people swarm around it anyway they can. Developers are flocking to iOS as millions upon millions of iPhones and iPads are sold every quarter. Marketers are starting to become append “iOS expert” on their business card right underneath “Social Media Guru” and “Web Visionary”. Conference organizers also see there is money to be made by channeling the high interest in Cocoa. I don’t fault them for it. One of my most rewarding experiences this year was going to NSConference and meeting so many people who enjoyed participating or purchasing software through the [Indie+Relief](https://www.justinw.me/2010/01/14/a-days-sales-for-haiti/) event I organized earlier this year. Instead, I’m more curious the motivation of those people who attend each and every one of these conferences either in the capacity of a speaker or attendee. My preparation time for my presentation and trip to 360 this week took an entire week of time away from me working on my Second Gear products. The run-up to WWDC each summer gives me the same “gotta get it done before San Francisco” mentality. I’m find doing that once or twice a year, but anymore time away from improving my products feels like time wasted. Camaraderie is great, but so is shipping software. That’s what I prefer to do. \- - - - - - 1. I still consider Aaron’s line of books the best [↩](#fnref-851-1) 2. Though I did agree to speak at 360MacDev next month, but only because it was a dedicated Mac conference and I want to see more Mac only events. [↩](#fnref-851-2)