Swift Diary #13: The Addiction

I’m at the point with Swift where I get on a roll sometimes. That’s when it gets fun. * * * I know the saying that programming isn’t typing — it’s thinking, and with autocompletion these days it really doesn’t matter how much typing a language requires. Except that that’s not entirely true. Programming is also typing. Or, put another way: a whole bunch of programming is housekeeping. And, for the most part, Objective-C requires a lot more housekeeping than Swift does. You end up with longer lines, twice the amount of files to maintain, imports to manage, types to type, and so on. With Swift you get more logic per page with less effort. * * * I’m doing my best to understand exactly what sculptures come from this new type of rock. I design like an Objective-C programmer, but I’m learning how to design like a Swift programmer. I do still wish for things — especially, 1) the ability to treat objects that conform to the same protocol as the same type, and 2) something like KVC. * * * But here’s what happens now. Sometimes I go to write some Objective-C code and I sigh at the effort — because I know the Swift version is half as long. I sigh at jumping to the top of the file and adding an import, and I sigh at switching to the .h file and adding a method. Part of me still wishes that Swift had been something like a cross between Objective-C and Ruby. I wanted a concise, expressive, and dynamic scripting language where I could be massively productive. Instead I got a concise and expressive programming language that’s less dynamic than I’d like — but where I could still be substantially more productive (once I learn it) than in Objective-C. And that’s where I am now — starting to feel that boost in productivity with Swift, and getting a little bit addicted to it.

Posted by on 27 August 2015 | 1:07 pm

On Scripting

Graham Lee writes of The death of scripting and The paradox of scripting. But how can scripting be dead? There’s bash, and powershell, and ruby, and…even Perl is still popular among sysadmins. There’s never been a better time to be a programmer or other IT professional trying to automate a task. True, but there’s never been a worse time for someone who doesn’t care about computers to use a computer to automate a task. Apps are in-your-face “experiences” to be “used”, and for the most part can’t be glued together. There are counter-examples, of course — the apps I work on (Mac versions of OmniFocus and OmniOutliner) are highly scriptable. But the trend toward silos, sandboxing, and highly-controlled experiences is clear. (First thing I did was look to see if Slack has a scripting dictionary. Of course not. Neither does HipChat. Apps these days.) If you’re thinking about adding AppleScript support to your app, read these articles from objc.io last year: Making Your Mac App’s Data Scriptable Scripting from a Sandbox In the first of these, I write: When adding AppleScript support — which is also JavaScript support, as of OS X 10.10 — it’s best to start with your app’s data. 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.

Posted by on 25 August 2015 | 1:08 pm

OmniDev Blog

At Omni we started a new blog. (With an RSS feed.) I wrote an article: Making Tab-Switching and Scrolling Faster in OmniFocus for Mac. And Tim Ekl has written the first two parts of a series on building push-triggered sync: Building Push-Triggered Sync, Part One: Choosing a Language Building Push-Triggered Sync, Part Two: First Steps Whistle-whetter: we’re using Go. Read all about it. PS I’ve been on my yearly beach vacation. Back now.

Posted by on 25 August 2015 | 12:50 pm

Swift Diary #12: The P Word

Guy English writes a Swift Protocol Proposal. It’s worth reading the Twitter discussion. Wooji Juice disagrees, and writes about the genius of Swift protocols. Daniel Jalkut writes about The Seven Stages of Swift. I think I’m inhabiting several of them at once. * * * I’ll try to re-state my issue with protocols again in a simple way. I’m writing a Finder replacement, let’s say. The UI has folders and files. There’s a Folder class and a File class. They’re quite different things, so there’s no class inheritance. I want to represent the file system internally as a tree of Folders and Files — let’s say I want to use Sets. A Folder has a children property, which is a Set that contains both Folders and Files. I want Folder and File both to have a writable name property so the UI can edit their names. Something like this ought to come naturally and easily to a language, or else that language is not helping me write apps. This isn’t some weird, made-up situation. It’s super-common. Look at Mail’s sidebar, for instance — there are a bunch of different things. (Or look at Xcode’s sidebar.) Yes. There are ways to deal with this in Swift, including using @objc protocols and collections. Or proxy objects or base classes (ugh) or whatever. But the most natural way is protocols. If my point was just to get my work done and ship a great app as soon as possible, I wouldn’t be using Swift. I’d be using what I know: Objective-C. But I’m also taking the opportunity to learn Swift, and the best way to really understand it is to use, as much as possible, pure Swift, rather than Swift-with-objc. And if, along the way, I run into questions or things that don’t help me write high-quality apps more quickly, then I’ll ask questions and even criticize when warranted. My hope (and belief) is that the language designers take the feedback in the spirit intended. I want to help make Swift a great language for writing apps. The designers may not give me what I want — it’s possible that I’m just asking for a faster horse, and they’re delivering a Model T, after all — but feedback from experienced app-writers ought to warrant attention. (Which I think it gets, which makes me glad.)

Posted by on 14 August 2015 | 12:13 pm

Swift Diary Page

I collected my recent articles on working with Swift on a single page. It’s linked-to at the bottom of every page on the site, so you can find it later.

Posted by on 13 August 2015 | 3:58 pm

People Were Quite Rightly Outraged at Me

In 1990 I was an editor of the weekly college newspaper at Seattle Central Community College. Each week we printed a comic strip drawn by a student. The strip — “Red Ruffensor,” as in red, rough, ‘n’ sore — was a liberal satire of action hero comics. It was community college student work, but pretty good for that. We were criticized, though, for not including anyone but white men and women in the strip. The position of the cartoonist was that this was a satire of a genre that doesn’t include anyone but white men and women (mostly men), and that to include anyone else would actually be mean. (Every character in the strip was a jerk.) So he didn’t. Until, under continuing pressure, he changed his mind. One day, the last panel of one of the strips included a character with stereotypical and exaggerated Asian features, and a speech bubble: “Me finally get a line!” Awful, right? It fit, though, because the whole point of the strip was that action hero comics are homophobic and racist and sexist (and yet homoerotic), and this was a liberal college that, we thought, got it. I was 21 years old. I okayed it. It ran. This became a huge (but localized) controversy. Seattle newspapers wrote it up, and some people (though not me) discussed it on 1090 talk radio. There were numerous discussions at school, and afterward the newspaper staff attended sensitivity training. What my 21-year-old self didn’t get was that that last panel was mean-spirited, even if, to our young minds, it made sense. The integrity of the comic as satirical speech would not have been harmed by leaving it out — and, even if it would have been, would that have been so important? (No. Consider the context.) I don’t remember if I apologized then or stuck to my guns. At any rate, now I say: I apologize. I’m sorry for running that. I should not have. It was wrong. * * * If I had the ability to send myself a message back in time, I would send myself a message to before the cartoonist wrote that panel. I would tell myself how to deal with the pressure to make the strip more inclusive. Here’s what I’d write: Dear Brent, Hi. I’m 47 years old now. Life is good. You’re still sitting in front of a Mac. I hear — actually, I remember — that you’re under a whole lot of pressure to make Red Ruffensor inclusive. Well, thing one: you, young man, have no idea what real pressure is yet. But I remember how this felt, and you need some advice. Luckily, this isn’t that hard. The solution is, in part, the same solution you’ve always used and always will use: start writing. Step one: Write an editorial explaining the comic — it won’t be hurt by explaining that it’s satirical, and that everyone in the strip is awful, and it’s all about pointing out the homophobia (and latent homosexuality) of action hero comics. Let people know that Red Ruffensor actually means “red, rough, ‘n’ sore” — because I guarantee you that they don’t know. Let people know that, in this particular comic, inclusiveness is a bad idea. Explain that the cartoonist is throwing punches — haymakers — at everybody in the strip. Also write that the paper is committed to inclusiveness, and so you’re looking for more student cartoonists. And if anyone reading this might be that cartoonist, please get in touch! And make a pledge: no Red Ruffensor in a given week unless there’s at least one other strip to run. Step two: Actually find another cartoonist. Or more than one. And run their work, and write an editorial that first week introducing the new strip (or strips), and thank the people who asked that the paper be inclusive, since it’s now better for it. That’s it. Pretty easy. Be good! Regards, your pal, Brent

Posted by on 13 August 2015 | 2:11 pm

Swift Diary #11: Objective-Swift

My main problems with Swift are: Collections of protocol-conforming objects don’t work as I need them to. No KVC. No equivalent of NSClassFromString. Now, these aren’t really problems with Swift — they’re problems with pure Swift. But there’s no such thing as a pure Swift app. The frameworks are Objective-C frameworks. You can’t load nibs without Objective-C. Given that, I made the pragmatic decision to start using @objc protocols, classes, and collection types where those things make sense, where Swift fought against my design. And suddenly the language is a joy to use. It’s like Objective-C but with type inference, no .h files, fewer imports, shorter syntax — and I get the things I was missing. I’m still not sure I like optionals, and there’s more casting than I’d like, but overall it feels like Objective-C with less housekeeping. In this language — I’ll call it Objective-Swift — I can go fast. * * * More about optionals… For those who don’t know Objective-C: it’s based on message passing, and sending a message to a nil receiver is fine. It just doesn’t do anything. If it has a return type, it returns nil. (Roughly speaking.) In other words: say foo is nil. The following in Objective-C is a-okay — nothing happens when foo is nil: [foo doSomething:someArgument]; The Objective-C syntax is weird to everyone who isn’t used to it, I’ll grant. The above could be expressed in another language as foo.doSomething(someArgument) What’s cool about this is that you can do nil-checking less often. Say you call a method that returns an object or returns nil. If it returns an object, you want to tell that object to do something, or you want to get one of its properties — or you want nothing to happen if the object is nil. You can just skip the nil check and write your code as if the object isn’t nil. I’ve relied on that behavior thousands of times. As an Objective-C developer it’s second nature. There are obvious problems with that, though. One is that it’s not clear at all in the code that the object may be nil and nothing’s happening and it’s okay (it’s by design). Someone reading it — including future me — may not realize it, and it may be important. The second, and related, problem is that nil as an argument rather than as a receiver is a completely different story. Plenty of methods will crash if you pass nil as an argument. So it’s not true that Objective-C code is free of nil-checking. Along comes optionals in Swift, which make it clear when a thing may or may not be nil. When a variable is defined as optional, and you want to do something with it, you have to handle the nil case, and that’s enforced by the compiler. That’s good — very good, in fact — except for all those times when I’m bugged because I have to satisfy the compiler when I feel like I shouldn’t have to, when years of experience tell me it’s quite okay to ignore the possibility of nil. So I’m of two minds on optionals. Like many other things with Swift, I don’t really care about it for code that’s entirely mine — because I know my own style so well, because I know what mistakes I make and don’t make — but I do care about it for code that will have many authors.

Posted by on 11 August 2015 | 12:05 pm

Swift Diary #10: Changes to Properties

Both of the apps I’m working on have a custom persistence engine (built on top of FMDB and SQLite). Core Data isn’t a great fit for these apps. (This isn’t me being contrary. I’m doing very database-y stuff, and Core Data is an object persistence system, not a database. Seriously: you should use Core Data.) The model objects are pure Swift objects. And I’d like to borrow one of Core Data’s awesome features: when a property is set on an object, the persistence system should get notified. It will record the change, then coalesce and queue updates to the database. * * * Let’s say I’m writing a Twitter client. (This an example used for historical reasons — because, if you look at history, you’ll find that people used to write Twitter clients — and should not be taken as indicative.) Let’s pretend it has a Tweet class, a pure Swift class, with about 20 properties (some from the server, some local) — and setting any one of those should trigger the persistence system to do its thing. I can do what I want if I add a didSet code block to each property. One of the cool things is that didSet is ignored during init, which means I can initialize an object with data without didSet getting called and triggering an unnecessary database update. Each didSet block looks like a variation on this: recordPropertyChange(self, key: "somePropertyName", newValue: somePropertyName) It’s a pain to do this for every single property in every single class that’s database-backed. * * * Were this Objective-C, the situation would be fairly easily dealt with via dynamic method resolution. Each property would be marked as @dynamic, and methods that do the right thing (update in-memory storage and notify the persistence system) would be provided at runtime. That’s not available to pure Swift classes, though. I could ask for that feature — but it had me thinking that there might be a better feature request to make. Classes could optionally (perhaps when conforming to a PropertyObserver protocol) implement a class method that gets notified when any property changes in the same circumstances where it would call didSet. (It should still call didSet, when it’s there.) Something like: class func didSetProperty<T, U>(object: T, key: String, newValue: U) {   recordPropertyChange​(object, key: key, newValue: newValue) } (I’m totally unsure that the above is the right way to express this. Maybe object should be Self? I’m still learning my way around generics and protocols.) If there already is a way to solve this, and I don’t need to make this feature request, then I’m keen to hear the solution. It would be useful.

Posted by on 7 August 2015 | 6:47 pm

Swift Diary #9: Where I’m Stuck

Let’s say I’m writing a multi-platform social networking client. I know a person, and I have it on strong authority that Jack Dorsey’s going to re-open the Twitter APIs. (I can say this out loud because it sounds like I’m just pretending.) So my social networking client will support Twitter, App.net, LinkedIn, and a handful of other systems. (Let’s say.) I’ve got the problem that I’ve written about before — protocols and collections don’t mix well. I’m using a protocol for the Account type. There are classes that conform to the Account protocol: TwitterAccount, AppNetAccount, LinkedInAccount, etc. There’s also an AccountManager class that manages the accounts list. The list is a Set<Account>, as it should be (since no account should appear more than once; since ordering isn’t important). Except, of course, no it isn’t, because Account is not Hashable. In reality it’s an array — [Account] — that holds all the accounts. That’s fine. That works. Except when it doesn’t: except when I want to see if the array contains an account object. Error: cannot invoke 'contains' with an argument list of type '(Account)' So I can’t do manually what a Set would do automatically, which is to ensure that a given account appears only once. And, here’s the thing: this scenario doesn’t appear once but a bunch of times. (A major example is the TimelineItem protocol. Each different type of account has one or more different TimelineItem-conforming classes, and a given timeline can contain multiple different concrete TimelineItem objects.) I’ve worked around some of these, and I’m sure I can come up with work-arounds for each case. But it’s getting increasingly frustrating. It’s slowing me down. I have some options: Continue with the work-arounds, despite the frustration. (Even though these projects are supposed to be fun.) Switch to Swift plus Objective-C types — that is, make Account and TimelineObject @objc protocols and make the classes that conform to those protocols @objc types. Then use Foundation collection types NSSet and NSArray. (This is like writing Objective-C with Swift syntax.) Switch to Objective-C, which handles my design perfectly. But is not Swift. I don’t know what to do. What would you do? * * * Update 10:40 am: Some people are asking why Account can’t be Hashable. It’s because it can’t be Equatable. (For starters. There might be other reasons too.) protocol Account: Equatable {   var accountID: String {get} } func ==(lhs: Account, rhs: Account) -> Bool {   return lhs.accountID == rhs.accountID } Error: protocol 'Account' can only be used as a generic constraint because it has Self or associated type requirements. If there’s an answer to this, then I’d be extremely keen to know what it is! * * * Update 11:00 am: Got Equatable working, thanks to Kyle Sluder, but not Hashable. Here’s my current gist. * * * Update 11:10 am: I spoke too quickly. Equatable is still the problem. Here’s the gist. Which means I’m faced with the original point of this post. What to do? * * * Update: 11:35 am: Several people have suggested using a base class instead of a protocol. That should do the trick, yes. But there were reasons to use protocols in the first place: I dislike class inheritance in general. I don’t like using a base class purely to satisfy the type system. Requiring a base class makes doing a plug-in API more difficult. (It’s simpler to have plug-ins conform to a protocol. Though I have to admit I haven’t done any research with Swift plug-ins, so it’s possible I’m completely optimistic here anyway.) I’m pragmatic, though, and I may end up doing this as a work-around.

Posted by on 5 August 2015 | 12:24 pm

Mapping with Wil

Wil Shipley writes about eliminating loops in Swift by using map and filter.

Posted by on 5 August 2015 | 12:11 pm

Swift Diary #8: forwardInvocation

Let’s say I’m writing an image editor. (I use this example on my blog for historical reasons — because, historically, I like to rib Gus. It should not be taken as indicative.) Here’s the problem I’m running into: I have various layer classes (BitmapLayer, ShapeLayer, GroupLayer, etc.) that live outside the responder chain. There’s a Canvas object that is in the responder chain. So I hook up my menu items and buttons with a nil target and whichever action makes sense. Now, the Canvas object doesn’t implement the various actions that the layers implement. Instead, the Canvas object implements respondsToSelector: — it returns YES if the selected layer responds to that selector. And then, if YES, forwardInvocation: in the Canvas object forwards the message to the selected layer. Well, that’s the design, anyway. Sensible. Time-saving. Simple. But forwardInvocation and NSInvocation are not available to Swift. * * * But, soft! What light through yonder window breaks! While forwardInvocation: isn’t available, forwardingTargetForSelector: is available. Which means the Canvas could see if the selected layer responds to that selector, and then does a performSelector: on that layer. Correct? If so, then it means that anyone writing an image editor is good-to-go with Swift. (That last sentence is the rib-Gus part again.) * * * However, Swift support for forwardInvocation: and NSInvocation would be useful. These things have their uses, and while forwardingTargetForSelector: can take care of some of them, they don’t take care of all of them. * * * Update 1:30 pm: Kyle Sluder reminds me: Remember that -[NSResponder supplementalTargetForAction:…] does not require its return value to be an instance of UIResponder. (Or NSResponder, in my case as a Mac app writer.) At any rate, supplementalTarget​ForAction​:sender: might fill the bill even better. The Canvas object could return the selected layer object.

Posted by on 4 August 2015 | 3:16 pm

Swift Diary #7: Protocols, Arrays, and Casting

I mentioned before that I’m making heavy use of protocols in my new apps. Here’s what got me today: Let’s pretend I’m writing an email client. (This is an example I use on my blog for historical reasons, and should not be taken as indicative.) I have a tree of Node objects. Each Node has a represented object, which is a data model object. There’s a NodeRepresentedObject protocol. There are also more-specific protocols. EmailMessage, for instance, is a protocol because I might need different concrete classes for different types of accounts (Gmail, IMAP, POP, etc.). My class Mailbox has its internal array of email messages. It also has a children variable which is part of the NodeRepresentedObject protocol. Here’s the relevant code: protocol NodeRepresentedObject : class {   var children: [NodeRepresentedObject]? {get} } protocol EmailMessage : NodeRepresentedObject {   // stuff here… } class Mailbox : NodeRepresentedObject {   var messages = [EmailMessage]()   var children: [NodeRepresentedObject]? {     get {       return messages     }   } } The error is: 'EmailMessage' is not identical to 'NodeRepresentedObject'. That’s true: it’s not. But an EmailMessage is a NodeRepresentedObject, so it ought to work just fine. I tried this: return messages as [NodeRepresentedObject] The error: '[EmailMessage]' is not convertible to '[NodeRepresentedObject]'. Why not? Again — it is a NodeRepresentedObject. The best way I’ve found to deal with this is to map it. return messages.map { return $0 as NodeRepresentedObject } That seems crazy. I’m using map to create an array whose members are absolutely identical to the original array. And if it would let me do that, why not allow my original solution? (Or at least the second solution?) Update 5:30 pm: Filed as rdar://22109003.

Posted by on 2 August 2015 | 7:02 pm

Swift Diary #6: Window Controller Initialization

I’m working on UI code — and the below took me a half hour and quite a bit of frustration to figure out, so I thought I’d better write it up. Here’s the deal: I want my window controllers (and view controllers too) to know about their nib name, but the outside world should not know about their nib name. Here’s how I handle this in Objective-C: the NSWindowController’s subclass has an init method that references the nib name. - (instancetype)init {   return [self initWithWindowNibName:​@"SomeNibName"]; } To instantiate the window controller from elsewhere, I just do [SomeWindowController new]. (Could be alloc/init, but I like the fewer characters this way.) Here’s how to do it in Swift: convenience init() {   self.init(windowNibName: "SomeNibName") } And then I can instantiate the window controller via SomeWindowController(), and all’s well. Now that I have the answer, it looks so simple. Many Bothans died, etc. PS Yes, I’m using storyboards, except for the few things that should be nibs.

Posted by on 1 August 2015 | 4:57 pm

Swift Diary #5: Yet More Uses for KVC

I’ve argued before (here and here) that pure Swift objects and structs need KVC or something like it. I keep running across real-world uses. I present two more. Templates In NetNewsWire you could create a custom theme, which was a CSS file, an HTML template, and, optionally, some assets. Inside a template you could type things like [[newsItemTitle]], and at render-time that string would be replaced with the title. How this was done: The template renderer took two objects: A string — the template itself. (The thing that included some HTML and code like [[newsItemTitle]].) An object, typed as id. The template renderer worked by scanning the template. Every time it found something in double-brackets — [[whatever]] — it pulled out the whatever part (call it the “tagName,” for lack of a better word) and got the replacement string like this: replacement = [obj valueForKey:tagName]; Then it would replace [[whatever]] with the value of replacement. What was cool about this was that the template renderer didn’t know anything about HTML or RSS. It didn’t know anything whatsoever about the passed-in object that generated the replacement strings. The system was uncoupled and reusable. It knew how to scan through a string and replace [[something]] with a call to valueForKey:, and that’s it. Would I love to be able to do the same thing with a Swift struct as the object? You bet. This is a great case for a struct. Object Comparison and Updating Say I’m writing an RSS reader or Twitter client — or something like Vesper or Glassboard — where the app makes calls to a web service to get a bunch of objects, then it compares those incoming objects to objects it already has and updates them as needed. This code doesn’t have to be a pain to write. In fact, you can write it once and reuse it in every single app. You need a comparison method that takes two objects — typed as id — and a set of property names to check. + (void)updateExistingObject:​(id)existingObject withServerObject:​(id)serverObject propertyNames:(NSSet *)propertyNames; Loop through propertyNames. For each: id oneExistingValue = [existingObject valueForKey:​onePropertyName]; id oneServerValue = [serverObject valueForKey:​onePropertyName]; if (![oneExistingValue isEqual:oneServerValue]) {   [existingObject setValue:oneServerValue forKey:​onePropertyName]; } Note that existingObject and serverObject don’t have to be the same type. serverObject could even be a dictionary. Whatever. It doesn’t matter, as long as the property names match up. Also note that you could easily extend this to return a BOOL saying whether or not existingObject actually changed. This can be very useful if you need to conditionally save a database or plist or update the UI. You can go a step further and have it return the set of property names that changed. If you have a custom persistence system, this could mean less work your database has to do when updating existingObject in the database. (For instance: you could generate SQL that updates the values only for those changed property names.) This is also just a few lines of code away from a syncing system like the one in Vesper. In Vesper the various properties have a modification date property. (For instance: note.text and note.textModificationDate.) The above code would be modified like this: In the case where values aren’t equal, it then constructs the modification date property name from the property name (by appending @"ModificationDate", so that you have textModificationDate and similar). Then it does valueForKey: on both objects to get that date. It compares the dates. Whichever value has the later date is the winning value. And then you could write 100 apps that all use this same code. (To bring it back to Swift: serverObject ought to be a struct.) Trade-offs The compiler isn’t going to catch some possible errors. But I’m willing to put up with that because of the other benefits — these systems are uncoupled and highly reusable, and they mean writing and maintaining less code. I don’t suggest for one second that KVC should be used everywhere and all the time. I love having the compiler catch bugs. But there are often some small-but-important spots like these where KVC is the best choice. Update 10:25 am I had thought it was obvious, but beyond the scope of this post, to point out that in the first pattern you need some constraints and you need to handle undefined keys. This is pretty easily done. The object that generates replacement strings could be a dictionary. Or you could override valueForKey and valueForUndefinedKey. That object certainly should not have any methods other than what’s needed to generate the replacement strings. In the end you might think it’s safer to base the system entirely on dictionaries and use objectForKey instead (especially when there’s a chance that the templates include user data). Totally fair.

Posted by on 29 July 2015 | 12:03 pm

Swift Diary #4: KVC Again

Al Skipp wisely writes (in reply to my post about KVC): It's still the case that Stringly typed code is a pain in the Aris to write/debug/maintain. True. So true. But let me remind you of a place where most iOS and Mac developers do it all the time: Interface Builder. Interface Builder is a Very Fancy XML Editor Some developers eschew Interface Builder (IB) altogether. That’s fair. I myself don’t automatically reach for it — there are times when a UI is so simple that it doesn’t need it, or it’s too dynamic to be expressed well in IB. So I at least think about it before I go there. But I do use it plenty often. And I’d bet that most developers use IB at least a little bit, if not a lot, in their apps. (Though maybe not for games.) And what you do you do in IB? You type (or copy-and-paste) in the class name of your view controller. You click checkboxes and set attributes. In the end you’re just setting a bunch of strings that gets stored in an XML file. In the end, you get things like this: <buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="gear" imagePosition="only" alignment="center" borderStyle="border" inset="2" id="1194" customClass="TransparentButtonCell"> You don’t want to do edit that directly, of course, so you have IB. But this is still what you end up with. Runtime Nib loading uses KVC. Though it may not use setValue:forKey: directly, it does the conceptual equivalent. That does not mean that you can only interact with your objects via valueForKey: and setValue:forKey:, of course. It’s just that instantiating uses KVC. Your own code is still foo.bar = 7 and so on. The alternative to KVC (or something much like it) — commence shuddering now — would be code generation instead. (Those of you who’ve been through that on other platforms, come out from under your desk. It’ll be okay.) Trade-offs Of course, it is a pain when you’ve mistyped — or just plain forgot to type — the name of a class in IB. That’s a drawback of any system like this. But we’re willing to make the trade-off because the productivity gain we get from using IB is worth the occasional issue like this. The nice thing about bugs like that is that they’re usually caught very quickly, and are just a normal part of the development process. It’s what we do for a living. If IB can do it, why can’t I? It’s a pretty nice system. I get to declare things rather than write code — and though I have to take care that my declarations are correct, I still end up saving time and writing and maintaining less code. It’s a win. The Core Data modeler is another example. I don’t have a handy example, but I bet it generates XML (or maybe JSON or, more likely, plists). And the runtime uses KVC and KVO (and method generation, which is another topic) to make it all work. It’s only natural that I might want to write similar systems for my own use. And I have. In the case of the database and model object code that I’ve written, I don’t have a fancy modeler — I just edit a plist. Though editing is more raw, the concept is the same: I type in class names and map database columns to types and property names. And my code — which I can reuse unchanged in as many apps as I want to — uses KVC to put it all together. As IB does. The rest of my code — the code outside my database code — doesn’t use KVC. I still write foo.bar = 7, rather than [foo setValue:@7 forKey:@"bar"]. I can rely on the compiler to tell me when I’ve made an error in the rest of my code. So, in the end, this stringly-typed database/model-object code is way less of a pain to write, debug, and maintain. In fact, I don’t touch it at all, since it’s debugged and working. But I’d still love to make it work with pure Swift objects and structs.

Posted by on 24 July 2015 | 12:04 pm

Swift Diary #3: Arrays, Protocols, and Pointer Equality

Let’s say I’m writing a Finder replacement. (Disclaimer: previous statement may or may not be true.) The common representation of the file system in a GUI app is a tree. A common pattern, then, is to create a tree data structure. The tree is made of Node classes, and each Node has a representedObject which conforms to the NodeRepresentedObject protocol. A representedObject may be a Folder or a File. All the Node class knows is that its representedObject conforms to NodeRepresentedObject. Each Node has zero or more children. The children are Node objects also. The children’s representedObjects are a mix of Folders and Files. * * * Here’s the trouble I ran into. Given a representedObject and an array of Nodes, I wanted to find the Node with that representedObject. Things to know: the representedObjects are uniqued (a file system folder has one Folder object; a file system file has one File object). And, because they’re uniqued, they’re also objects rather than structs. Because this is true, I can use pointer equality on representedObjects. The Objective-C code might look like this: - (Node *)existingChild​WithRepresentedObject:​(id<NodeRepresentedObject)​representedObject {   for (Node *oneNode in self.children) {     if (oneNode.representedObject == representedObject) {       return oneNode;     }   }   return nil; } Pretty simple. * * * My first go at doing this in Swift looked like this: func existingChild​WithRepresentedObject​(representedObjectToFind: NodeRepresentedObject) -> Node? {   for oneChild in children {     if oneChild.representedObject === representedObjectToFind {       return oneChild     }   }   return nil } This didn’t compile: I get the error error: binary operator '===' cannot be applied to two NodeRepresentedObject operands. “But,” I thought, ”shouldn’t pointer equality always work?” Well, no. Not if representedObject is a struct. So it occurred to me that I have to tell Swift that these are both objects, and it works: if (oneChild.representedObject as! AnyObject) === (representedObjectToFind as! AnyObject) * * * But I don’t like using as! — as Rob Rhyne writes, “But every time you type !, someone at Apple deletes a Radar.” So I figured there must be a better way. And there is. Keep the original line as it was: if oneChild.​representedObject === representedObjectToFind. Make NodeRepresentedObject conform to the AnyObject protocol, which lets the compiler know that representedObject is an object, so that pointer equality testing will work: protocol NodeRepresentedObject: AnyObject { It works. See the gist. * * * Here’s the part I don’t totally like: to make this work, it required bringing in Objective-C. AnyObject is an @objc protocol. So here’s my question: is there a way to do this without bringing in Objective-C? (I feel like there are two Swifts. Swift + Objective-C is like writing Objective-C with a new syntax. Pure Swift is another thing. I’m pragmatic, and I’ll use the former as needed — but I want to learn the pure Swift solutions.) * * * Update 10:15 am: the answer came quite quickly from Matt Rubin on Twitter and others: try: protocol NodeRepresentedObject: class { … } Done! It works. * * * Update 10:40 am: and there’s also this, which I didn’t know, from Joe Groff on Twitter: AnyObject is marked '@objc' for obscure implementation reasons, but it is a native Swift feature.

Posted by on 23 July 2015 | 12:10 pm

How to Hang Mail, TextEdit, and Contacts

We often get crash reports where the crash happens outside our code and we can’t reproduce it. (Like every developer, I’d bet.) While our users often tell us what they were doing when submitting a crash log — thanks! it helps a ton — those steps don’t always have the one key thing we need to be able to reproduce the crash. But today we got one from a helpful OmniGraffle user: hit the Return key really, really fast. We tried it, and we reproduced the crash. Then reproduced it in other of our apps, then reproduced it in Mail, TextEdit, and Contacts. (And stopped there.) So I decided to title this post “How to Hang Mail, TextEdit, and Contacts,” because it’s more universal than “How to Crash OmniFocus.” But I’d bet this works on a fair number of apps, Apple’s and not Apple’s. Before you try it, fair warning: you will have to force-quit TextEdit. When I did this on 10.11, things went weird and I had to reboot. Here’s what to do: Launch TextEdit. Start a new document. Type a few characters. Save it to your Desktop. Choose File > Export as PDF… and have it export to your Desktop. Choose File > Export as PDF… again — and select the file you just exported to. (As if you’re going to overwrite it.) Hold down the Return key. TextEdit will hang after a few seconds. You’ll have to force-quit it. Open Console. You’ll see something like this: 7/22/15 3:28:25.441 PM TextEdit[866]: *** Assertion failure in -[NSWindowCentricRemoteView maintainProcess​NotificationEventMonitor:], /SourceCache/​ViewBridge/​ViewBridge-105/​NSRemoteView.m:1356 Note: to make this work, you may have to have your Keyboard key rate set fairly high in System Preferences > Keyboard. (Mine is at second-fastest.) Also note: the PDF part is a red herring. It has nothing to do with PDF. That just happened to be a handy example. Also note: you can do the same thing use Save As… in TextEdit and get a slightly different weird behavior. rdar://21949944 Update 4:20 pm It may not hang on 10.11 b4. You might see some display strangenesses — like black rectangles where a sheet used to be. And you may see notes in Console from com.apple.appkit.xpc.​openAndSavePanelService.

Posted by on 22 July 2015 | 5:35 pm

Swift Diary #2: KVC

I was very glad to hear that performSelector and friends are supported in Swift in the latest Xcode 7 beta. But what I want to talk about today is a similar thing: Key-Value Coding (KVC). I use KVC in a critical part of my apps: the part that creates model objects from database rows. The database code is generalized and shared by multiple apps. I create a mapping (using a plist) that maps SQLite table names to property names and types. The object creation code goes through the mapped property names and does the right thing for each name. In the end it boils down to something like this: [modelObject setValue:​someValueFromDatabase forKey:​propertyName]; (This even works for non-object properties, which is brilliant on the part of KVC’s designers.) I can do this in Swift, too. (Note that this is unchecked code, and I could have the syntax wrong.) modelObject.setValue​(someValueFromDatabase, forKey:propertyName) There are plenty of other places where KVC makes sense. (It’s part of a hearty, dynamic breakfast.) Another example might be mapping NSTableView cells to values — a columns’s identifier might be configured to be the same as a property name, and so it’s easy to get the desired value: modelObject.valueForKey​(columnIdentifier) The coupling here is quite loose, and the compiler isn’t going to tell you if you’ve mistyped a property name. You’ve got all kinds of rope here. But I’m totally comfortable with that. Here’s the deal I’m willing to make: to make my code more elegant (read: smaller, easier to maintain, reusable), I’m willing to let it crash if I’ve configured things incorrectly. A bug here — say there’s a typo in a property name in my database mapping — will mean an instant crash, as the object has no such property name. I’m good with that. Crashes like that have zero chance of living beyond the time it takes me to build and run. * * * If this is available in Swift, then why am I writing about it? Because this is not a pure Swift thing: it’s a Swift + Objective-C thing. You can’t do this with structs, for example. I want to get the advantages of structs. There are plenty of cases where my model objects could be structs. Structs are cool. We’re in a transition period right now. Swift needs Objective-C so that people who rely on the dynamic nature of Objective-C — like me, like many developers — can write their apps. It would be best, though, if Swift didn’t have to carry Objective-C baggage with it forever in order to make it adequate for the job of app-writing. I don’t think it will, even. So my case is that Swift itself needs things like this. If not a clone of KVC, then something very much like it.

Posted by on 22 July 2015 | 3:38 pm

Manton News

The esteemed Mr. Reece has gone indie! Just the other day I described Manton and me as litter-mates. I’m proud of him for taking this leap.

Posted by on 20 July 2015 | 12:02 pm

Swift Diary #1: Class or Struct from String

Like Mike Ash and his Friday Q&A blog posts, I take requests from readers. Unlike Mike Ash, all I have is questions. This one comes from my co-worker Jim Correia, and is related to a question I posted on Twitter last night about instantiating an object whose class is known at runtime rather than compile time. For reference, here’s the answer to last night’s question. Jim takes this one step further: what if all you have is the class name as a string? This isn’t an academic question — it’s something app developers do. For example, do a Show Package Contents on any Omni app and look inside Info.plist — you will likely find class names in the plist. (Example: see OFControllerClass in OmniFocus’s plist. Also look inside the OIInspectors array.) This is a useful pattern when you have a general framework of some kind and you want to configure it for a specific app. The framework doesn’t know which specific classes to use, so you tell it. And then, in the code, at some point it comes down to doing an NSClassFromString(s) to get a class, and then instantiating an object. I want to do the same thing in Swift, but with additional criteria: I don’t want to have to mark the class an Objective-C class. I want to use pure Swift. I want to be able to use structs interchangeably with classes. Whether the thing is a class or a struct is a detail that’s private to the class or struct, and not something the general framework needs to know. I realize that this may seem marvelously unsafe to some people. But, in practice, it’s not. And it’s super-common. (And it’s not terribly different from working with Interface Builder, where you configure by typing in class names.) I’ll update this post with the answer. (I assume there is one.) * * * Update 10:05 am: @jckarter writes: Possible, but not implemented yet.

Posted by on 20 July 2015 | 11:39 am