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

Secret Projects Diary #3: Decision to Make

Both my secret-project apps are very dynamic. (They both even have plugin architectures, so that people besides me can extend the apps in significant ways.) The designs call for heavy reliance on protocols — protocols all over the damn place. Now I’m faced with a decision. Even though there are solutions to my earlier post regarding Swift and protocols, there are lots and lots of places that need solutions. And those solutions require more code than I was expecting to write. More code means more code to maintain and more places for bugs to hide. And those solutions don’t have — I hate to say it — the elegance of Objective-C. I was hoping that I could use protocols in Swift in much the same way I do in Objective-C. That is, just as Objective-C doesn’t care about the difference between id<Foo> and ConcreteFoo *, Swift wouldn’t care about the difference between Foo and ConcreteFoo. But that’s not the case. * * * I feel like a putz every time I write “I’m going to use Technology X!” and later write “No I’m not!” People tease me about it (which is fine). But I’m not a curmudgeon. I’d never call myself a graybeard (despite the actual gray that appears when I skip a day shaving). I like new things. Here’s the thing: I have a responsibility to choose the best tool for the job, knowing that the best tool is the best tool for me, at this time, on this specific job. And I like writing about these decisions, on the grounds that my actual circumstances will be different from yours but that it’s good exercise to follow along with other people’s engineering decisions. (Well, I certainly get a benefit from reading what other developers write, at least.) * * * Here’s one way to think about it: how much grief will I put myself through trying to get my protocol-heavy Swift code to work and make it good code and elegant? * * * Here’s another way to think about it. If Objective-C didn’t have the ability to treat id<Foo> and ConcreteFoo * in the same way, and suddenly Swift had that ability, would we be talking about how this feature is really, really cool? A game-changer? The best thing since type inference? I think so. So is it smart to cast aside Objective-C, which already has this (and other) wonderful features, just because it’s not the new thing? Except that it’s not just that Objective-C isn’t the new thing. It’s also not the future thing. Switching isn’t a matter of if but of when. And I want these apps to last a long time. * * * In the end, it took me writing it up to decide to stick with Swift. Expect more blog posts.

Posted by on 19 July 2015 | 6:21 pm

Solving Problems I Don’t Have, Except that I Do Have Them

I’m not sure if I’ve said it on my blog, but I’ve said it in person to other people: Swift’s type system solves a problem I don’t have. Example: if I make an NSArray, I know what’s in there, my code knows what’s in there, and I’ve never had a crash or other bug where the array contained something unexpected. Seriously. This isn’t that hard. Except that that’s not actually true. * * * There are two cases where that hasn’t been true, and they’re representative, I think. One is in JSON parsing: I’ve ended up with NSNull in an array or dictionary where I expected something else — and then I’ve sent it a message expecting it to be an NSString or whatever, and the app crashed. So that’s a thing: data from the outside world may be weird. That being said, Swift doesn’t necessarily help very much. Or maybe it does, but I’m not good enough at Swift yet to realize how it helps. Totally possible. But right now, for me, there’s always a point where I’m surprised to be forcing a cast and then looking around nervously to see if the atmosphere ignited. There’s a second case where I think it does help. I wrote a crashing bug in Objective-C (and fixed it moments later; it didn’t ship) where I expected everything in an NSArray to be of the same type, and it wasn’t true. The code was building a pull-down menu, and the zeroth item was an NSDictionary with a value for key @"name", and other items were of an object type that had a name property. Every object would respond to valueForKey:@"name" as expected — but not to obj.name. I didn’t realize what was going on at first, and Swift absolutely would have helped. Now — the original code wasn’t written by me, and I wouldn’t have done it that way, but it’s not necessarily wrong. Just different from my style. But it’s a fact of life that apps very often have more than one author, and sometimes many more than one, and with different styles. And they may be separated in time (the original author may not even be working on that app; they may not even be at the company any more). While Swift makes it harder to write type-related bugs — which is great — it also makes it harder, sometimes, to do what I want in a reasonable and simple way, which is not great. However, it improves with each release. And if there are trade-offs which make the choice of language a tie, the tie-breaker has to be the question: which technology is the future? (That presumes that the choice of language is a tie. It may or may not be. It differs with each person and each app, and it changes with every release of Swift.)

Posted by on 19 July 2015 | 2:29 pm

Secret Projects Diary #2: Swift 2.0 Protocols

Let’s say I’m writing an RSS reader. (This is the example I tend to use on my blog, for historical reasons, and shouldn’t be taken as indicative of anything.) Let’s say the RSS reader can have a mix of stand-alone feeds and feeds that are synced with FeedBin, Feedly, NewsBlur, etc. I might very well do this: Create a Feed protocol. Create classes for each different type of feed: LocalFeed, FeedBinFeed, FeedlyFeed, etc. Each one of these conforms to the Feed protocol. (Why? Because each syncing system is different, and rather than have a giant Feed class that can handle all the different types, it’s smarter to have a Feed protocol and then specific implementations for each different type of feed.) RSS readers tend to have folders too. But folders may have different rules, depending on the system: folders inside folders may or may not be allowed, for instance. So, similarly, I might do this: Create a Folder protocol. Create classes for each different type of folder: LocalFolder, FeedBinFolder, FeedlyFolder, etc. Each one of these conforms to the Folder protocol. The Folder protocol includes the following: var feeds: [Feed] {get} func addFeeds(feedsToAdd: [Feed]) Now, in a concrete implementation of addFeeds, I want to check that each feed isn’t already contained in the folder. func addFeeds(feedsToAdd: [Feed]) {   for oneFeed in feedsToAdd     if !feeds.contains(oneFeed) {       feeds += [oneFeed]   } } But I can’t: I get Cannot invoke 'contains' with an argument list of type '(Feed)'. Okay, I think — let’s just use a Set anyway. Probably should have been a Set all along. So I change the Folder protocol to make feeds a set: var feeds: Set<Feed> {get} And on that line I get an error: Type 'Feed' does not conform to protocol 'Hashable'. So I try to make the Feed protocol Equatable, and I can’t. (And it has to be Equatable to be Hashable.) * * * I believe in protocol-based programming. Big, big fan. But it’s here where I get frustrated. It occurs to me that I’m still new to Swift, and I’m trying to use Objective-C patterns. That’s fair and true. The Objective-C version of all of this is pretty natural, though. Given Feed and Folder protocols, I can do this: - (void)addFeeds:(NSArray *feedsToAdd) {   NSMutableArray *feedsArray = [self.feeds mutableCopy];   for (id<Feed> oneFeed in feedsToAdd) {     if (![feedsArray containsObject:oneFeed]) {       [feedsArray addObject:oneFeed];     }   }   self.feeds = [feedsArray copy]; } (A version where self.feeds is an NSSet is even simpler.) It occurs to me that there probably is an answer in Swift. But it probably means more code. Objective-C syntax may be more verbose, but the fact that I can treat id<Feed> as an object without having to stand on my head is important because, again, I’m a huge fan of protocol-based programming. (And I’m a huge fan of less code.) Let’s just say that I’m doing it wrong. What’s the right way to do this? * * * Aside: “Brent — if you love Objective-C so much, why don’t you marry it?” Here’s the deal: I’m 47 years old, and if I start ignoring new things, I’ll fall behind and won’t be able to catch up. When you’re 30 or even 40 you can safely ignore things for a while and catch up later. Later on it’s harder and time is shorter. So I’m learning Swift. And, by the way, I’m enjoying it. There’s so much to love. But sometimes I hit roadblocks and Swift’s type system feels like a straightjacket — and then I miss the elegance of my beloved Smalltalk-derived Objective-C. * * * Update 11:25 am: I created a playground showing my conundrum: RSSReaderExample.playground.zip. (May require Xcode 7 beta.)

Posted by on 19 July 2015 | 1:08 pm

The Liscio Approach to Variants in Swift

In two recent posts — see how we keep calm and carry on? We’re back to tech topics — I wrote about implementing variants in Swift 2.0. (See Swift question: Enum vs. Struct for Variants and, before that one, Swift Protocols Question.) In both cases I was definitely thinking like an Objective-C programmer — I was thinking about how to wrap native types in a variant type. One approach was to use an enum with associated types, which is much like using tagged unions in C. Another approach was to create a different struct for each under-the-hood value type and have them all conform to a Value protocol. Chris Liscio — Capo author (Capo is genius, FYI) — suggested another approach: Don’t wrap. Don’t box. Just use the native types directly. That is, instead of creating something like this… protocol Value {   func valueBySmashingOtherValue​(value: Value) -> Value } BoolValue : Value {   let value: Bool   func valueBySmashingOtherValue​(value: Value) -> Value {     // do something and return a Value   } } IntValue : Value {   let value: Int   func valueBySmashingOtherValue​(value: Value) -> Value {     // do something and return a Value   } } etc. …do this instead: protocol Value {   func valueBySmashingOtherValue​(value: Value) -> Value } extension Bool : Value {   func valueBySmashingOtherValue​(value: Value) -> Value {     // do something and return a Value   } } extension Int : Value {   func valueBySmashingOtherValue​(value: Value) -> Value {     // do something and return a Value   } } etc. That is, extend the native types instead of wrapping them. In Objective-C you can’t extend BOOL or NSInteger since they’re not object types, but in Swift you can extend Bool and Int and similar types. At my stage in learning Swift I wouldn’t have thought of this — but Chris did. (Thanks, Chris!) (The advantages of this approach are, I hope, self-evident.) PS The code above hasn’t been checked to see if it compiles. (Written directly in MarsEdit.) But you get the idea. PPS I am frequently tempted to write that Objective-C is my lightsaber. But I don’t think that’s fair. I think it’s more that I’m still learning how Swift can be elegant — and Chris’s approach here counts as an instance of elegance.

Posted by on 4 July 2015 | 7:39 pm

Curtis Love

Curtis Herbert, Tough Love: Instead of looking inwards at a lack of success I think we would be better served looking outside our community. If we look externally we’ll see that the App Store isn’t full of doom-and-gloom bad for indies, but rather markets at large are stacked against indies. Absolutely right. I’d add, though, that each market has a shape, and the shape of the iOS App Store is in Apple’s control. They can’t control the behavior of people, but the shape of the market has an impact. I’d also add that a high volume of high-quality, interesting apps is good for selling iPhones and iPads. Are there things Apple could do that would make the iOS App Store better for indies, so that we’re not rejecting iOS app ideas out-of-hand? I think so. There’s no silver bullet, but there are numerous good ideas that, taken together, could make a significant difference. It’s still going to be tough for indies — there’s no way out of having to design well, work hard, and market effectively, and we wouldn’t want a way out; we like it tough — but every inch of lowered risk and every dollar of greater reward makes a difference.

Posted by on 1 July 2015 | 11:43 am

So Much Love

Allen Pike, The Supply-side Blues: However, when expressing frustration with the current economics of the App Store, we need to consider the effect of this mass supply of enthusiastic, creative developers. As it gets ever easier to write apps, and we’re more able to express our creativity by building apps, the market suffers more from the economic problems of other creative fields.

Posted by on 1 July 2015 | 10:57 am

Love

At the Cyclops the other night I was talking with fellow Mac and iOS developers. One person mentioned that a friend had acquired an iOS game — a good game that’s less popular than it deserves, that maybe just needs some marketing. Person: “So here’s the question. Would my friend’s iOS app be successful if…” Everyone else at the table: “No!” We didn’t wait for the “if” clause, because there’s nothing that could be in it that would matter. That’s not to say that there aren’t successful iOS apps. Of course there are. I know people who work on them. I work with people who work on them. But the odds are so very long. Do we still talk about new apps and recommend apps to people? Hardly, these days. * * * Well, that’s freaking dark, and I guess I did say it out loud. Hello despair: …there’s nothing that could be in it that would matter. Okay. I feel responsible for letting you out of this post a bit more nicely. Despair isn’t my style. * * * If I estimate the number of iOS apps in the App Store, and get the difference between the estimate and the actual number, that difference will be larger than the number of successful apps. (I define successful as a good-faith “makes enough of a profit to make it worth continuing to work on the app.” Most apps fail to make a profit at all, of course.) I haven’t done an actual study. But do any developers doubt that I’m right? And when developers think this way, they take their app ideas and toss ’em aside. “Hey, you know what, this idea would be really great for iPad! Darn.” “This would be perfect for iPhone! Oh well.” Shrug. Whatareyagonnado? * * * Yes, there are strategies for making a living, and nobody’s entitled to anything. But it’s also true that the economics of a thing may be generally favorable or generally unfavorable — and the iOS App Store is, to understate the case, generally unfavorable. Indies don’t have a fighting chance. The platform is awesome. We love writing iOS apps. It’s fun and massively rewarding in every way except monetarily. As a craft — as a budding art form, perhaps — it’s juicy. * * * You might think that development needs to get easier in order to make writing apps economically viable. The problem is that we’ve seen what happens when development gets easier — we get a million apps on the iOS App Store. The easier development gets, the more apps we see. And, the easier development gets, the more is expected of the apps you write, and the less people will pay. You probably have to do syncing. You need a companion Apple Watch app. And so on. I kind of want to say that development needs to get harder — but what I really mean is that we need to solve harder problems in our app. Think of the difficulty level in things like Capo — do something actually very difficult like that, create a great UI and market the app well, and you may have a success. The problem, of course, is that you’re taking a big risk. Your odds may be better when you’re solving a truly difficult problem — but the investment in time is bigger. And that’s not a general solution to the economic problems of developing iOS apps. I don’t have one. Maybe there isn’t one. (Well, there’s Mac apps. Want a business? Write Mac apps. But that’s a closely-guarded secret, and I promised not to tell anyone. You didn’t hear it from me.) * * * This is the age of writing iOS apps for love. Well, that’s not true for everybody. Well-established and awesome companies such as Omni, Panic, Flexibits, AgileBits, Tapbots, and The Iconfactory have a business writing iOS apps. (They do it for love, but not just for love.) Companies like Black Pixel make money by writing apps for other companies that have money. And big companies and funded companies don’t actually have to make money from their iOS apps. They have other goals. (I don’t pretend to understand the economics of funded companies.) You the indie developer could become the next Flexibits. Could. But almost certainly not. Okay — not. What’s more likely is that you’ll find yourself working on a Mobile Experience for a Big National Brand(tm) and doing the apps you want to write in your spare time. If there’s a way out of despair, it’s in changing our expectations. Write the apps you want to write in your free time and out of love for the platform and for those specific apps. Take risks. Make those apps interesting and different. Don’t play it safe. If you’re not expecting money, you have nothing to lose. Could the do-it-for-love era — with the creative freedom that that brings — bring us back to the days when we downloaded apps that weren’t from Facebook and Starbucks and Funded Company X, and we told our friends about our exciting finds? I hope. I have hope.

Posted by on 30 June 2015 | 12:02 pm

Swift question: Enum vs. Struct for Variants

In a previous post I mentioned using structs plus a protocol to implement a variant type. There’s a Value protocol and a number of different structs that conform to that protocol. But Andy Matuschak’s comment about using an enum instead keeps coming to mind. And then there’s this note in the pre-release Swift book: Alternatively, enumeration members can specify associated values of any type to be stored along with each different member value, much as unions or variants do in other languages. So let’s imagine a variant that can represent a bunch of different data types and that has logic for arithmetic operations and for coercions. enum Value {   case variantBool(Bool)   case variantInt(Int)   case variantString(String)   etc. — for doubles, dates, data, collections, and so on } (Forgive the “variant” prefix in this example — it’s there so I’m not writing case Bool(Bool) and so on.) Now let’s say we have a bunch of logic. func canAddValue(value: Value) -> Bool func valueByAddingValue​(value: Value) -> Value And so on for subtracting, multiplying, and dividing. (Example: variantStrings can add and subtract other variantStrings and things that can be coerced to variantStrings, but they can’t multiply or divide. variantData can’t do any arithmetic at all. Etc.) And then add logic for coercions: func canCoerceToType​(type: Value) -> Bool func valueByCoercingToType​(type: Value) -> Value (This is a little weird because a Value is a type — variantBool, variantInt, etc. — as well as data.) There’s a whole ton of logic there: a variantDate can be coerced to a variantDouble but not to a variantArray, etc. Unless I’m missing something — which is highly likely, as I’m just barely starting — I’ve got a whole ton of switch statement to write. And those switch statements have inner switch statements. (Conceptually, that is. Of course I would break things out into separate functions, as in func variantBool​CanCoerceToType​(type: Value) -> Bool and so on.) That seems a lot to me like writing C code with tagged unions. Which is not necessarily a bad thing — I grew up on C and and still love programming in C (though I don’t get much chance to do it these days). My original idea — a Value protocol plus a bunch of structs conforming to Value, one for each type — is something an Objective-C developer who’s new to Swift would come up with. I realize it’s still early to ask about idiomatic Swift and best practices, but I’m asking anyway. What would you do?

Posted by on 23 June 2015 | 9:33 pm

Varieties of News Readers

I think — provisionally — that there are three types of news readers. (Am I missing any?) 1. Casual Newspaper This category includes Flipboard, Zite (sadly defunct), the upcoming Apple News, and others. These tend to have the richest user interfaces of all news readers, with lots of pictures, animations, and interesting layouts. Typically you pick some categories that interest you and perhaps some sites. You may also add RSS feeds and you might have it pull links from your Twitter and Facebook feeds. These tend to have significant server backends that not only read various feeds and sites but also assemble (via algorithms and curation) a set of articles personalized for each user. These are casual because, as with an actual newspaper, there’s no expectation that you’ll read everything. These tend not to have unread counts, for instance. 2. Productivity App This category includes apps like Reeder, NetNewsWire, Google Reader (now gone), Feedly, Fever, and others. Their user interface often resembles a Usenet reader or email app. These apps often have things like unread counts and power-user features such as extensive keyboard shortcuts. These tend to be RSS readers specifically, though not necessarily entirely so. They don’t always do anything about relevance or personalization — personalization is entirely in the hands of the user, who picks which feeds to read. Some do include relevance features, but in general these apps are for people who want the control in their own hands, who don’t trust algorithms or curators, who don’t want to miss something that might be important. There are two subcategories of productivity apps: browser-based server apps and native apps. Interestingly, the native apps often provide syncing by connecting to a server app (which may be made by a developer who’s not the same as the native-app developer). 3. River of News These are reverse-chronological streams with optional titles and a short amount of text — often just a summary or excerpt of the linked-to story. (See Dave Winer on What is a River of News aggregator?) These are also somewhat casual in that there are generally no unread counts and there’s no pressure to read everything. You read by scrolling, and you scroll as far as you want to. There are two subcategories: RSS (or RSS mostly) and social network feeds. Twitter and Facebook could both be considered news rivers. (The RSS variety came first by many years, of course.) Rivers sometimes have relevance algorithms behind them — as with Facebook, for instance — and sometimes not. They may be stand-alone, without any form of syncing, or they might have giant server back-ends — or something in between.

Posted by on 23 June 2015 | 3:26 pm

Swift Protocols Question

I’m still very much a Swift newbie. The following example is contrived, but it accurately depicts the problem I’m trying to solve. I have a protocol: protocol Value: Equatable A number of different structs conform to this protocol. Some of those structs also conform to this protocol: protocol Smashable {   func valueBySmashing​OtherValue​(value: Value) -> Value } My intent is absolutely clear — valueBySmashingOtherValue must return an object that conforms to the Value protocol. However, I get this error: Protocol 'Value' can only be used as a generic constraint because it has Self or associated type requirements. Okay. So I revise the Smashable protocol like this: protocol Smashable {   func valueBySmashing​OtherValue​<T>(value: T) -> T } That compiles. Cool. So in a struct named Foo I add this: func valueBySmashing​OtherValue​<T>(value: T) -> T {   return Bar() } That’s right — Foo’s ​valueBy​Smashing​OtherValue returns a Bar. (Yes, this is contrived, but it distills the more-complex real-world code, which makes sense and is absolutely the right thing to do.) Both conform to Value. But I get this error on the return Bar() line: 'Bar' is not convertible to 'T'. At this point I don’t know what to do. Hence this blog post. Objective-C version I approach Swift exactly like an Objective-C coder — because I’ve been writing Objective-C for almost 15 years. Here’s the Objective-C version: @protocol Value<NSObject> stuff @end @protocol Smashable<NSObject> - (id<Value>)valueBy​SmashingOtherValue:​(id<Value>)​otherValue; @end Foo method (Foo and Bar both conform to Value): - (id<Value>)valueBy​SmashingOtherValue:​(id<Value>)​otherValue {   return [[Bar alloc] init]; } One possibility I’m still thinking in Objective-C. It’s entirely likely that there’s a Swift-like design that hasn’t occurred to me. But what is it? One simple possibility: don’t use protocols at all. Make a Value struct that does everything the various Value-conforming structs currently do. The Value struct would be littered with switch statements, which is ugly (and is usually a sign of poor design), but it would work. This doesn’t seem Swift-like, though, given the importance of protocols to Swift. And I can’t make myself do it. There must be a better option. What I don’t want to do is complain, a la Nabokov, that this new language can’t match the suppleness of my native language. I’d rather assume it’s just that I haven’t learned this new language well enough. P.S. I’ll happily link to your blog post if you write up a solution. Update 10:30 am Monday June 22: Answers There are a bunch of replies on Twitter. The essence of the best answers was this: Value should not be Equatable — the individual structs should be Equatable. Brent Royal-Gordon: Thinking more, the problem is Equatable. Remove or abstract that conformance from Value and everything will work right. For more details, see David Owens II’s blog post: …there is a way out of this if your situation allows for it: don’t conform your protocol to Equatable, instead, conform your types to it. And Llamagraphics’s blog post: The error message says Protocol ‘Value’ can only be used as a generic constraint because it has Self or associated type requirements. This is a little misleading, because it implies that valueBySmashingOtherValue needs to be rewritten as a generic function, but that actually just pushes the problem down to the adopters of the Value protocol. The real fix is to move the use of the Equatable protocol from the Value protocol to the individual struct declarations… And see Andy Matuschak’s gist — which makes an interesting point that I had briefly considered and then dropped: One note before we start: if the inhabitants of Value are a closed set, then making Value an enum is going to be a clearer model than using a protocol like this. I'm assuming you need to be able to retroactively add new members of Value. In my case, the inhabitants of Value are a closed set. There are about a dozen. What concerned me, though, is that I’d be creating a monster enum with a whole bunch of switch statements. But perhaps that’s not true? I don’t know Swift well enough to think it out in advance — I’d have to try it and see. (Actually, I may be misunderstanding Andy. There are a dozen Value types — but the values are unbounded. Perhaps not a great case for an enum.) Ramble In the end, I’m still tempted to say the Objective-C version was simpler. And it is, and not just because I’m more familiar with Objective-C. But it’s important to note that it’s not apples-to-apples. In Objective-C I’m creating classes instead of structs, and there’s no support for the == operator. But I will say this: Objective-C, because it’s less strict with types, is closer to a scripting language than Swift is. I know that that could be controversial, and seems absurd when you consider that Objective-C is a superset of C, which is pretty darn far from a scripting language. But Objective-C as-we-mostly-write-it doesn’t include much straight C code. That’s not a value judgment but a characterization. There is a place for strict, less-strict, and not-strict-at-all languages — they all have their uses. But when I imagined Apple’s next-generation language, I imagined a higher-level and less strict language — one that made it easier to get started as a developer, one that got rid of a bunch of the housekeeping we have to do as Objective-C developers. Though Swift does get rid of a bunch of housekeeping — we can use type inference much of the time, we don’t have to create .h files, etc. — it adds its own housekeeping mandated by a stricter type system (and optionals). When I think about how much of our apps is user interface code — which is often rather boring to write and is just stuff like setting a label, animating a property, pushing a view controller, and so on — I wonder why we’re not using an actual scripting language. It wouldn’t have to be for all of a given app — not for the performance-sensitive parts — but it would be great for all the stuff that’s just pushing user interface APIs around.

Posted by on 21 June 2015 | 12:55 pm

More About http Deprecation

Dave Winer writes about http deprecation in The People’s Browser. And I’ve thought more about it in the context of writing Mac and iOS apps. Let’s consider a few apps I’ve worked on in my career: NetNewsWire: an RSS reader that connects to any site with an RSS feed, no matter how that feed is served (http or https). MarsEdit: a blog editor that connects to any blog with an external API, no matter how that API is served (http or https). Glassboard: a private group messaging system. Of these, only Glassboard would fit in an https-only world. Since we controlled the server, and since privacy and security were hugely important, requiring https would be no problem. (And of course we did use https.) The problem is the other two apps. They all rely on the open web rather than servers controlled by the app writer. And it would be unacceptable to limit those apps to https only. Let’s also consider my two secret-project Mac apps. Both of them need http access — they’re not limited to servers that I (or some corporation) control. Since neither app will be sandboxed, I’ll be able to do this without Apple’s approval. My concern, of course, is that this situation won’t last. (It already means that there couldn’t be iOS versions of my secret-project apps — at least not without Apple granting an exception, which may be temporary.) I’m totally on board with defeating the ability of the NSA and your internet provider and everybody else from snooping. I hate this snooping business — it’s anti-American and it makes me sick to my stomach for the future. But I also know that the web isn’t going to switch to https quickly or completely. It’s expensive. To cut off http is to cut off the arms of the body of free speech.

Posted by on 15 June 2015 | 2:00 pm

Secret Projects Diary #1: Post-WWDC Notes

Note: This series — which will probably last a long time — is my attempt at writing about things without actually announcing what they are. I’ve decided I can eat this cake and still have it. The point is not to tease — though I realize that that’s a side effect, and I apologize in advance. (It’s not going to stop me from saving actual announcements until the software is ready, and it’s not going to stop me from writing in the meantime. Because writing helps me think, and it’s fun.) Swift I started working on my apps a few months ago, and there was no question at the time that I should use Objective-C. But now with Swift 2 I wonder if it’s time to switch. The new Swift goes a long way toward curing angle-bracket blindness. But, more importantly, now we know what Swift will be once it grows up (and it’s growing up fast) — and that thing, a protocol-centered language, is a thing I want. (The most important session of this year’s WWDC was Protocol-Oriented Programming in Swift. It’s a peek into how we’re going to be writing software for the next decade and more. For the rest of my career.) I haven’t written much UI code yet. Almost everything so far has been data transformations — isolatable things that run outside the main thread, things that could benefit from Swift structs and enums rather than the collection of classes that I’m currently using. Objective-C is a living language, but Swift is the safer bet for the long term. And I want my apps to last a very long time. I’m torn between wanting to make forward progress and wanting to port the code so far. I haven’t decided yet. I might do these things concurrently. OS X 10.11 and Auto Layout My apps will both require 10.11. That was never in doubt. One of the interesting changes is that AppKit (with split views, particularly) has more of a concept of a sidebars and content lists. And there are some new behaviors, such as automatically hiding a sidebar and showing it as an overlay, that we get if adopt the new APIs. At least one of my apps (and possibly both; undecided for now) will have a sidebar. But I wasn’t planning on using Auto Layout because I’ve had problems with performance, bugs (in NSToolbar), debugging, and with actually getting things to work the way I want. (I have not been able to replicate Mail’s splitview handling using NSSplitViewController, for example, but I can replicate it if I go the old-fashioned route.) Auto Layout solves a problem I don’t have. I’ve been writing manual layout code for so long that I barely even have to think about it. It’s easy. While I understand the benefits of declaring (as opposed to coding) layout, those benefits disappear when things go wrong and when I can’t do the thing I want to do. But this leads to a dilemma. Doing things the old-fashioned way means manually writing sidebars-that-overlay (and so on) and nailing the behavior perfectly and revising it every time the behavior changes. If I use Auto Layout instead, I get the behavior, and any changes to that behavior — but I also get an unknown set (of unknown size) of struggles and frustrations. If it’s a tie, then the winner is the future-proof answer. Which is Auto Layout. NSStackView Stack views in 10.10 are slow. (I can point to multiple performance issues in shipping apps that are a result of stack views.) Word on the street is that they’re much-improved in 10.11 — which is great. If that’s true, then I want to use them. There are lots of cases where a stack view is the best answer to a layout problem, and so I suspect there will be plenty of stack views in my apps. (As long as they truly are faster now. I haven’t checked yet.) http deprecation This one worries me a little, and I need to find out more. Since neither of my apps will be sandboxed, it may not be an issue. But it’s a larger issue in the industry and is bound to have an impact on what I do sooner or later. What upsets me about this issue in general is that it’s anti-democratic: it can make writing for the web more expensive and difficult for individuals. As a writer, reader, and open web partisan I dislike everything that shifts power away from people and toward entities with greater resources. What you end up with is corporate speech rather than the voices we know and love and need to hear. This is a complex situation, though. I strongly believe in the right to privacy, and that encryption should be used much more widely than it is today, and that no organizations, official or otherwise, should have back doors. Well. Anyway. More research and thought required on this one.

Posted by on 14 June 2015 | 3:37 pm

How Not to Crash Series Finished

All done. (At least I think so — I might think of more things, I suppose.) There’s a new page that links to all the posts. There’s a link to it at the bottom of every page on this site.

Posted by on 10 June 2015 | 6:20 pm

How Not to Crash #9: Mindset

You know the old line about not writing code that’s as clever as you are, because it will take someone even smarter than you to debug it? I used to think that means I should write code that’s about 80% as clever as I am. Save a little bit for debugging. But over the years I’ve come to think that I should write code that’s about 10% as clever as I am. And I’ve come to believe that true cleverness is in making code so clear and obvious that it looks like nothing at all. And that’s why I have rules like do everything on the main thread except for perfectly isolatable things and avoid unsafe_unretained always and so on. This means I don’t get bonus points for being a code magician. I don’t pull rabbits out of hats and I certainly don’t walk tightropes. I won’t even look at tightropes. I do difficult things as needed, but the goal even with the difficult things is to write the simplest and most-readable code that I can. If, in the end, the code looks easy — unimpressive, even, as if a middle-school kid could have written it — then good. In the small, this means that methods tend to be small and focused with little nesting. In the large, architecture and naming is iterated-over until it feels inevitable, as if no thought went into it because it all must have been obvious. It means not getting too abstract. Explicitness is obviousness. But it also means not getting too non-general, either — there are times when two or three things are really the same thing, and they can be generalized without harming maintainability. (And there are times when they can’t.) I avoid tight coupling and large structures — except for when the best solution really is for x to know about y. And I keep learning and getting better. Time The thing that separates programming from painting, writing, architecture, and composing music is that there is no finished product. There are released versions, yes, but there’s no finishing, there’s only abandoning. Code exists in time, and maybe across many people — and you don’t even know how long or who. This should never be out of your mind. Cape, mask When I was younger I wanted to be a code magician — or, really, a hero. But I learned that actual software quality is more important than what I imagine other people think of me. And, more: quality is a reward that’s almost spiritual. It’s an act of devotion, both selfish and unselfish, to something more important than ego. Selfish because the process of striving for quality makes you a better person. And unselfish because better code and better software is better for other people. And the first thing other people ask of your software is that, if they launch it, it stays launched. Any programmer who can’t bring themselves to care about that — or who rationalizes away crashing as a fact of life these days — isn’t taking this great fun we are privileged to have seriously enough.

Posted by on 10 June 2015 | 6:05 pm