Sep 2014

Omni

I start my new job as a developer at the Omni Group today. You already know them and their wonderful products, and I’ve expressed my admiration for them here on my blog many times.

But, before I talk about how I’m excited for this new job, I’ll reassure Vesper users: Vesper will continue, and I will continue as its developer.

It’s in great shape, actually — we’ve done the heavy lifting of designing and writing an iOS app, writing client sync code (that’s shared between iOS and Mac apps), and writing and deploying the sync server. And we have good work in the pipeline.

Plenty of work — lots of work — remains for Vesper, but we’re over the biggest hurdles, which is great. We’ll keep at it.

I love that I get to work on both Vesper and on Omni apps. Omni is one of the great Cocoa development companies, and they’ve grown slowly and steadily over many years. They write lovable productivity apps — not just great iOS apps but also great Mac apps. They’re generous to and respectful of their users, employees, and the local development community. Their values and ambitions align perfectly with mine.

And for me it’s a chance to do something I’ve never done: to work on a large team with lots of products and lots of users. To be part of something not just a little bigger than me but a lot bigger than me.

I could have shopped around and talked to other companies (including Apple, I suppose) — but I didn’t. I could have considered contract programming as a way to bring in extra money, but I know myself well enough to know I’d hate it.

Instead, I wanted to work at Omni. And now I am.

Skillet Diner User Interface Lessons

I wrote that thing about the Skillet Diner because I was insulted and angry about it the next day. (I’m not an angry person in general: this feeling is rare for me.)

But there are also some lessons to learn for software developers.

The first obvious one is to treat people with respect from the second they open the door — or from the second they launch your app. The first-time, first-run experience is massively important.

There’s also a second, less-obvious lesson.

The most charitable explanation I have is this: I said I’d be willing to sit at the counter, but I didn’t specify that I’d be willing to sit outside or at the bar. I figured I didn’t actually have to figure out all the different sections and specify each one to the host.

But the host knows the place: he thinks of the restaurant in terms of outside, dining room, counter, and bar. Whereas I, new to the place, think mainly of just sitting down somewhere. I’m no expert in that restaurant, having just arrived, but I was observant enough to notice some counters with empty seats together, so I did say we wouldn’t mind sitting there.

If my theory is correct, then the host expected me to treat him like a computer. He expected me to specify which sections would be acceptable, and he expected me to know all of them and present a list of acceptable choices.

But picture us: we were hungry, brand-new to the place, and we had enough experience to know that every other host in every other restaurant ever has managed to understand our wishes just fine — and has asked questions when needed, which is totally fine.

In other words, this particular UI was designed to be technically true but was entirely lacking in understanding of the (potential) customer.

Skillet Diner (Ballard) Considered Harmful

Sheila and I had been meaning for some time to try the Skillet Diner in Ballard. We went last night around 7 pm.

When we got there there were a couple parties standing by the front desk. The host seated them.

Then we told him that there were two people, and answered no when he asked if we had reservations.

He told us it would be about 20 minutes. I asked if we could just sit at the counter — there’s a long counter with a bar at one end, and there were clearly two seats together in a couple spots — and he said no, but he’d add a note saying we’d be willing to sit at the counter.

So we stood and waited. I counted two two-tops open outside and two in the dining room. As we waited another table paid and left, which made it three two-tops open in the dining room.

As we waited nobody was seated in those tables or at the empty counter spaces.

About five minutes in to this, another couple walks in. They don’t have reservations either. The host explains that there’s a wait. He goes somewhere else for a minute. They flag a waitress, and ask her. She explains that the restaurant is very busy. The host returns, and they ask if the bar is open seating.

The host looks bugged (he’d look bugged the whole time we’d been there) — but then he grabs a couple menus and seats them at the counter in the bar.

Ahead of us.

We walk out.

* * *

As we walk out there are still empty tables-for-two outside and in the dining room, and there was space at the counter for two.

And I had figured by saying that we’d be willing to sit at the counter, that would have been enough to say that we’d even sit at the bar. Or wherever.

The bar appears as just an extension of the counter, where it turns 90 degrees. Someone new to the place, like me, might not even realize that they’re not the same thing — but it seems like I shouldn’t have to specify every single section where I’d be willing to sit. If you’ve got space, just ask me, right?

Now, it’s possible he was about to seat us at a table after seating that couple. But he should have done so first, instead of insulting us by seating another couple ahead of us. Or he could have at least told us and then come back for us.

But he didn’t.

In other words: the service at Skillet Diner in Ballard was so bad that we didn’t even get as far as sitting down. This was a first for me.

We won’t give them a second chance.

* * *

Update 11:50 am: On Twitter, Skillet Diner replies:

there is no excuse for terrible service and that host's actions will be corrected.

I’m still not giving them a second chance. But I’m glad they recognize that this was terrible service.

UISplitViewController Question

Picture an app with three levels of hierarchy. Let’s pretend it’s an RSS reader (it’s not).

Feeds > Timeline > Article

The modern way to make this work for iPad and iPhone is to use a UISplitViewController.

  • Left: navigation controller with Feeds and Timeline.

  • Right: navigation controller with Article.

Launch in portrait on iPhone 6 Plus. The Feeds view controller takes up the full screen. Good.

Tap a feed. The Timeline appears full screen. Good.

Now rotate — the split view now appears. On the left is Feeds; on the right is Timeline. Not good.

And, if I tap a feed, a second Timeline appears in the left, which means two timelines are showing.

I have my project set up almost exactly like the Xcode template for a split view controller app. The difference is really just that the master has Feeds and Timeline view controllers, instead of just a single Feeds view controller.

How do I get the Timeline to move to the master (leftmost) side when going from compact to regular horizontal size class?

My question is much like this unanswered question on Stack Overflow. A difference is that I’m using a selection segue instead of pushing a view controller. (I’m not sure the difference matters. At any rate, we have the same issue.)

Update 2:30 pm: I ran into serious trouble when nothing I tried seemed to do anything. Clean builds didn’t help. It wasn’t till I noticed that breakpoints in delegate methods weren’t getting hit — and I was about to file a Radar — that I realized I probably needed to delete the DerivedData folder. So I did, and things started working. So: consider that a reminder.

I’ve published a gist that shows what I’ve got so far. I’m sure it’s not the final version of the code — splitViewController:​collapseSecondary​ViewController:​ontoPrimary​ViewController: will need more logic — but it solves the problem so far.

Thanks to Tim Ekl and Saniul Ahmed for help via Twitter.

And — bonus — @FriedLemur has the tip of the day (regarding DerivedData):

Option key turns Clean into Clean Build Folder, pretty much rm -rf

That’s so much better than me trying to remember where the DerivedData folder actually is.

Reeder and Unread

I asked on Twitter about which iPhone RSS reader I should use.

I got lots of responses. Reeder was most often mentioned; Unread was second-most.

So I set up both with my syncing system (Feedbin) and gave them each a shot.

They’re good apps. As a user there’s a lot to like, and as a developer there’s a lot to admire. I can’t say that one is better than the other, or that one deserves more popularity than the other.

But, in the end, choosing was for me almost a no-brainer: I went with Unread because Reeder’s low-contrast UI (light gray on even-lighter-gray) was too difficult for me to read. Which is totally subjective, of course, and doesn’t actually say much about either app. But that’s my choice.

How To Steal

Fellow Q Dave Wiskus talks about copying in the latest Better Elevation video.

David’s Critique of Swift

In my My Swift Dilemma, David Owens compares Swift to Objective-C and to a hypothetical Objective-C 3.0. And looks at the costs of optionals and generics.

David is disappointed, and not sure whether or not to be optimistic. I understand that. And while I’ve reserved judgment on a bunch of his points (not least because I have much less experience than he does), they’re well worth understanding — on the grounds that we should understand our tools and their decisions and trade-offs.

Craig on In-App Browsers

Craig Hockenberry, In-App Browsers Considered Harmful:

There is always a tradeoff between usability and security. Doing the OAuth token exchange with an in-app browser makes it easier for a user to login, but they’ll have no idea if their personal information was captured. That is why Twitterrific did its token exchange in Safari, even though it’s a more complex user interaction and a more difficult technical implementation. As a user, I know that there’s no way for my login to be compromised when the transaction involves Safari.

Glen on Swift Performance

Glen Yi writes a brute force solution to Cardano Triplets and notes Swift and Objective-C performance differences.

CocoaConf at Yosemite

This spring CocoaConf is going to Yosemite. The actual place.

I’ll be speaking. So will fellow Q Dave Wiskus. The speakers list is fantastic — one of the very best I’ve ever seen.

And it’s all within sight of Yosemite Falls.

[Sponsor] Underdog.io: Apply to NYC Startups in 60 Seconds

Underdog.io is a curated, two-sided marketplace for technical talent. We make it fast and painless for engineers, designers, product managers, and data scientists to get their résumés directly in front of founders and hiring managers at venture-backed startups in New York City. No more recruiters, and no need to fill out separate job applications.

Benefits

Here’s why our curated marketplace is the best way to get a job at a startup in New York:

  • Free for candidates.
  • Short application process: 60 seconds or less.
  • No need to create an account or remember a password; we can do everything by email.
  • Closed network: no candidate info is public, so your job search is done in private.
  • No hand-holding or middlemen: connect directly with founders and managers.
  • Two-sided curation: only the best candidates AND startups are allowed in the underdog.io network.
  • Startups loves us because we’re cheaper than recruiters : ).

Let underdog.io help you land your next job.

Dave on Software Testing

Dave Winer, The lost art of software testing:

I think all developers go through the initial hatred of the tester, feeling unloved, and depressed because the labor of our love is so awfully buggy, broken and badly designed! Oh. But you eventually come to see that knowledge is power.

I’m not sure that the art is actually lost, though it’s certainly less common than it should be. Nick Arnott has tested most releases of Vesper, and he’s amazing. Best tester I’ve ever worked with. (I like to joke that he hates my guts and is trying to kill me — that’s just what it feels like sometimes when a tester is doing a great job.)

And there are companies such as Omni who have testing departments, and who are, by all accounts, similarly great.

Mark on College Board Testing

Mark Bernstein: What’s Wrong With Facts:

And the more the tests depend on facts, the more vulnerable they are to corruption. Worse, the potential for corruption is so obvious that there doesn’t really need to be any corruption at all before people generally believe that it’s hopelessly corrupt.

Vesper and New iPhones

Now that some people are getting their iPhone 6 and 6+ deliveries, they’re checking out their apps — and, if tweets are anything to go by, Vesper is one of the few apps ready for the larger screen sizes.

Here’s one from Josh Biggs:

God @vesperapp looks amazing on the #iPhone6

It’s a good day. I love days like this.

Bryan on Building Share Extensions

Bryan Irace writes What we learned building the Tumblr iOS share extension.

Sounds like extensions are very much at 1.0. Of course. My congratulations go to the team at Apple that shipped it — it’s huge. Big cool thing.

Josh on “Homeland”

Josh Marshall, “Homeland” And Other Un-American Words and Ideas:

But the ‘homeland defense’ concept was always closely tied to creating a missile shield over the United States. And when I poked around a little further to try to find the earliest uses of the phrase in this context the earliest ones all traced back to Reagan missile defense initiative in the 1980s.

I never heard it used as a word referring to our country until after September 11. And it’s made my stomach hurt ever since.

The word makes me feel as if I’ve fallen through to a parallel world, one where the simplistic things said about America in college freshman dorm rooms by the newly engagé are actually all true.

Nick on Privacy

My co-worker on Glassboard Nick Harris talks about privacy:

Apple’s decision to make it impossible to decrypt data on the device without the users password is the real reason they can say no to warrants. This was another idea we had tossed around. It would have been a paid feature where the board would be encrypted from end to end with only the chairperson having the keys. I had a plan for this and pushed it but didn’t win over the team on getting it built.

Privacy was a huge big deal with us with Glassboard. (And I brought those lessons with me to Vesper.)

With Glassboard we definitely wanted, as Nick pointed out, to do on-device encryption, so that the server would have no way of decrypting text. But we had to do so much so quickly that we couldn’t make the time. (And there were some technical issues — how could we do push notifications if the server can’t push the decrypted text? It’s possible Nick’s plan accounted for that; I don’t recall now.)

It seems as if the realization among regular users that privacy is critical has been glacially slow. But it appears to be picking up speed. (I sure hope that’s true.)

Charlie on Democracy

Charlie Stross, in 2013: Political failure modes and the beige dictatorship:

So the future isn’t a boot stamping on a human face, forever. It’s a person in a beige business outfit advocating beige policies that nobody wants (but nobody can quite articulate a coherent alternative to) with a false mandate obtained by performing rituals of representative democracy that offer as much actual choice as a Stalinist one-party state.

Facts and Thinking

I was reading about Texas and the AP History course — and the thing I was bugged about wasn’t Texas. (The article doesn’t provide enough information to form an opinion.)

Instead, I was bugged by this statement:

The controversy stems from the recent overhaul of the AP test, administered by the New Jersey-based College Board, that was meant to de-emphasize memorization.

Lots of people are nodding their heads. Why memorize things? Of what value is knowing a bunch of dates and the names of dead generals?

The point of school is to teach us how to think, after all.

But that always sounds to me like people arguing that you could learn the rules of English grammar without learning any of the actual words. The facts — and, especially, the stories — of the world are its words. That’s our vocabulary. That’s what we think with and about.

It’s not a matter of memorization to know that World War I came before the Roaring Twenties, and that the Great Depression came next, and that World War II followed. There should be no way a high school graduate could be unsure of the sequence of events, and they should be able to get the decades right, even if they don’t recall, for instance, the exact date of the stock market crash (October 24, 1929).

They ought to know that the Soviet Union was our ally in World War II and our enemy later. And they ought to know that Germany fought a two-front war, and that Germany’s army wasn’t the first to run into trouble in Russia, and why. And they ought to know enough to be able to speculate as to why Germany hadn’t learned from the past.

Knowing the stories isn’t memorization. Once you know the stories you know how one thing causes another, how things are related and reflected, and you can think about the present and the future. And you end up knowing pretty well when things happened — because you know how things fit together — even if you don’t recall every single precise date and the names of every player. (Who assassinated Franz Ferdinand? I had to look it up. Gavrilo Princip.)

To “de-emphasize memorization” sounds like a thing everybody can agree on — except that I suspect it really means “we’ve made it so you don’t have to know what actually happened, which makes it easier for you to do well on the test, which makes us look good.”

* * *

Darmok and Jalad at Tanagra. Temba, his arms wide.

Code-Signing Confusion

Daniel Jalkut documents recent issues regarding code-signing.

While WWDC 2014 was the best Christmas ever, and while the new iPhone models and the Apple Watch look very cool (I’ll be getting a 6+ and a watch), I still can’t help but worry.

What worries me these days is bugs.

Developers know what I’m talking about. To start listing them would seem like Apple-bashing, which isn’t my point.

Bugs make developers reluctant to adopt new things. A developer thinks: I’d love to do x, y, and z — but I think I’ll let everybody else go first.

I’ve said before recently that OS X 10.11 and iOS 9 could be about bug fixes and performance enhancements, and nothing else, and developers would be thrilled.

Spam

I’m not using Gmail or similar — I use the mail server my hosting provider gives me.

That mail server has SpamAssassin, so I have that enabled and set to quarantine everything that scores a 1 or above.

A fair amount of spam gets through to my mail client — Apple Mail — anyway. And so I have junk mail filtering turned on there too.

But Mail’s junk mail filtering doesn’t do a very good job.

To be fair, it’s dealing with messages that SpamAssassin didn’t catch either. The tough ones. But there are a lot of those.

Tonight I got fed up and went back to SpamSieve. It had been years since I used it — but I’m so happy it’s still around. It always did a great job.

* * *

You know what great technology doesn’t have a spam problem at all? RSS.

Not that RSS is a replacement for email or Twitter or anything else. It brings you what you asked for — blog posts and podcasts, mostly — and nothing else gets through.

(RSS feeds may contain advertising, of course, but so do web pages and we don’t call that spam. It’s a different thing.)

What you don’t get with RSS is blog posts from some entirely other blog than what you asked for. If you subscribe to a podcast, you don’t get episodes from some other scammy podcast.

There was a sort-of spam problem many years ago. Back then there were blog search engines (which have all shut down, as far as I know), and those search engines would index spam blogs, and so if you had a feed that was a search you could end up with posts from spam blogs.

But I’m probably the only person who remembers that. And the problem wasn’t with RSS, it was with the search engines and the providers who allowed spam blogs.

How the Sites Drawer Cost Me Some Publicity

This was years ago, and I haven’t thought about it in years.

NetNewsWire had a feature called the Sites Drawer — it was a big list of categories (Mac, Sports, Weblogs, etc.) and a bunch of feeds in each category. It made it easy to find feeds to subscribe to.

(The feature eventually got removed because it was a lot of work to maintain. Removing it was a mistake, however.)

Though Sheila and I have strong political and social views, we considered it a point of pride that the Sites Drawer had feeds that didn’t express our views. We made sure it had feeds of all kinds.

We avoided pornography and hate, but were happy to put in everything else.

Our thinking was that this was not like the stupidity of “teach the controversy“ and “fair and balanced reporting” — this was a service for our users, so they could find the kinds of things they wanted to find. We didn’t endorse these feeds: we just provided a catalog.

And one day during those years a tech writer (I won’t name him) contacted me with some questions, because he wanted to write a chapter about NetNewsWire for his upcoming book.

This was very cool, I remember thinking, because I had enjoyed some of his writing in the past.

That is, until he found the Sites Drawer. We had some feeds related to homosexuality — I don’t remember which, but they were of a liberal tone — and he objected to those feeds.

And he informed me that he couldn’t write about NetNewsWire due to his conscience.

* * *

People always say it’s important to have a conscience. But what if your conscience is wrong?

It’s the same thing with passion — people say it’s important to be passionate about something. But what if your passion is for something horrible?

Vesper, New iPhones, and Editing Fixes

Vesper 2.004 is on the App Store.

The two big changes are support for iPhone 6 and 6+ screens and editing fixes.

Supporting 6 and 6+ wasn’t much work. I had done most of this work before the iPhone announcements, and it was a matter of fixing the couple spots that assumed a 320-point-wide screen. The remaining thing to do was to add launch images for the 6 and 6+. Simple.

The editing fixes were a bigger deal. The first thing is that Apple fixed some bugs in UITextView in iOS 8. Because of those fixes, I was able right away to remove some of our many work-arounds, some of which were a bit heinous. I ended up removing all of our work-arounds and starting from scratch.

And I was pleased to find that we needed very few work-arounds — and small ones, well-contained and easy-to-understand, not like the previous work-arounds — to make editing of long notes much, much better. I’m very pleased, and I thank Apple for attending to this. It’s much appreciated.

At the same time, I also learned from a person-who-can’t-be-named a couple of things that seem to help with UITextViews.

  • Set allowsNonContiguousLayout to NO on the layout manager. It may be NO by default, but set it to NO anyway.

  • Avoid using contentInset — use textContainerInset instead.

So: not a huge release, but a very welcome one. Dealing with editing bugs has been a giant time-suck for me, and I’m so glad to finally get past that, and I think Vesper users will be pleased.

Eric on Web Architecture

Answers About Web App Architecture For Small Teams:

If you are planning on staying a small team (say, less than 3-5 engineers) for a few years, the friction you feel is going to be coming from some place different than communication and coordination between engineers.

When you’re starting out, and when you’re small, the speed at which you can make changes and improvements makes all the difference in the world. Having a bunch of separate services with interfaces and contracts just means that you have to make the same change in more places and have to do busywork to share code.

Timeline Algorithms

I’ve never stopped thinking like an RSS reader developer. A habit of nine years is difficult to shake.

For many years what I wanted to do was develop an algorithm for the reader that would pay attention to what you pay attention to, so that it could bring to the top things likely to be most important to you.

I never got that far, which I regretted for years.

But now I wonder if that would have been the right thing to do. These days I hear complaints that you don’t see everything on Facebook from the people you’ve chosen to follow. And Twitter seems to be moving toward an algorithm-based timeline too, which has people (including me) upset.

At the same time, people do like things like muting features and lists. So it’s not that they’re against filters and organization — it’s that they don’t want these imposed from the outside.

These days, were I writing an RSS reader (I’m not), I think I’d skip developing an algorithm based on the user’s attention — instead, I’d focus on making it really easy to filter out the things you don’t care about, and to highlight the things you’re more likely to want to see.

And not try to come up with some algorithm which would have the effect of bugging people and making them feel like they were missing things. Since they would be.

Online Life

Dave Winer, The frenzy of online:

This isn’t communication, or sharing. It’s growing more and more frenetic every day, it seems. And more pointless.

I’ve often had the thought that our social networks are the same thing every day, with just slightly different details. When I skip them for a few days, I find that I have absolutely no feeling of missing anything.

Here are some things that don’t give me that same-thing-every-day feeling: making things, reading books, and talking to people in real life.

(Currently reading The Quiet American.)

On Criticism and Enjoyment

David Gerrold (one of my favorite science fiction writers):

Comic Book Guy isn’t having any fun. He’s bored — and he’s boring. Bart and Milhouse are having fun. They’re excited and interested. They get it — it’s about being a kid again. The whole point of a comic or a book or a movie or a TV show is to be a kid and have fun. It’s about trusting the author/filmmaker to take you on an exciting journey — not a dark ride, but a journey of discovery. You can’t do that if you’re watching the lighting, the editing, the camera angle, the dialog, the acting — you gotta let go and be a kid again.

Full-Text Search

New Yankee Codeshop shows how to do full-text search on iOS and OS X using SQLite and FMDB.

The Indie Developer’s Wilderness

Gus Mueller:

However much time I’ve been doing this for, and no matter how much practice I put into it, there’s one thing that always sneaks up and pulls the rug right from under me. It’s usually between major releases, but not always. It’s a period of time where I’m pretty lost, and I don’t know what to do. I have feature lists, I have open bugs to fix, and I have an outline of where the app is going. But I feel mentally incapacitated, like I’m getting nothing done.

Rock Stars

Fellow Q Dave Wiskus talks about putting on a good show in Rock Stars.

Apps are the showbiz of today.

Manton on Microblogs

For a new project, Manton Reece is defining a microblog post.

Manton and I care about many of the same things. (We’ve known each other since the ’90s when we were both in the Frontier community.) Among the things we both care about are the virtues of decentralization and of owning your own writing.

I don’t have much in the way of details of what he’s working on — but it sounds like a project I’ve had in the back of my mind for quite a while. Since I’m more interested in the thing existing than actually doing it myself, I’m very happy to see Manton working on it.

* * *

Is the web we lost gone forever? Was it a brief golden age before the rise of Facebook and Twitter and The Algorithms of Engagement?

Or is the current period a brief blip in time, where we turned the wrong corner and now we’re getting back on the right road?

I used to think that the very structure of the web meant that it was always inevitable that we’d get back to the great web. I’m no longer that kind of progressive — I realize now that loss is real, and usually permanent, and that good things have to be fought for, not by a handful of heroes but by a bunch of regular people like me and Manton.

[Sponsor] Hot-patch and Control production code with Rollout.io SDK (iOS developers)

In today’s mobile landscape, a lot of resources are directed towards building better quality apps — from beta testing platforms to distribution systems and even app performance monitoring solutions. But none of these solutions help developers while their app is in production.

With Rollout.io, developers can quickly react to their users by remote-controlling their app’s settings and parameters, as well as fix and contain errors and issues in real time — without waiting for a full release cycle.

Capabilities:

  • Contain & hot-patch production bugs
  • Create analytics events on the fly
  • Messaging
  • SDK toggling
  • Advanced logging and debugging
  • UI changes (buttons, images, etc)

See how it works:
https://www.youtube.com/watch?v=4nT-1Nw0ihw

Radek on Swift Methods

Radosław Pietruszewski makes the case for brevity:

Some people say that “clarity trumps brevity.” And they’re absolutely right. Except for the fact that brevity can be a factor in clarity. Verboseness doesn’t come for free…

The trick in finding the sweet spot is to maximize the things that explain what the code does and remove as much noise as possible — the things that don’t really add information.

Alex on Developing for the Apple Watch

Alex Vollmer, A New Future?:

This is going to sound funny, but I think the tactile pulsing feature of the Apple Watch is one of its most intriguing. It got me thinking about how, paired with the right software, it could be a fantastic way to teach a wearer certain timing-related skills…

As a musician, that pulsing action might make for a great silent metronome. Instead of playing along with a monotonous click, you could simply time your playing with the watch's pulse. Music teachers always talk about “feeling the groove,” this would make it a literal reality.

Tim on Size Classes

Tim Schmitz, Reading the Size Class Tea Leaves:

Both the iPad Air and the iPad mini have a “regular” size class in both dimensions, which implies that Apple is at least leaving room for something larger than the iPad. The likeliest explanation is that they’re keeping their options open for shipping larger devices in the future. Maybe a larger “iPad Pro?” Or perhaps an Apple TV SDK, in which the TV has a “large” size class.

iOS Design Kit

TETHR is free and looks pretty good from the screenshots. (Scroll down on the page.)

(Via John Nack.)

Pablo on the Apple Event

Pablo Bendersky, Apple Watch Event Thoughts:

While iOS 7 and 8 have a visual style that do not require pixel perfect mockups, iOS 7 was touted as designed for retina displays, and the recommendation was to use retina assets (like 1px lines) which might not look good on the 6 Plus.

I would think that every programmer thinks in powers of two — more so than in powers of ten. (Is 100 a round number? Hell no. But 64 is.)

The @3x thing makes me feel like one of those computers in the original Star Trek that Kirk destroys by feeding it bad input. Does. Not. Compute. Can’t. Divide. Three. By. Two. Help. Me.

Pop. Bang. Fizz. Lights out.

(Okay. I’ll adapt.)

Gift Tickets to NSScotland

NSScotland (they’re sponsoring this blog this week) has a nice idea: gift tickets. Buy a ticket for someone who can’t afford it — a student, for example. Other conferences should do this too.

This Acquisition Makes Total Sense

Jared Sinclair, Unread is Now a Supertop App:

I’m proud of the work I put into Unread, and can’t wait to see what Supertop does with the foundation I laid down. Unread has the cleanest code I’ve ever written for a personal project, so I’m hopeful that it won’t be a burden for Oisin and Padraig to wander through it.

I admire both Castro and Unread. This looks like a great fit.

WatchKit Speculation

Awkward Hare:

Will you have to write WatchKit apps in Swift? Seems that would not be necessary on a technical level, but it feels like a possible Apple-like move to encourage adoption.

What I Can’t Get Over

It’s crazy to me that with interest in Apple at such a high, a publication that covers Apple couldn’t make enough money to retain its staff.

It seems to me that Macworld had a giant advantage over almost everything else.

Is it just that it’s hard to make enough money to run a quality publication? Even with the advantage of being Apple-centered?

Swift Policy

Now that Swift is at 1.0, I need to set a policy for when to use Swift code and when not to.

Swift is a peer of Objective-C and you can ship apps written (all or in part) in Swift. And I expect that the share of Swift code will grow fairly quickly.

I also expect that, once I’m good at Swift, I’ll be more productive than I am with Objective-C.

That’s a big premise to accept, and it’s not based on experience yet — I’ve written only a few hundred lines of Swift code, and slowly — but it looks like it’s true. There are classes of bugs that won’t compile in Swift. It has very nice things like type inference and optional chaining that cut down on the amount of code I need to write and maintain.

But this means I’ll be less productive as I get up to speed. There’s never a good time to be less productive, but developers are used to making this particular trade-off: adopting a new thing now has benefits later.

So my policy is this: new code will be written in Swift.

There are exceptions, though. The things Swift can’t do will have to be written in Objective-C. (Luckily these are fairly rare.)

And there has to be a time limit. I forget who proposed the 45-minute rule for CSS, where you give up and just use a damn table for your layout. I don’t want to be too quick to punt when using Swift, because it means I won’t be learning as much as I could be (and I need to become expert: that’s the point), but I also can’t let my productivity go too far from what’s normal.

I’ll give myself two hours of banging-head-on-disk, then punt. As a rough guideline. (I’m not actually going to use a stopwatch.) This number may change, but it’s important to have some limit as I’m doing this.

Also: I got the latest version of the Swift book and I’m re-reading it. Just because it feels right. You probably don’t need to, but I feel like I do.

I’ll also keep the known issues from the Swift release notes handy, for when I do get into a weird situation. And I’ve added the Swifter site to my favorites bar, for easy lookups.

Apple Watch and Username and Password

Say you have an app connected to a web service — like Twitter or Facebook — and you create a native Apple Watch app.

How is the watch wearer able to enter their credentials for the service?

Update 11:40 am: The answer, as many people have pointed out, is that this is one of the reasons the Watch requires an iPhone. I’m curious about the details. I’ll be patient.

Macworld Love

Macworld magazine has meant so incredibly much to me over so many years. And it’s not really closing — but they just let almost everybody go and they’re dropping the print magazine. So it’s finished as the Macworld that I loved.

More important to me, though, are the people I’ve gotten to know a little bit. Great individuals, great team. I feel bad for them for this very unhappy surprise — but I also have no doubt they’ll go on to do awesome things. And better things.

If we could deliver a standing ovation via internet as these folks leave this particular stage, we would. It’s so deserved.

PS In case you missed it, here’s Jason Snell’s personal announcement.

Xcode 6.1 and Swift

Airspeed Velocity documents changes to the Swift Standard Library in Xcode 6.1. How we live now is we don’t sleep anymore.

Tim on NFC

Tim Bray, A Word on NFC:

There is a large and in­ter­est­ing class of prob­lems where push­ing bits across nar­row gaps is use­ful. For a sub­set, re­quir­ing ac­tu­al phys­i­cal in­ti­ma­cy is a must-have; for the rest, it’s not a prob­lem. So here’s hop­ing Ap­ple pub­lish­es a sen­si­ble API in iOS.nex­t.

First Thoughts After the Apple Event

Off the top of my head, before thinking things through…

I want the watch. I want to write software for the watch. I want the watch. Want.

I think I’ll go for the super-big iPhone. I’m a sucker for screen real estate. Might as well go all the way. (But I might change my mind once I hold one in real life.)

At this point, Apple could, and should, slow down a little. Yearly OS X and iOS releases mean a lot of work for developers. Consider not just the usual updates we need to do — now we have watches and extensions and handoff and a new language. Wonderful things, but also a ton of extra work.

My favorite OS X release ever was 10.6 (Snow Leopard) — that was the year Apple didn’t add any features (except for some very cool developer features such as blocks). Apple fixed a ton of bugs and made everything faster. My hope is that Mac OS X 10.11 and iOS 9 are Snow-Leopard-like releases. If they switched to a longer interval between releases, I would not complain.

I like U2. I thought they were old and tired by the time I was in college (1986). (Their last good album was War, said me.) But now I realize that the young me was a jerk. U2 was and is a great band.

Every time anyone said “intimate” during the event I cringed a little.

I think health and fitness are massively important (doi) and I look forward to these features. But my liberal heart breaks every time I think about how much easier is it for the affluent to be healthy and fit than for people who can’t afford fancy watches. But that’s not a reason not do it. And I’ll be happy to take advantage of those features.

I actually missed huge chunks of the video. I’ll watch it later tonight once it’s available.

I’m massively worried that Xcode 6 and iOS 8 are not really ready for release. But then I have this same worry every time. I’m glad it’s not my job to make that call. Are the bugs fixed?

I hope bars get in on Apple pay.

I want the watch. Waaaaant.

[Sponsor] NSScotland

NSScotland, the Scottish Mac and iOS development conference, runs October 25-26 this year in beautiful Edinburgh.

Sessions include Rob Rix on polymorphism in Swift, Drew McCormack on making magic, honorary Scotsman Graham Lee on testing at Facebook, Sally Shepard on developing for the AppleTV, Johnnie Walker on iOS image processing, Eric Knapp on CoreMIDI, and Glasgow’s own James Thomson on indie survival strategies.

We’re also delighted to be running a Swift kickstart tutorial from Daniel Steinberg on Monday October 27 (the day after the conference).

The conference is limited to 100 and the tutorial to 50 — tickets for both are still available.

And if you’re coming to Scotland, why not take an extended vacation? There’s a reason they put Hogwarts here, after all — it’s lovely country. Worth the trip. :)

Mustapha on Blogs

Mustapha Hamoui, Blogs Are Cool Again:

If you choose to follow a blog, no company like facebook can decide whether or not you can read its posts. So don’t hesitate to blog away.

My favorite part, self-centeredly, is that Mustapha calls me a “known iOS developer.” Like “known Communist.” Love it. :)

Dave on JavaScript Apps

Dave Winer, I write apps in JavaScript that run in the browser:

I go to the <script> section and start writing routines. Just as if I were going to run it from my desktop, which in a very real sense I am. It’s just that today my desktop exists mostly in my mind. Which is where it always has been.

I don’t think Dave is using any of the frameworks like Backbone, Ember, or Angular. (jQuery maybe? I don’t know.) He does use Bootstrap, I believe.

I like this approach. Part of me thinks those frameworks are overkill (even jQuery), and that writing regular-old JavaScript to do what you want is not that onerous a thing, and will make for leaner, better code. (Along the way you’d develop your own library, of course.)

But that’s just me — I like to minimize dependencies. And I don’t like the idea of a browser downloading 100K (or more) of code when it could be 10K. And I don’t like the idea of updating my code just because a framework made a breaking change but I need to upgrade because there’s also a security fix. (Would this happen? I don’t know. Could just be paranoia on my part.)

On the other hand, there really is something to be said for these frameworks. If they take care of the boring parts, and then just get out of the way and let me concentrate on the unique parts of my app, then that’s a win.

* * *

Web apps make such an interesting contrast with iOS and Mac apps. With native apps, you use Xcode and the Cocoa frameworks, and that’s that. You might choose between Objective-C and Swift, and you might choose to use some open source libraries such as AFNetworking.

But those choices are few and relatively small compared to all the choices with writing web apps.

You could say that writing iOS and Mac apps is like living in a town where one company provides most of the jobs. (Sure, you could work at the diner, but all your customers work at this one company.)

And writing web apps is like living in New York City, where choice and contrast is everywhere, and sometimes A and B (and C and D) are all equally cool but different.

The web is the cosmopolitan environment.

Santiago on Web Apps

Santiago Valdarrama writes:

All the logic in my API would be packaged as a standalone library and the REST interface will simply expose this logic. I can import and use the library directly in my code, and my applications will talk to the methods in the library without having to go through HTTP. These methods contain 100% of the logic so I won’t be duplicating code neither incurring in unnecessary latency.

If I understand correctly, then this means that my several different Node/Sinatra/whatever apps would each have their own copy of this library. I hadn’t thought about that approach, and I’m a little worried about how I’d manage making sure it’s up-to-date in each place. But that kind of thing (via Ruby gems, npm, Git, Mercurial, etc.) is supposed to be easy these days.

The approach I imagined is that an API server would play that role, and the various apps would talk to the API server via http to do the common things. (And the in-browser app would talk to that API server too.)

I hadn’t thought of Santiago’s approach. Definitely worth considering.

Client-Side Apps

A number of people have suggested to me that pushing the app (as much as possible) to the browser is a good idea. Thick-client all the things!

But Alex Dieulot tweeted a couple links against that are worth reading:

Blogs Are Cool

I often get responses via email to my blog posts. Almost all of those responses would make great blog posts on their own — and, in fact, I wish they were on the web so I could link to them, so you could read them too.

Now, plenty of people do post responses to their blog, and I see those in my RSS feeds, or they mention me on Twitter and include a link. That’s awesome.

But, to the people who send email, to me or to any blogger: please consider publishing what you write instead of emailing it. Not because email sucks, but because more people than just me should be able to read what you wrote. You have something to add to the discussion.

If it makes it easier to compose in your email app, then that’s fine. That’s a good approach to writing blog posts — imagine you’re writing an email to a friend, but then publish it.

And then let me know that you’ve published a response. Send me email or get me the link via Twitter. Easy.

* * *

Slight tangent: I’ll plug MarsEdit.

Ten years ago I wrote about MarsEdit’s design — and the gist of it was that it makes it feel more like you’re writing an email to a friend than Writing an Important Blog Post.

My goal, in other words, wasn’t just to write a good app that people like, but to write an app that makes it more likely people will write for the web. It was designed to take the pressure off.

If you’re not using MarsEdit, and you’re having trouble getting your thoughts on your blog, give the free demo a try. You might find that it helps, that it makes it easier. (And, if not, no sweat.)

Simon on Web App Architecture

Simon Ljungberg writes:

We are currently dealing with some of this on Bloglovin because our web app is starting to get split up between a few different services. We’re tackling this by building a collection of components. These components represent different UI elements (kind of like Boostrap I guess). Each service includes the library of components as a dependency, and as such we update the code in one place and the dependency in the other places.

My previous post could be summed up as just this question: “Should I use one Rails app or a collection of Node/Sinatra/whatever apps?”

Almost everybody says to use a collection of apps rather than a monolithic app. Which is cool, because that’s what I’d rather do.

Web App Architecture Question

Vesper’s web app is small, just a couple thousand lines of code, and it’s split into two components: an API server and a website.

The API server handles syncing. It’s almost all JSON — it doesn’t serve any web pages.

The website is for verifying your email address and doing a password reset. It doesn’t talk to the database directly — it talks to the API server.

Both are Node.js sites.

I like this architecture mainly because my temperament pushes me toward modularity.

I like small, focused pieces that can be updated independently, as long as the API contract is upheld. I like that I can run as many instances I need of each component.

* * *

But what if I were doing something larger?

Picture a hypothetical web app with the following components:

  • Account management website (create account, login, email verification, password reset, profiles)

  • API

  • Background tasks — downloading tweets (let’s say), doing something interesting with the data

  • Push notifications

  • Main website (the UI for the app)

  • Misc. website (marketing, privacy policy, about, help, support, etc.)

(Also assume a database and some kind of static file storage.)

How would you organize this?

My first thought is that these are all separate apps. But that’s just my reflex — it’s not necessarily the right way to do it.

* * *

If they’re separate apps, then there are issues of code sharing. A simple example: each of the three websites should probably have the same navigation bar at the top. I can’t change it once — I have to change it three times.

Maybe that’s not the worst thing, and I’d put up with that in order to get the other benefits of modularity. But it gets worse: each website also needs to be able parse an authentication token cookie and decide if it’s valid or not and who it refers to.

Things like that could be solved via the API server — pass the token to the server and get a response back (valid, invalid, expired). But that adds latency to the system (and I’m a speed freak), and there is still some duplicated code (the code that calls the API server).

Okay. So the websites really need to be just one website. That gives us this:

  • Website

  • API

  • Background tasks

  • Push notifications

Question: can the website talk to the database? If not, then it has to go through the API server, which adds latency. If it can, then it's duplicating code that the API server knows about.

The same question could be asked about the background tasks and push notifications. Do they go through the API or, potentially, duplicate code from the API?

To get rid of latency imposed by API calls, and get maximum code-sharing and no code duplication, I end up with this:

  • One big app with everything in it

Which goes against my grain.

Might as well use Rails or Django at that point, right?

* * *

Does JavaScript in the browser change things?

Consider the navigation bar that has to be the same across websites. If this is built in the browser, built by JavaScript that exists in one downloadable, static file somewhere, then I’ve eliminated code duplication.

(Let’s assume I don’t care about browsers with JavaScript turned off and I don’t care about browsers with poor standards support.)

At that point the three different websites could just be JavaScript apps which call the API server. The server components of those websites wouldn’t need to talk to the API server or to the database at all.

So, for fetching and updating data, instead of browser > website server > API server > database, we’d have browser > API server > database. Which sounds much better.

Are we at the point where this is really feasible and secure?

Also, does this just mean trading one big framework (Rails, Django) for another one (Backbone, Angular, Ember), with the added disadvantage that the user has to download the framework? (Is that really a good idea given that many people might be on phones with spotty connections? Maybe those frameworks aren’t as heavy as I imagine.)

* * *

Perhaps the trade-offs in the choice of monolithic vs. modular just balance out and don’t point to a clear better practice. In which case the answer would be: go with whichever I prefer, and deal with the challenges of that approach as they come up.

But I can’t help but think that maybe they don’t balance out, and that using something like Rails or Django is actually the best call for a web app like this, and that going with my personal preference for modularity would mean a lot of standing on my head while cleaning the house.

(Well. This is all hypothetical anyway.)

What would you do?

Dave on Markdown

Dave Winer, Let Markdown be Markdown:

The Rolling Stones openly copied American blues musicians.

But they came up with their own name, which left them free to develop their own style, following whatever direction their art pulled them in.

Rob on Map (and Filter)

Rob Napier:

The mapping could be performed in parallel or in reverse order. It could be performed once and cached, or recomputed every time it’s accessed. In principle, we don’t care. As long as the mapping only depends on its inputs, and as long as there are no side effects, we will always get the same result. This is the heart of good functional programming.

(Via Michael Tsai.)

Craig on the Terminal

There’s no need to write any more about the Terminal. Just link to Craig’s piece. It’s all there.

(Me, I’m still using tcsh, which was the default in early versions of OS X.)

Email

The folks at Front tell us that email will last forever.

I was thinking about how people complain that they can’t send links in Twitter direct messages. And I was thinking about a system where you could send links privately.

In the ideal situation that system would be owned by nobody and would be based on open standards. The message wouldn’t pass through any one specific service.

That system is email, of course. It’s a miracle.

Yet we hate it so much.

There’s no technical reason why that specific use case — message with link, no subject line, quick to find contact, quick to write and send — couldn’t be handled by email. The issue is user interface.

It continues to surprise me that email app vendors don’t think about the way people communicate now. They may think about the way people communicate by email but they don’t think about how people communicate in general.

Maybe it’s an issue of economics. If you write an email app your best case scenario is, apparently, to get acqui-hired and then discontinue the app.

* * *

Another huge problem with email is spam. I get a few hundred a day.

Think back to 2004. Bill Gates said that spam would be a thing of the past in two years. That would have been 2006 — eight years ago. It’s worse now than ever.

I get much less Twitter spam than I get email spam. But the downfall of any system where anybody can send a message to anybody is that anybody will send a message to anybody.

It makes me cranky.

NickH and NetNewsWire

Nick Harris, my co-worker at NewsGator and Sepia Labs, writes NetNewsWire – Time to Breakup:

I need read state sync and a multiple device experience. I want to be able to click links to blog posts I see on Twitter and have them marked read in my RSS app. Really I want to spend less time dealing with read state — something I was spoiled with at NewsGator.

It’s not easy. It’s an incredibly difficult problem to solve. But it is solvable. The problem is if the solution is profitable.

BASIC Was Cool

James Hague, Lessons from 8-Bit BASIC:

There’s a small detail that I skipped over: entering a multi-line program on a computer in a department store. Without starting an external editor. Without creating a file to be later loaded into the BASIC interpreter (which wasn’t possible without a floppy drive).

Here's the secret. Take any line of statements that would normally get executed after pressing return:

PLOT 0,0:DRAWTO 39,0

and prefix it with a number:

10 PLOT 0,0:DRAWTO 39,0

The same commands, the same editing keys, and yet it’s entirely different. It adds the line to the current program as line number 10. Or if line 10 already exists, it replaces it.

I feel a little bad for all the people who didn’t learn to program this way. It was so much fun.

Swift, Strings, and Memory Use Question

Do I understand this correctly? NSString (usually) stores strings in memory as UTF-16, while Swift uses UTF-8. Correct?

If so, then I think this means that for text-heavy apps — such as Vesper, such as RSS readers and Twitter clients and similar — there could be a nice reduction in memory use due to this change. (If they use Swift strings.)

True?

Update a few minutes later: Alastair Houghton tweets:

No. NSString stores strings as 8-bit ASCII where possible. It only uses UTF-16 if it has to

Update 8:40 pm: Well, maybe. Sometimes. Consider the many European languages that have accented characters — those aren’t ASCII characters, which means NSString would use UTF-16. But if Swift uses UTF-8 in those cases, then it should save memory, since not all (or even most) of the characters are accented.

Or, as Alastair Houghton tweeted when I asked him about this case:

Yes, e.g. in European languages (French, German, Spanish etc) where many chars are ASCII but some are accented.

(Also remember that words with accented characters — résumé, éclair — appear in written American English too.)

The Atlantic on Twitter

In April of this year, The Atlantic published A Eulogy for Twitter:

People are still using Twitter, but they’re not hanging out there.

(Via The New Atlantis.)

[Sponsor] thoughtbot

We’re looking for an iOS developer to join our team in New York City. You’ll work with top-notch iOS developers from around the world, building great products that customers love to use.

We focus on high quality work and the importance of learning, so that we can hone our skills and expand our knowledge. We’re even already doing some projects in Swift.

We produce the iOS development podcast Build Phase, and our blog Giant Robots Smashing into other Giant Robots.

Learn more on our website and contact us at jobs@thoughtbot.com.

Archive