Category Archives: Programming

Lightweight universal apps

When the iPad first shipped, many developers embraced completely separate apps for iPhone and iPad. The argument was that they were different platforms and deserved special design attention (and separate revenue). I never bought this argument, and eventually — with the iPhone 6 Plus and multiple screen sizes — everyone agreed that it just made more sense to use universal apps.

At the same time, there’s a parallel argument that an app on the iPad shouldn’t just be a “scaled up” version of the iPhone. That if you can’t invest the time to do a universal app properly, don’t bother.

The redesigned Twitter iOS app was a great example of this. It was widely mocked for it’s poor use of space on the iPad.

With the iPad Pro and widespread iPad multitasking, I think this changes again. An iPad app that is designed exactly the same as its iPhone version is still very useful in slide-over and split screen. In fact, for many “iPad” apps I use every day on the iPad Pro, I use them in their compact layout more often than full screen.

My next app was designed for the iPhone. I spent some time trying to rework it with split views for the iPad Pro, but I just can’t justify the work right now to finish that effort. I’m going to ship it as a “lightweight” universal app anyway, though, so that it’s available in slide-over. To me, that’s a worthwhile compromise, significantly better than no offering on the iPad at all.

Swift and Core Intuition 209

Like many developers, I’ve spent the morning looking over the Swift open source release. I continue to be intrigued and look forward to working Swift into more of my routine.

On today’s Core Intuition, Daniel and I talked about Swift for about half of the 50-minute episode. We recorded the episode yesterday afternoon, before the open source announcement, so we’ll be following up next week on everything that has changed. I bet there will be some more progress in Swift web server frameworks by then, too.

Apple Pencil, for real

As we talk about on Core Intuition episode 208, I finally got an Apple Pencil. It’s great. My experience matches Gus Mueller’s, about how good the Apple Pencil is after years of using Wacom tablets and third-party iOS styluses:

“I find that when using the HB Pencil in Procreate, I get something that is very, very close to what I feel when I’m drawing in my sketchbooks. But of course now I’ve got layers and many colors and a perfect eraser to work with. And endless pages. I love it.”

On the question of whether it’s a “stylus”, Ben Brooks sums it up this way:

“That’s the question I get asked a lot from people — my wife especially. Apple will tell you it is not a stylus because it is so much better than any other stylus, it clearly is something else. So, instead, I’ll tell you that it is very much a stylus — it just so happens to be the best stylus I have ever encountered on any device.”

I’ve also been improving the Apple Pencil support in an iPad app I’m working on. I haven’t completely finished reading Russ Bishop’s article on supporting the Apple Pencil, but looks like it has a bunch of additional tips in it that I’d benefit from. It covers not just the API changes to UITouch, but also gestures, coalescing, and predictive touches.

Developing for the iPad Pro

Let’s start with a quote from the MacStories review by Federico Viticci:

“For developers, it’s time to be bold with their iOS apps and understand that they can be more than single-purpose utilities. There are millions of people who aren’t buying PCs anymore because mobile devices are their only computers.”

I’ve been using the iPad Pro a lot in just the last two days. Apps that have taken advantage of the larger screen — and that support iPad multitasking well — are just much more useful. It’s great to have Slack or Tweetbot in the sidebar and a writing app in the main part of the screen. (Until Editorial is updated, like Seth Clifford I’ve switched to Byword.)

As a developer, going from an iPad Mini to an iPad Pro has opened my eyes to what Federico says above. You simply can’t have a great iPad app today if it doesn’t attempt to fit well on the iPad Pro. So although I said I would discontinue my app Tweet Library, I’ve actually been spending some time this week to update it to support iPad multitasking.

The key to iPad Pro support is actually less about auto layout (although that’s helpful too), and more about split views and size classes. For a modern app, this is an easy transition. But Tweet Library was written for iOS 4. Back then, UISplitViewController was extremely underpowered. I had used MGSplitViewController instead, which I’ve modified over the years to adapt to multiple screen sizes from the iPhone to the iPad. So the first step to real iPad multitasking was to rip out most of the split view code and start over with a clean foundation based on iOS 8/9 and UISplitViewController. Not exactly trivial work that I could knock out in a day, although I tried.

I remain very optimistic about the iPad Pro, especially when the Apple Pencil is actually available. From a business standpoint, it also seems like a better investment in time than either the Apple Watch or Apple TV. There are so many platforms and distractions now. If I can’t focus on a single platform, I want to at least be proactive in saving some attention for the iPad.

Two weeks notice: unfinished work

Three weeks ago I had about a dozen open Jira tickets. Today, my last day with the company, most of those are still open. I was able to update some documentation and do minor maintenance work, but a bigger change I had hoped to deploy turned out to be impossible because of a missing internal API.

It’s unsatisfying to leave unfinished work. There’s only so much that can be done in a limited time, though, and as we all know software (especially a web app) is rarely ever completely finished.

Bittersweet, moving on after so many years. The folks I’ve worked with have been really great. I’m going to enjoy keeping an eye on what they ship long after my GitHub access has been revoked.

This morning, my (now) former boss and good friend Willie Abrams linked in the company chat room to some of the photos that he had taken over the last 14 years. Brought back a lot of good memories, from brainstorming app features in a conference room to wandering around San Francisco before WWDC.

I think I’m going to let this be the final post to wrap up the “two weeks notice” series. I’ve accomplished a lot but there is still plenty left, especially shipping new products. It’s been good to force myself to write every day, so I’ll keep that going with the usual full posts and microblog posts.

You can find all 14 posts under the tag “2weeks”. Thanks for reading.

Two weeks notice: final pull request

With just 5 days left at my regular job, it’s time to get serious about wrapping up my work. I have a small change mostly ready and tested locally, but need to push it up to GitHub and finish testing on the dev server. I have a couple open Jira tickets to look at after that.

Over the weekend I spent a lot of time with the Stripe API, trying to improve how I manage user subscriptions. Stripe has some new features since I first started using it. For example, options for sales tax and a quantity field. The latter is convenient if you have something like the ability to pay for multiple hosted web sites in a subscription, rather than deal with adding custom line items on an invoice.

Deadlines are an excellent way to push yourself to actually finish something. So this deadline of Friday is good, in a way, but unlike most of my other deadlines, I can’t miss it and keep working for another week. That finality is a little daunting right now, as I look at the week ahead and everything I want to get done.

I think it’s a bust

The movie Draft Day doesn’t really have any business being good, but somehow it is anyway. I don’t even like football that much — who has time for it when there’s basketball? — but I’ve now seen this movie several times and love it. The movie actually gets better instead of worse on multiple viewings.

It also has a number of memorable lines. One of them is this, said by Kevin Costner’s character about the college football star who everyone thinks is the next greatest thing: “I think he’s a bust.” Five simple words that undo all momentum.

And unfortunately that’s still how I feel about Swift. I’m following Brent’s blog posts about learning Swift and I’m trying to come to terms with whether to adopt the language, and I finally got it. I already have a capable quarterback in Objective-C, and I’m not ready to rebuild my roster yet, risking everything on a young language with so much promise but less real-world success.

No matter how much Swift has improved, no matter how much everyone fawns over it, I still can’t shake the feeling that it’s a hype that someone else’s team needs. For me, it won’t end up solving the problems I have when building apps. For me, it’s a bust.

Retiring App.net support for Sunlit

Sunlit 1.3.1 shipped today. It’s a minor update focused on fixing bugs, but it is also the first version to remove App.net support. Existing users still have access to all the App.net features — the code still exists in the app for now — but the App.net sign-in button and settings have been removed for new users to simplify the requirements and UI.

It was difficult to let go of the App.net-specific features. A significant amount of the codebase was around syncing and collaboration features via App.net. There was also some great location check-in support built on App.net locations and compatibility with Ohai. I had to remove screenshots and prune down the App Store description to account for the removed features.

What’s left is an app that has fewer features but which feels light and simple again. Maybe this should have been our 1.0 version all along.

Two years ago, I wrote about waiting for App.net’s killer app:

“The promise of App.net is bigger than one type of app. App.net isn’t just a blank slate; it’s an amplifier. It’s waiting to power the next new idea and help it grow into something big.”

This vision didn’t pan out. But I’m proud that we gave it a shot and put a lot of effort into the platform even after others had given up on it. Now that we’ve finished this “reset”, of sorts, we’ll move forward to build other features we always wanted in Sunlit.

Fun apps don’t need clean code

Jared Sinclair says that a successful app has nothing to do with writing clean code. Thinking about Riposte:

“Riposte, still used and loved by some App.net diehards, has one or two view controllers I wrote that are thousands of lines long. The app was littered with procedures that should have been generalized but got copied-and-pasted everywhere. And it didn’t matter.”

Most programmers try to improve their code a little from one project to the next. But obsessing about how the code looks and how it’s structured might mean that you’re not spending enough time worrying about the things that matter even more: what the app looks like and what it does (and ever shipping it).

iOS 9 search

Federico Viticci has a comprehensive write-up about Apple’s approach to search in iOS 9, including comments from developers. On local app search:

“With local app search, iOS 9 can build an index of content, app features, and activities that users may want to get back to with a search query. Built like a database and already in use by Apple apps such as Mail and Reminders, CoreSpotlight will provide low level access to the index of an iOS device, making it easy to organize and retrieve content users have previously seen, created, or curated.”

I’ve been slowly going through WWDC session videos, but haven’t cracked open the documentation for search yet. Sounds like an important new API for any app that has user documents.

Clever code and WWDC

In his 9th essay about avoiding crashes in your code, Brent Simmons writes about learning to be even less clever:

“But over the years I’ve come to think that I should write code that’s about 10% as clever as I am. And I’ve come to believe that true cleverness is in making code so clear and obvious that it looks like nothing at all.”

I’m in San Francisco for WWDC this week, but without a ticket again. I took some time this afternoon — miles away from the hotel and Moscone — to reflect on what I’m doing here and what I need to do next. I’ve been to WWDC many times; my first was in 1996. And it has taken almost all of those years for me to understand the truth of Brent’s statement about being clever.

I also believe that a programming language can either encourage or discourage clever code based on the syntax it allows. I saw it with Ruby — programmers intent on fitting as much logic into a single line of code as possible. I think I see it with Swift as well, in operator overloading and maybe even a kind of rejection of Objective-C’s notorious verbosity. We’ll know for sure if we eventually see a Swift book in the pattern of JavaScript: The Good Parts.

Watermark transition plan

I sent an email to Watermark customers over the weekend, letting them know that the service as it currently exists will be going away on May 15th. As I wrote about last year, Twitter has improved their search enough that a part of what Watermark is good at is no longer as necessary as it once was. However, I still see interest in Tweet Marker, from developers and users, so I wanted to keep the web-based timeline and sync from Watermark and make it available to all Tweet Marker subscribers.

You can learn more about Tweet Marker here. I’ve had to significantly scale out the backend servers this year, including adding a second load balancer, so I’d love your support. The new timeline feature will roll out later in May.

While I’m happy to keep offering a part of Watermark (now back in Tweet Marker), I have less good news for Tweet Library. I’ve found it very difficult to justify the time to finish the new version. It’s now looking likely that the current version will be the last.

Searchpath improvements

As part of a renewed commitment this year to work on my web app Searchpath, I’ve just rolled out a few improvements. A search engine like Searchpath needs frequent maintenance to keep running smoothly — minor bug fixes and behind-the-scenes work on queues and web crawling — but I also hope to catch up on new features that I’ve long planned for the product.

One marketing bullet I always had that wasn’t fully realized: “Also serves as a text backup for your site.” Searchpath now exposes links to download both the HTML for any stored page on your site as well as a text-only version of that page after Searchpath has attempted to trim out the navigation and other links. Hopefully this will help out any customers who might need to retrieve lost text from their site if their primary site backup failed (or doesn’t exist).

Searchpath is free to try and $8/month or $75/year. Setup is as simple as copy/pasting one line of JavaScript where you want a search box. You can learn more and get started here.

WWDC 2015 dates

WWDC will be June 8-12 this year, with a lottery for ticket selection. I’m not going to put my name in the hat for a ticket; I hope to save some money and let others have a chance. I’ll be in town for a few days to meet up with folks and attend AltConf, which looks excellent again.

The student scholarship page caught my eye this year. App submissions have to be written using at least some Swift:

“To be considered for a WWDC 2015 Scholarship, build and submit an app that showcases your creativity and technical skills. Your Mac app or iOS app must be written in Objective-C and Swift, or written entirely in Swift.”

I’m also starting to reset my expectations for a more full-featured, native Apple Watch SDK. I think we’ll see welcome improvements to WatchKit, but with the watch still weeks out from shipping, it seems too soon for a reimagining of the API by June.

Goodbye Riposte

Jared Sinclair announces that Riposte will no longer be available:

“As part of an agreement reached over an alleged trademark infringement, Riposte (the App.net app I made with Jamin Guy) will be removed from sale on the App Store. We’ll also be taking down the riposteapp.net homepage.”

Even today, Riposte is arguably the best social networking client out there. It pioneered consistent gestures for navigation. It will remain on my home screen for some time to come.

Short and sweet job posts

I’ve been very happy to see the variety and high quality of jobs listed on our Core Intuition Jobs site. Two in particular have recently caught my attention for being concise, as if they don’t want to waste a potential candidate’s time with too many bullet points.

First up is Betaworks, which you’ve heard of as the company that now develops apps like Instapaper and Digg. Here’s the listing in its entirety:

“We’re working on a bunch of brand new products at betaworks and are looking for iOS contractors to help our existing engineers move faster. We’re ready to start ASAP and this gig will go through June (with the option to stay on for longer if you’d like to). Email us for more info if you’re interested!”

And here’s new startup Honest Dollar, where you’ll be working in downtown Austin with my friend Justin Youens and a team looking to reinvent retirement plans for small businesses. Again, the full text:

“We’re a new startup in Austin and are looking for awesome people to help build our iOS apps! We have an amazing team in place, and are looking to extend it.

“If you have at least a few years of impressive iOS experience, we’d love to talk. Relocation assistance available, but onsite desired. Full-time or contract.”

I bet both of these companies would be great places to work.

Minimal UXKit

Brent Simmons reacts to the news that the upcoming Photos app for Mac uses a private UXKit framework. Instead of being the full UIKit-based replacement for AppKit that many developers want, Brent suggests it could be a minimal framework just to make some things easier:

“I could imagine a minimal UXKit that isn’t meant to replace AppKit but that can be used with both AppKit and UIKit. It might have UXColor, which would wrap UIColor and NSColor. Same with UXFont and UXImage. UXTableView could present a simplified superset of UITableView and NSTableView/NSOutlineView.”

Like Brent and many other developers, I started this same kind of compatibility work when porting Tweet Library to the Mac. I ended up abandoning the project because it’s a slippery slope to basically reinventing Chameleon. (Also, back in 2006 I ported parts of Microsoft’s MFC C++ framework to Cocoa and it was a lot of work. I’m not eager to repeat that process.)

I agree with Brent that we don’t necessarily need a completely new AppKit. I’d love to see Apple standardize the foundational classes which are nearly identical already — colors, images, and fonts, as Brent mentioned — as well as UI elements that could be the same without a real cost — views, buttons, labels, table cells, and maybe split views. These UX-prefixed classes wouldn’t do everything their UI and NS versions could do, but they’d allow developers to move more code into cross-platform layers of their app by sticking to the common properties and methods.

As tempting as it would be to throw in iOS-only classes like UINavigationController, I think that would be outside the scope of a minimal UXKit. Candidates should already exist in similar forms on both platforms.

WWDC 2015 is going to be fun if Apple attempts to tackle even a little bit of this. A minimal UXKit would strike a good compromise between the usual iterative improvements to AppKit and a more revolutionary change to the frameworks.

Swift or Android

I was nodding my head while listening to the latest Developing Perspective yesterday. David Smith talked about all the work to update his apps for iOS 8, starting on Apple Watch apps, and so taking the pragmatic approach to keep using Objective-C rather than dive into Swift.

Then I read this by Russell Ivanovic on getting started with Android development:

“It’s really not that hard to get started, but you have to be realistic. If you want to get somewhere, you’re going to have to invest some time. If you want to build a viable business on Android like we have, that might end up being a lot of time. I really feel like 2015 might be the only window you’re going to get though, before Google Play becomes as hard to succeed in as the iOS App Store.”

And I thought, getting up to speed with Swift is probably not that different than learning Android. I’ve programmed Java before, but don’t know the UI frameworks; I know the Cocoa frameworks, but have never programmed anything significant in Swift. Both would require setting aside current priorities and investing some time in a new language or new tools.

If I had to build an app in either as quickly as possible, choosing Swift would certainly be faster. I’m just not sure it would actually be a better use of my time than poking around in Android.

Updated Tweet Marker extension

I updated the Tweet Marker Safari extension to version 1.2 today. This version fixes the extension to accommodate recent design changes on twitter.com. Existing Tweet Marker paid subscribers can grab the new extension here.

Here’s a screenshot of the “Set Marker” link that the extension adds to twitter.com. Then when you launch a compatible iOS or Mac Twitter app, it will scroll the timeline to that position.

If you’d like to support Tweet Marker or use the Safari extension, you can subscribe for $1/month.

Yosemite toolbars

Jason Snell writes about some of the inconsistencies in Mac OS X 10.10 Yosemite, such as how only a few of Apple’s own apps use the new combined title bar / toolbar style:

“It makes me wonder if Apple was initially enthusiastic about this approach, then realized it wasn’t applicable to many situations, and rather than abandoning it just decided to live with the inconsistency. There’s certainly no clear, this-is-the-future signal.”

I don’t hate the new style, but that does seem like the fundamental problem with it: it can’t possibly be used for all apps, especially those with lots of toolbar buttons. I considered it for the next version of Clipstart, but it’s not really a compelling enough change to risk breaking things that already work well.