movq

Wherein I Move a Lot of Words Around

Sunsetting

Michael Tsai has a great collection of quotes about Apple's sunsetting practices. As quoting a list of quotes is a bit meta, go read it.

On 168 Hour Workweeks

Ron Conway’s Advice for Young Founders at YC’s Startup School (via Sci-Fi Hi-Fi):

"But [angel investor Ron Conway] took a turn for the serious, warning the enthusiastic crowd that “you have to be willing to work 24/7.” He then went a step further, solemnly claiming, “Dating someone or married: warn them that they’re not first in line, that you have this vocation, that your duty is to your company. It has to be that fanatical.”

There are two kinds of businesspeople: those that want to build a small company that becomes a large company, and those that want to build a company as fast as they can without regard for living life. The above advice falls into the latter.

Yes, technology is moving quickly. Yes, everyone else is building your idea. And yes, many of those building your idea are working insane hours and telling the rest of the world they don't matter as they do it. That doesn't mean you have to do it, too. It just means that if you're choosing the sane route, the 40-50h a week route, that you need to plan your slow takeover more carefully than they're planning their surge. You need to plan for the war, not for the battle. And you need to plan for the war understanding that you're going to lose the first battle, but that after that loss the enemy will have a period where they have nothing — nothing at all — to fight with for a period of time as they juggle hiring, VCs, tech news, bugs, lawsuits (inevitable), and other things they didn't think of when rushing their solution to market faster than they should have.

You consider those things. Be ready for those things. Then release when they're weak and keep moving.

Cycloramic is Not Doomed After All

This App Avoided Being Made Useless By Using The iPhone’s Charger (But Not For Charging):

But wait! The iPhone 6 has round edges. It can’t stand upright on its own. Cycloramic is doomed, right?

Clever. Very clever.

Can Nadella Save Microsoft?

Can C.E.O. Satya Nadella Save Microsoft? | Vanity Fair:

There’s a sense in the world outside Redmond, Washington, that Microsoft’s best days are behind it, that the sprawling colossus, which employs more than 100,000 people, doesn’t know what it is, or even what it wants to be. Gates and Nadella are adamant that’s not the case, and they are both adept at the sort of big-picture corporate-speak designed to persuade people that the company not only has its act together but also has a vision. In their view, this new world of unlimited computing power, where your devices can connect you anytime, anywhere, should rightfully belong to Microsoft. They even have a catchphrase: “Re-inventing productivity.”

Count me in the former group.

Ping

The Story of the PING Program:

I quickly coded up the PING program, which revolved around opening an ICMP style SOCK_RAW AF_INET Berkeley-style socket(). The code compiled just fine, but it didn't work -- there was no kernel support for raw ICMP sockets! Incensed, I coded up the kernel support and had everything working well before sunrise. Not surprisingly, Chuck Kennedy (aka "Kermit") had found and fixed the network hardware before I was able to launch my very first "ping" packet. But I've used it a few times since then. *grin* If I'd known then that it would be my most famous accomplishment in life, I might have worked on it another day or two and added some more options.

GT to close sapphire plant and sever ties with Apple

GT to close sapphire plant and sever ties with Apple:

Rumor had it that the then-forthcoming iPhone 6 would use sapphire or sapphire-coated glass to protect their displays from scratches, and it sent GT’s stock climbing. On September 9, Apple announced new iPhones with “ion-strengthened glass,” not sapphire. This sent GT’s stock sliding downward.

Lovely.

Core Data and Data Protection

A project I’m working on needed to secure the Core Data database on-disk in iOS (the nature of the content demanded it). When asked about this I instinctively said, “Sure! iOS has data protection APIs that easily allow that!”

I should stop answering so quickly.

Yes, there are APIs for that. The ones you’ll find mentioned all around the Internet are the additions to NSData and NSFileManager that let you use the NSFileProtectionKey attribute and set the protection class of the file and — MAGIC! — the file is encrypted and the keys are managed for you. The very first thing I did, then, was to naively write:

if (![[NSFileManager defaultManager]
    setAttributes:@{NSFileProtectionKey:NSFileProtectionComplete}
     ofItemAtPath:[storeURL path]
            error:&error]) {
    NSLog(@"Failed to set file protection attribute: %@", error);
    abort();
}

Well, it ran and didn’t throw an error. That’s good. I then locked the device and had Xcode copy the sandbox out and then I looked inside the Documents folder. As expected, there was no SQLite file inside. However, there were two other files inside I wasn’t expecting.

AppData
    Documents
        File_Protection.sqlite-shm
        File_Protection.sqlite-wal

sigh

Of course.

I set the protection attribute on the Documents directory itself, mostly to say I tried it (it didn’t work, of course). While I could test for the files and set the attribute on them at various key moments, that was hacky and not how you do security. Another answer was required.

After an hour of searching around the Internet, blog posts, presentations, and — gasp — the Apple Developer Forums (I was desperate) I came upon the WWDC 2012 video for session 214: “Protecting the User’s Data”. On a slide halfway in there was a list of APIs that offered protection options for files and I saw two that weren’t listed anywhere else I’d found: sqlite3 and Core Data.

Light. Bulb.

I turned to the NSPersistentStoreCoordinator docs and to the options when creating the store itself and found the magic. If you pass in @{NSPersistentStoreFileProtectionKey:NSFileProtectionComplete} to the options: parameter of addPersistentStoreWithType: then Core Data will open the SQLite database with the SQLITE_OPEN_FILEPROTECTION_COMPLETE flag and then everything should be glorious.

So, I set that property, put the app on my phone, locked it, and then pulled the container again. Hmm.

AppData
    Documents
        File_Protection.sqlite-shm

That’s more promising, as the WAL (write-ahead log) has user data in it. But what is this SHM file and why was it excluded? The SQLite site had the answer. It’s a shared memory file used as an index into the WAL file. I opened it up in Hex Fiend and after a file header the rest of the file was filled with NUL characters, so it seems safe. The SQLite documentation assures us that it contains no persistent content. So, barring SQLite bugs, that’s probably fine.

Mixed Objects in Swift Collections

At first the idea that a collection in Swift could only be one kind of object bothered me, but I’m slowly seeing a useful pattern emerging from this — one that Obj-C made tedious due to its grafting of an pass-by-reference-only object pattern on top of another language.

In the specific case that I just solved, for example, I have a table controller with a static list of choices and actions that would be performed when clicked. In Obj-C I’d probably do something like:

NSArray *choices = @[
    @{ @"name": @"Item 1", @"image": imageForItem1, @"action": @"action1" },
    …
];

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    …
    NSDictionary *choice = _choices[indexPath.item];
    [self performSelector:NSSelectorFromString(choice[@"action"])];
    …
}

… or something equally unsafe outside very specific parameters.

Swift, however, makes that a bit more difficult in a lot of ways. However, when writing in Swift it’s temping to do it in “The Swift Way” as well (namely so I can stop writing question marks and wrapping code in conditional optional statements). Therefore I wound up with something more like:

enum MenuAction : Int {
    case Action1
    case Action2
    case Action3
}

struct MenuChoice {
    var name : String
    var image : UIImage
    var action : MenuAction
}

let choices : [MenuChoices] {
    MenuChoice(name: "Action 1", image: imageForAction1, action: .Action1),
    …
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let choice = choices[indexPath.item]
    switch choice.action {
    case .Action1:
        action1()
    case .Action2:
        action2()
        …
    }
}

It’s certainly more safe. It’s quite a bit more verbose and explicit, but those are also the things that make it more safe. Could it be done in Obj-C like this? Mostly, yes. However, you can’t shove a struct into an NSArray and declaring one-off classes for such things is a bit tedious. Compare the above Swift to the following Obj-C syntax:

typedef NS_ENUM(NSUInteger, MenuAction) {
    MenuActionAction1,
    MenuActionAction2,
    MenuActionAction3,
};

@interface MenuChoice : NSObject
@property (nonatomic) NSString *name;
@property (nonatomic) UIImage *image;
@property (nonatomic) MenuAction action;
@end

@implementation MenuChoice
@end

First, there’s the Foundation macro NS_ENUM to deal with. You have to use this one if you want your enum to work in Swift as well as Obj-C. Then there’s the ever-present nonatomic keyword for properties, and then the repetitive @property itself.

Notice that MenuAction, being an NSUInteger, doesn’t get the * to say it’s a pointer. You’ll have to catch that every time you pull this trick, and you’ll get it wrong at least once.

Lastly, there’s the empty implementation to trigger the generation of the properties.

It’s kind of messy, no? Compare, again, to Swift’s version:

enum MenuAction : Int {
    case Action1
    case Action2
    case Action3
}

struct MenuChoice {
    var name : String
    var image : UIImage
    var action : MenuAction
}

Much cleaner, and it does the same thing. Exactly the same thing. Mostly the same thing. There’s one hidden feature of the Swift version: there will not be a nil for any of those properties of MenuChoice. If the struct exists, there will be a valid value inside.

I’m not sure how sold I am on Swift for a lot of things — the loss of dynamism means a lot of things are now less possible — but there are certainly places where it brings a lot of sanity, and that much I do like. I’m still writing about 50/50 between the two languages, but for a language to get to 50% this fast is noteworthy.

Cathode

Cathode is a fully customizable terminal app with a look inspired by classic computers. Don’t let the playful exterior fool you; under the hood there’s an advanced emulator designed for serious work. Whether you prefer crisp, clean text, or a flickering, glowing mess, Cathode is the perfect tool for hacking in style.

This thing is gorgeous, and highly usable.
Cathode

How to Remove the Podcasts app in iOS 8

Thanks, Restrictions! Can we block the Tips app, too? THINK OF THE CHILDREN!