Better Words

James Somers (via Gabe Weatherhead, via Michael Tsai) writes about using a better dictionary — and how to get it installed on your Mac, in Dictionary.app. Had double-rainbow guy been raised on this older Webster’s, he might have read this: Besides the ordinary bow, called also primary rainbow, which is formed by two refractions and one reflection, there is also another often seen exterior to it, called the secondary rainbow, concentric with the first, and separated from it by a small interval. It is formed by two refractions and two reflections, is much fainter than the primary bow, and has its colors arranged in the reverse order from those of the latter. I had never noticed that the second rainbow has its colors in reverse order. This is the quality of eyesight that we want in a dictionary. I looked up “glass,” and noticed that the default dictionary and this old Webster’s both note that it can be used as a synonym for “to reflect.” The default dictionary provides this example: “the opposite slopes glassed themselves in the deep dark water.” Which isn’t terrible, but it sticks to the literal pretty closely — while the old Webster’s give us two examples, one literal and one not, to illustrate the range of uses. Happy to glass themselves in such a mirror. —Motley. Where the Almighty’s form glasses itself in tempests. —Byron. (Byron. Wow. I like a metaphor like that because you learn something about both sides, about the Almighty and tempests both.) This is after two minutes of clicking around. There’s an entire language of rewards in there. (Tip: the original article suggested p { line-height: 0.7em } — which I think might be a typo. I went with 1.2em.)

Posted by on 22 July 2014 | 1:28 pm

Swift and Internal Access as Default

So if internal access is the default, and I don’t want to use it (or want to use it exceedingly sparingly), what do I do? I can think of a few options. Just pay attention. By convention treat internal as private, and pretend that other objects can only see what’s public. The compiler won’t enforce this, but it’s the kind of convention that’s easily enforced manually if it’s habit. Actually mark every damn thing as either public or private. Just don’t ever use the default. That’s a pain, but also the kind of thing that’s not that hard if it’s habit. Modularize. The last one intrigues me. My app could be broken up into modules — Q Branch Standard Kit, DB5, data layer, syncing, images/attachments rendering and storage, and user interface. In that case, I’d be less bugged about objects presenting a larger API, since the objects that could see that expanded API are only other objects in the same module. I do have a natural bent toward modularizing. I’ve always liked splitting things into frameworks. And the tea leaves clearly spell out Way of the Future for this approach. But I have two objections, one practical and one theoretical. The practical one is that I’m still shipping an app for iOS 7, which doesn’t support embedded frameworks. (Or, not exactly.) That problem will take care of itself after a while — but still, it means that right now I’d have to start an iOS 8 branch just for frameworks, which leads down the road to merge debt. Merge debt’s a killer. The theoretical one is the same problem I expressed previously: where I used to think about public vs. private, now I have to think about public vs. internal vs. private, and I’m not sure that that additional complexity is good for me. The discipline of public vs. private, along with the drive to reduce what’s-public down to the barest minimum, has been good for my designs. It suits my brain — which is more experienced than it is clever — quite well. There’s an argument that frameworks really need this, that objects need to expose some bits to their neighboring objects that they don’t expose to the world. I bet that that’s how many frameworks have been written. But I also bet that that’s not how I’d do it. But I could be wrong, and I could be missing out, and maybe I’m just being a stick in the mud.

Posted by on 21 July 2014 | 3:15 pm

Swift Access Control

It’s out, and we have public, internal, and private levels of control. Public means the world can see it; internal is visible inside a target; private is inside-the-file only. (I think I have this right.) My first thought: I’m not sure I’ll ever use internal. My second thought: protected would have been nice. I actually used this in Objective-C, back in the days when we’d declare our instance variables. My third thought: maybe I don’t really care about protected. I’ll clarify. With my Objective-C header files I’m accustomed to thinking about only two levels of access: public and private. I used to use @protected sometimes, back in the days when we declared our instance variables. But I haven’t missed it. And I haven’t even once wished for a target-only access level. Public-or-private as the only choice imposes a discipline that makes for simpler code. I design for the least-possible surface area, and this makes me think harder about design. If I use internal (or protected) access, then my designs are more complex, and I’m one step away from taking expedient shortcuts at the expense of good design. So I have classified internal as a code smell and decided not to use it. But this is entirely provisional, because this stuff is all so new, and because I haven’t thought about it as much as the language designers have. I’m a total Swift newbie, like almost everybody else. (I may end up a fan of internal access, in other words, however unlikely that seems right now.)

Posted by on 21 July 2014 | 1:43 pm

Glassboard Changes

I’ve been watching with interest as Justin Williams works to turn Glassboard into a sustainable service. It’s not profitable or even break-even at this point — but he’s making changes to turn this around. Those changes do mean that people using Glassboard for free will be more limited than they were. For example, boards created by non-paying users will be limited to five members — but people can buy a basic membership for $1/month and get up to 25 members. That’s reasonable. If something isn’t worth $1/month to me, then it’s not worth my time at all. A few people are complaining on Twitter, of course. And some of the complaints seem to be based on the same magical internet thinking that has led to so much doom and heartbreak — that if you make a whole bunch of people happy by giving them wonderful free things, you’ll be rolling in dough. And when that thinking is contradicted by facts and logic, that magical thinking says: you should have given them more and even better wonderful free things, and it would have worked out. I like how Justin is handling all this. He’s direct and clear. Some may take this as bluntness, and it’s true that Justin might never get accepted to the diplomatic corps. But it’s because he doesn’t care about being liked so much as providing a great service. And that’s what we should want him to care about. I use Glassboard all day every day. Our internal Q Branch communication goes through Glassboard. We have a board for Vesper beta testers. Chris Parrish and I have a board where we work on The Record. Seattle Xcoders has a board. My family has several boards. I like that it’s simple and private, that there are no ads, and that we’re not being tracked for nefarious reasons. It’s no Google or Facebook where the users are the product — it’s an honest service that is itself the product. As it should be. I can imagine being in Justin’s shoes. As a fellow indie doing a hard job, he deserves our best wishes. And, if you find the service useful — as I most certainly do — it deserves your financial support. Because we developers all know that wonderful things are not free — or, if they are, they don’t last.

Posted by on 21 July 2014 | 12:18 pm

[Sponsor] UI for iOS: Filling Gaps in the UIKit Framework

Telerik UI for iOS is a native development toolset featuring an advanced Charting library with 10+ fully customizable chart types, Calendar, AppFeedback and Data Sync controls. Integrating the components in your Xcode project is very straightforward thanks to the easy-to-use API. The product comes with dedicated support and detailed documentation of the API. Give it a try for free and get advantage of the dedicated support that comes even with the trial version of the product.

Posted by on 21 July 2014 | 12:11 pm

Chris Liscio Does the Hard Work

Chord Intelligence. Screw that guy. While I’m fussing over the best way to do an animation, he’s doing science.

Posted by on 18 July 2014 | 8:05 pm

Vesper, Auto Layout, and Justin’s Book

Last night I decided to use auto layout for some sub-sub-sub-view in Vesper for iPhone. Worked great. (I’m getting the hang of it.) Except that it broke the interactive pan-back-from-detail transition. The view just wouldn’t move with your finger. I have no idea why. I pulled out the little bit of auto layout code I was using. So: enter Justin Williams. Today I emailed him to ask if his new book covered auto layout and interactive transitions, and he said he’d give it a shot. I like how he’s doing this. He’s put out an early, unfinished version of his book and he’s getting feedback as he goes. Very cool. The thing I need to learn isn’t really using auto layout for layout — I’m getting the hang of that part. The Mac version is all auto layout, even. But the iPhone app barely uses it all, since the app is so full of animations and interactive transitions, and I just don’t get (yet) how to use auto layout with all this. You might think I’d feel some urgency about auto layout, given the rumors of 4.7" and 5.5" iPhones. If the rumors are true, those screens might have different point dimensions than what we’ve seen so far. (Maybe. Even if they don’t, we should be prepared for it.) However, it’s no harder to support different dimensions using layoutSubviews and layout code than it ever has been. There are a few places where Vesper hard-codes screen width at 320 points — but I could fix those in 15 minutes. The Credits screen is written to expect just two specific heights, but it wouldn’t take much work to make it work with variable heights (and it would probably simplify that particular code, actually). No other part of the app expects any particular screen height. It’s not urgent, in other words, but it’s still important to switch to auto layout. What’s cool about auto layout isn’t that it allows us to deal with different screens — we can do that the old-fashioned way just fine. All those Mac apps for all those years handled resizing windows and views without auto layout, after all. What is cool is that we can switch from imperative to declarative style, and that matters. The more we can do of that with our UI code (which is so fiendishly boring to work on) the better.

Posted by on 18 July 2014 | 7:49 pm

auto_closure

Apple, Building assert() in Swift: Auto-closures are a powerful feature because you can conditionally evaluate an expression, evaluate it many times, and use the bound expression in any way a closure can be used.

Posted by on 18 July 2014 | 7:18 pm

The End of the Gloomy Source List

I’ve been spending most of my time in Yosemite for a while now. My favorite on-the-surface change is the change to source lists. The sad-and-blue source list we’ve had for years — first seen in iTunes, iLife, and Mail — has been replaced with a translucent source list. It’s more fun, and I think people are going to love it. But me, I’m ultra-sensitive to on-screen clutter. (It’s a flaw.) I almost never have files on my desktop. There are relatively few icons in my Dock compared to other people (around 12). I hide apps that are not in active use — at most I’ll have Xcode, Terminal, and Vesper for Mac showing. My desktop background is always a solid color. So I turn off source list translucency, via System Preferences > Accessibility > Display > Reduce Transparency. And it looks great. Source lists are a nice very light gray, rather than that wiped-out blue we’re used to. When I have to go back to 10.9, and have to deal with the old-style source list (in Xcode, especially), I can’t wait to get back to Yosemite. I’m surprised by how much of a difference this makes to me. It’s a big deal. Update a few minutes later: William Van Hecke posts on Twitter: We’ve long called that sidebar color “corpse blue” around here. It’ll be sad to lose that bit o’ jargon.

Posted by on 18 July 2014 | 1:51 pm

New Database

Realm is a new mobile database that I should look at. While there are many options for server-side databases, for mobile it’s pretty much SQLite. (Core Data uses SQLite.) A few people may be using LevelDB (which I’ve been meaning to look at). Perhaps some people are using Kyoto Cabinet. I love SQLite. I’ve been using it since SQLite 2.something. I’ve just about made a career out of it. But if you asked me if we mobile developers should have more options, I’d respond with an emphatic yes.

Posted by on 16 July 2014 | 7:55 pm

A Stock Control Won’t Always Do the Job

I wrote about using stock and custom controls the other day, and I was careful to make the point that sometime custom controls are absolutely needed. Vesper has a bunch of custom controls — far more than in any app I’ve made before. We could probably cut out a few of them, especially now that iOS 7 and 8 added features that we didn’t have when Vesper was first created, but we can’t cut all of them, or even half. Here’s a small example: If you’re a Vesper user, you know that tags sit above the keyboard when you’re editing. When you’re not editing, they appear below the end of the text. The tags move as the keyboard appears and disappears. You also know, if you’re a user, that tapping a tag gives you a little menu — much like the text editing menu — that lets you copy or remove a tag. The tags themselves are a UIButton subclass. A fairly elaborate one, but still a UIButton. That menu, though, is entirely custom. It’s not even a popover, since popovers won’t appear on iPhones until iOS 8. It’s a fake popover, custom from the ground up. It seems like this is the perfect place to use UIMenuController. And, in fact, if you look at the menu (just tap on a tag to see it), you’ll see a black menu with white text, rounded edges, and an arrow pointing to the tag button. It looks almost exactly like a UIMenuController menu, in other words. A normal, non-obsessed person wouldn’t notice the difference. So why not switch to UIMenuController? Delete all that custom code. Great idea. (I love deleting code. Love love love.) But UIMenuController wants the item attached to the menu — the tag button, in this case — to become first responder. And, as soon as the button becomes first responder, the text view is no longer first responder, which means the keyboard falls away, and the tag buttons move so that they’re anchored at the end of the text. (And the UIMenuController menu shows and hides real quick, as if it’s been frightened by all the sudden activity.) So we can’t use UIMenuController in this case. We could do something entirely different — a UIActionSheet, for instance — but that would be a usability loss in this case. A UIMenuController-like-menu really is the best way to solve this problem. Which means we have to use a custom control. It’s possible that, in iOS 8, I could make it a real popover, but I’m not sure I’d have control I need over the appearance. (The corners have to be rounded just so, the arrow has to be the way it is, etc.) Anyway. That’s show biz for ya. Update 9:15 pm: Well, it’s possible to keep the keyboard up when using UIMenuController. See Jared Sinclair’s tweet. I’m not sure that would actually work in my case, since it would hijack typing, which should go to the text view. (I say this without actually trying it, though.)

Posted by on 16 July 2014 | 7:38 pm

Overcast

It’s shipping. It’s good. You should get it.

Posted by on 16 July 2014 | 11:04 am

Lettersapp.com Auction Finished

The winning bid was $1,060, which will go to App Camp for Girls. Congratulations to the winner! And thanks to everyone who bid.

Posted by on 15 July 2014 | 10:54 pm

A Perfect Day for a Pinboard Client

Spillo from Bananafish Software looks pretty cool. Includes AppleScript support, even.

Posted by on 15 July 2014 | 11:05 am

String Constants

Here’s my secret, or maybe my superpower, or maybe just me being lucky — I’ve never had a bug related to using a string literal when I should have used a constant. But I have had bugs when I used the wrong string constant. Here’s a line of code that just made the in-development app throw an exception: NSArray *uniqueIDs = [syncNotes valueForKeyPath:​VSSyncNoteIDKey]; Looks good, right? But it’s wrong. I replaced it with this — and the bug was fixed: NSArray *uniqueIDs = [syncNotes valueForKeyPath:​@"uniqueID"]; You’ve figured it out already, I’m sure — VSSyncNoteIDKey != @"uniqueID". VSSyncNoteIDKey is @"noteID", which is the server name for a note’s unique ID. The local storage name is uniqueID. And I picked the wrong one in that line of code. The real way to fix it is this: NSArray *uniqueIDs = [syncNotes valueForKeyPath:​VSUniqueIDKey]; (Which I changed it to after having to find the right constant for uniqueID.) I know that using a string constant is the accepted best practice. And yet it still bugs me a little bit, since it’s an extra level of indirection when I’m writing and reading code. It’s harder to validate correctness when I have to look up each value — it’s easier when I can see with my eyes that the strings are correct. I knew I wanted @"uniqueID" and could have typed that — yet I used VSSyncNoteIDKey (probably because that’s where autocomplete led me first, and it looked right). I know the three knocks against using string literals: It’s hard to spot typos by eye. The compiler won’t catch errors. If you make a change, you have to change it in multiple places. But I’m exceptional at spotting typos. And I almost never have cause to change the value of a key. (And if I did, it’s not like it’s difficult. Project search works.) The question is: do I want to be the one guy who does what every other developer in the world thinks is terrible? What if I believe, honestly and with good reason, that my using string literals would make for fewer bugs during development? You’re horrified right now, I know, and you kind of wish I hadn’t posted this. (Think of the children!)

Posted by on 14 July 2014 | 1:56 pm

Second-to-last Day for Lettersapp.com Auction

The bid is up to $555.07 for Lettersapp.com. The money will go to App Camp for Girls. The auction ends Tuesday at 7 pm Pacific. Don’t miss out! Great domain name and great cause.

Posted by on 14 July 2014 | 11:21 am

Swift Reflection

When I wrote about Swift structs and valueForKey yesterday, I didn’t know of a way to get this behavior. Then Jason Peebles posted a gist showing how to do it. (Don’t be blinded by the fact that it’s doing operator overloading. The body of the function is what’s important.) Though it’s not documented in the Swift Standard Library Reference — and is subject to change, and could disappear entirely — Swift has a reflection API. I wouldn’t build anything on it, myself. It’s one thing to use documented features knowing that they could change — but using undocumented features is just asking for trouble. But still, it’s interesting. The Objective-C runtime has methods for getting lists of properties and methods and other info about objects — but they’re C APIs and they use C types, so they’re not that nice to deal with. And, given the general guideline that #import <objc/runtime.h> in production code is almost never a good idea — and given that Cocoa has valueForKey:, setValue:forKey:, performSelector:, and respondsToSelector: — the Objective-C reflection APIs are (as far as I can tell) rarely used. This is by design, surely. And you can imagine why: using reflection is a great way for developers to have fun while making clever and hard-to-understand systems. But here’s the thing: I want this. It has its uses. And, used well, it can make for simple and easy-to-understand systems that are easy to maintain. I forget who said that Swift is a language that can use something like Core Data but where you couldn’t actually implement something like Core Data. You might have solid reasons for wanting to look at an object’s properties (to write a generic JSON serializer/de-serializer, for instance). You might want to be able to provide method implementations at runtime, as Core Data does with @dynamic properties in Objective-C. If I had to guess, I’d say we won’t see much of this in 1.0. It’s an advanced feature, not very safe and very open to abuse, and Swift needs to focus on safety for its first release. But before too long we’re going to need this stuff. That there’s a reflection API, however undocumented and likely to change, is a good sign.

Posted by on 13 July 2014 | 2:03 pm

Swift Structs and valueForKey

Though I’m not writing very much code in Swift, I’m writing a little — and my brain is running a background thread where it keeps thinking about Swift and how my designs will change with Swift. One of the things that intrigues me is the idea that structs can be used in place of objects in some contexts. Structs make multi-threaded programming simpler, since they’re passed by value and tend to be immutable. I came up with a good use case, but then I hit a snag. API Code When Vesper’s sync system gets a JSON reply from the server, it has to turn that JSON into an array of something usable, and then merge those something-usables with existing model objects (NSManagedObject-like objects), and create new model objects when there isn’t an existing object. The something-usables could be structs instead of objects. They can be created in a background queue (so that the JSON-to-struct conversion happens off the main thread), and then passed to the main queue where they’re merged with existing model objects. That they’re immutable is perfect. The structs don’t need to change — they’re just a representation of what the server provides. Only the model objects need to change. The Snag For every merge-able property there are really two properties, and there’s a simple naming convention. For example, a note’s archived flag has two properties: archived and archivedModificationDate. Merging works like this pseudo-code: if existingObject.archivedModificationDate < serverObject.archivedModificationDate {   existingObject.archived = serverObject.archived   existingObject.archivedModificationDate = serverObject.archivedModificationDate } But the code doesn’t actually look like that. Instead of duplicating the above for each property, there’s a single method that takes server object, existing object, and property name as parameters. Then it uses valueForKey: on both server object and existing object. (It gets the key for the date value by adding "ModificationDate" to the property name.) This turns merging a given property into a one-liner: mergeProperty(existingObject, serverObject, "archived") (At this point I could, but haven’t, specify an array of property-names-to-merge in a plist rather than in code. I’m partial to that kind of thing, since it allows me to write highly generic and reusable code.) The snag: structs don’t respond to valueForKey I fired up a new playground and create a simple struct. It worked fine — I could access values via dot notation. Then I tried valueForKey — which didn’t work, as expected. Because I’d written a bunch of JavaScript code lately, I also tried the following: x["propertyName"] And: x.["propertyName"] Neither of those worked, either — but how cool would that have been? And Swift-like, I think, to provide a syntax for KVC rather than force the use of valueForKey:. Perhaps there is a way to do this right now, and I just don’t know about it. Totally possible. (Let me know on Twitter if that’s the case.) If there’s not, then I can’t use structs in this case, no matter how much it makes sense. And this is a case where Objective-C’s magnificent suppleness — which we app developers rely on, which we prize — should provide some direction for the future of Swift. rdar://17652770

Posted by on 12 July 2014 | 1:57 pm

Swift Blog

There’s a new Swift blog at developer.apple.com. (You should subscribe to the feed.)

Posted by on 11 July 2014 | 1:16 pm

On Adding AppleScript Support

Me, writing in the latest objc.io: Making Your Mac App’s Data Scriptable: Scripting isn’t a matter of automating button clicks; it’s about exposing the model layer to people who could use your app in their workflows. While that’s usually a small minority of users, they’re power users — the kind of people who recommend apps to friends and family. They blog and tweet about apps, and people listen to them. They can be your app’s biggest evangelists. Overall, the best reason to add scripting support is that it’s a matter of professionalism. But it doesn’t hurt that the effort is worth the reward. The entire issue — Back to the Mac — is good. It includes articles by Craig Hockenberry, Gus Mueller, Daniel Eggert, and Florian Kugler.

Posted by on 11 July 2014 | 1:10 pm