Print Numbers to the Console Painlessly with this One Weird Trick

I’ve given up trying to remember NSLog number formatters. I was cool with it until Macs got 64-bit processors — and then I just lost it when I stopped being able to use %d most of the time.

And now I’ve given up even looking up the number formatters. With the new literals syntax it’s just so easy — as in this line of code I just wrote:

NSLog(@"t: %@", @([d2 timeIntervalSinceDate:d]));

What did I want? %f? I don’t need to know or care.

Web Performance

I continue to be freaked-out about how bad is web performance. HTTP Archive says that the average transfer is 1907K, which is down just a little from last month, but still outrageous.

For comparison, my iPhone app Vesper is 5.0MB, which is less than three web pages. And you don’t have to re-download it every time you use it.

One of the strengths of the browser-based web is — or ought to be — that it’s lightweight. Going to any given site should not require an amount of data transfer that’s a significant fraction of downloading a native app.

The situation right now is crazy.

Scott Jehl writes in A List Apart, Planning for Performance:

We’re not doing a good job.

Le Guin

Mom sent me a link to the video of Ursula K. Le Guin’s short talk at the National Book Awards. It’s great.

Tumult Wow

Sure, the Tumult folks are pals. But check out the video for Tumult Hype Professional.

Allen on WebKit

Allen Pike did a great talk at Xcoders a few months ago on embedding WebKit in iOS apps — and it’s up on Vimeo.

WatchKit

There goes today’s productivity.

It is apparently not Swift-only. There had been speculation.

Native and Web Apps

John’s article Native Apps Are Part of the Web had me thinking about my own history of apps and their relationship to the web.

I fell in love with the web in the mid-’90s, and in the ’90s I worked on browser-based apps — Manila (a blogging system and CMS) most prominently.

In the 2000s I continued my love affair with the web, but I started writing native apps: NetNewsWire, an RSS reader which downloaded feeds from the web and displayed content in an HTML view; and MarsEdit, a native client for posting to browser-based blogs.

Later I worked on TapLynx, a framework for web publishers to create iOS apps, and then Glassboard, an iOS and Android group messaging app with a web backend (and even an HTML app).

These days I work on Vesper, which syncs to a web backend, and OmniFocus, which syncs via WebDAV.

Each of these is a web app in the http sense. NetNewsWire and MarsEdit even had HTML views, and Glassboard had an HTML-based version. For Vesper I even wrote a server, which was the first time in a decade I’d done server-side work.

Which is just to say that the distinction between native and web apps isn’t a true distinction. Since native apps are also web apps, and since native apps may also use HTML, the true distinction is between native apps and browser-based apps.

And I sometimes think about writing browser-based apps. I’m not anti. They’re cool, and I might write one again some day.

[Sponsor] Tinderbox

Tinderbox, the powerful note-taking app, gives you the technical tools you need — inheritance, composites, and templates — to manage software challenges such as system architecture and big refactoring efforts.

From brainstorming and product design through coding, delegating, testing, and marketing, Tinderbox helps you capture ideas, uncover emergent structure, and adjust as plans and requirements shift.

For example, here’s a Map view from early planning for Tinderbox 6, where we planned the move of hundreds of existing classes into a new framework and a fresh UI.

Tinderbox screen shot

Every note is backed by styled text and an extensible list of attributes and values. Tinderbox offers flexible rules to enforce constraints, agents to gather notes of special interest, timelines, tree charts, and a lively user community.

Tinderbox is also great for plotting novels, planning dissertations, and tracking commitments.

This week only, Tinderbox offers Inessentialists a $75 discount on the brand-new Tinderbox 6.1.1.

The Case Against } else {

Sometimes I see code like this:

if {
    …stuff…
} else {
    …other stuff…
}

That’s pretty much a-okay with me.

Pretty much. Until I want to comment-out the else block. There’s no way to do a line-wise selection and hit cmd-/ (when it works) and comment out just the else block.

Update 3:15 pm: Dan McTough reminds me that there is a way to do this. My objection is that it’s more difficult and requires more paying-attention. It’s easier to go to the start of a block and select to the end — it requires almost no thought.

Also: many people like } else { on the ground that it makes it easier to notice the else. Okay.

How to Set the Instruments Inspection Range

I have, by accident, successfully set an inspection range in Instruments — and later I can’t reproduce it. This time I’ve figured it out for good, and so I’m writing it down.

Here’s how:

Record for a while. Click the pause button.

Find the clear downward-pointing triangle above the graph. Click and drag it to the start of the range you want. Type cmd-< to set the beginning.

Click and drag that same triangle to move it to the end of the range you want. Type cmd-> to set the end of the range.

Done.

When Split Views and Windows Fight for Your Mouse

It takes precision mousing to reproduce this, but I bet you can do it.

Launch Contacts.

Note that you can click-and-drag in a bunch of places to move the window. Click in the sidebar or in a profile where there’s no content — you can move the window. Cool.

Now for the precision mousing part: move your mouse to the second split view divider (between the alphabetized list and the profile pane). Move to right below the top of the window. Hover exactly over the divider (note the resize cursor). Then click and drag.

Even though the cursor shows a splitview-resizing cursor, the window moves.

And sometimes the split view divider changes position as the window moves. It’s weird.

I think I know what’s going on:

  • movableByWindow​Background is YES for the window.

  • The NSSplitView returns YES for mouseDown​CanMoveWindow.

It seems to me that if the splitview-resizing cursor is shown, then any click-and-drag should resize the split view and not move the window, even when the above two things are true.

I’ll file a Radar.

Update 11:55 am: Bug filed. rdar://18929475

[Sponsor] Mandrill, the Fastest Way to Deliver Email

Integrate, deliver, track, and analyze with Mandrill, an email infrastructure service from MailChimp.

Mandrill is a scalable, reliable, and secure email infrastructure service built by the folks at MailChimp that’s trusted by more than 300,000 customers. It’s easy to set up and integrate with existing apps. And it’s really fast, too. With servers all over the world, Mandrill can deliver your email in milliseconds. Detailed delivery reports, advanced analytics, and a friendly interface mean your entire team—from developers to marketers—can easily monitor and evaluate email performance.

Get started with Mandrill today.

This post is sponsored via Syndicate Ads.

First Go at Using IB_DESIGNABLE and IBInspectable

In AppKit, views don’t have a backgroundColor property. This isn’t a great big pain or anything — just a small thing. But nice to solve.

There are many times when I have a view that contains other views and the container view should have a background color. (And be opaque. I’m a big fan of opaque views.)

And sometimes I just need a divider — and a divider is, after all, just a thin view with a background color.

And I’d really love it if I could set the colors in Interface Builder, and I’d love it if IB actually drew the correct background colors. That would go a surprisingly long way toward making IB a WYSIWYG editor.

So here’s what I did:

Created BackgroundColorView.

In the .h file:

IB_DESIGNABLE
@interface BackgroundColorView : NSView

@property (nonatomic) IBInspectable NSColor *backgroundColor;

@end

In the .m file:

- (BOOL)isOpaque {

  return YES;
}

- (void)drawRect:(NSRect)r {

  [self.backgroundColor setFill];
  NSRectFill(r);
}

And then in IB I just use a BackgroundColorView (I set the Custom Class to BackgroundColorView), and it does what I want. I can set the color in IB, and IB draws the correct background color.

I like it. It means that I’m not the bottleneck — designers can change the background color themselves. Cool.

Vote!

If you don’t vote, then everything bad our government does is your fault, and you don’t get to complain.

There’s no such thing as remaining neutral or sitting one out. There’s no not-playing-the-game. Not-voting is still playing the game. In a democracy you’re involved no matter what you do.

Worst case is when a choice is between the lesser of two evils. It’s easy to get cynical in those cases — but the greater of two evils relies on your cynicism to win. Don’t let it.

Yosemite Sharing Menu

Extensions are cool.

I hadn’t looked at how to add a sharing menu to a Mac app — as in Safari in 10.10, or as in UIActivityViewController on iOS — until just now, and I find that I can’t find anything.

Is this truly not there? If so, then I’m surprised. I just took it as a given that it would be there, since the value of sharing extensions goes way down when only Apple apps can include a sharing menu.

Obviously I could build a sharing menu (as I’ve done before) — but I want a sharing menu that uses sharing extensions. Of course. Am I just missing this?

Update 4:20 pm: Chris Parrish says: NSSharingServicePicker. So, yes, it is there. Whew!

CocoaConf Seattle

I had a great time at CocoaConf Seattle this past weekend. I’m already looking forward to the event in Yosemite this spring.

I got to play a few songs as a Conditional Breakpoint! It was a total thrill for me. Check out the Breakpoints album on iTunes if you haven’t already.

A Day of Programming

Sometimes days are like this:

Our testers — who are great — report a regression I caused but that I didn’t notice. Why is sub-pixel anti-aliasing not working in this view? The text looks bad. (Note to self: test with a non-retina display before comitting.)

I investigate, and find, to nobody’s surprise, that the culprit is a layer-backed ancestor scroll view. I turn off layer-backing — I just uncheck that particular box.

Then run the app. It’s good to see sub-pixel anti-aliasing back. But look at how things have gone wonky.

Wonky? Let’s be precise: the layout inside outline view cells is incorrect. If I check the box (turn layer-backing back on), then layout is fixed. Uncheck it, and layout is broken.

(This all sounds straightforward, but I’m glossing over a bunch of things I tried and researched. The above is a couple hours of work.)

The wonky view uses auto layout, but it’s not entirely constraint-driven: there’s a manual -layout method. When an ancestor is layer-backed, then that method is called at the appropriate times. When it’s not, then that method isn’t called often enough, or not at all the right times.

Or… but it also looks like something else might be moving those views, giving them a zero origin when it shouldn’t be. Exactly as if it’s doing constraint-based layout and not calling the -layout method. Sometimes.

I click around a while, add NSLogs and breakpoints and all the usual things. I can’t figure out what’s happening. I bring in resizeSubviewsWithOldSize: (the old friend). I accidentally introduce an infinite loop at one point.

To reassure myself, I check that checkbox again (turning on layer-backing) — and layout works again as expected.

Time to get pragmatic.

If it seems as if those views are sometimes getting laid-out by their constraints, and -layout isn’t getting called, then maybe that’s really what’s happening. So one possible solution is to give all the views their necessary constraints, so that -layout isn’t needed at all.

I tried it. Success! (I think. At least so far.)

And that was a day of work. In the end I don’t know why there was a problem, but I have a solution. I should probably file a Radar, but it seems like exactly the kind of thing that will be hard to duplicate in a simple case (though I could be wrong).

There’s nothing wrong with days like that. In the end the thing is solvable. What worries me is when I have too many days like that strung together, when I have too many Radars to file.

Archive