Monday, August 25, 2014

The Swift Wish List

Christoffer Lernö has a good list of suggested changes, although I’m not sure I agree with the last one about optional dispatch.

FastCoding

Nick Lockwood:

FastCoder is a high-performance binary serialization format for Cocoa objects and object graphs. It is intended as a replacement for NSPropertyList, NSJSONSerializer, NSKeyedArchiver/Unarchiver and Core Data.

The design goals of the FastCoder library are to be fast, flexible and secure.

FastCoder is already faster (on average) for reading than any of the built-in serialization mechanisms in Cocoa, and is faster for writing than any mechanism except for JSON (which doesn't support arbitrary object types). File size is smaller than NSKeyedArchiver, and comparable to the other methods.

This is potentially very useful because NSArchiver is essentially deprecated and NSKeyedArchiver is much slower and produces larger files. Binary property lists are decently fast but don’t support objects or references.

The API looks nice, except that I wish it used NSError rather than exceptions. It’s compatible with ARC, but he recommends compiling with -fno-objc-arc for better performance. This, despite lots of __unsafe_unretained annotations in the code.

Building 3D With IKEA

Kirsty Parkin:

Every year, CGSociety goes to SIGGRAPH, one of the premier conferences on innovation for the computer graphics and VFX industries in the world. In 2012, we watched as Martin Enthed, the IT Manager for the in-house communication agency of IKEA, gave a short presentation. He told us how their visualisation team had evolved from the use of traditional photography for the IKEA catalogue to a system today, where the bulk of its imagery is CG. I remember leaving the auditorium (which was packed) thinking, “Those natural-looking photographs in the IKEA catalogues are amazing. I can’t believe they’re mostly CG. It’s incredible.” It was such a great presentation that we went and saw it again in 2013 when it was an official talk, and figured you guys might like to know how IKEA did it - what they had to build and innovate to get their still images to look so real. So we made a time to catch up with Martin, and asked him how and why IKEA decided to make the leap from traditional to digital.

Sunday, August 24, 2014

objc.io on Testing

Issue #15 of objc.io is all about testing. It’s really good.

Pawel Dudek:

This is where behavior-driven development (BDD) comes it. It aims at solving these exact issues by helping developers determine what should be tested. Moreover, it provides a DSL that encourages developers to clarify their requirements, and it introduces an ubiquitous language that helps you to easily understand what the purpose of a test is.

Maybe I’m just not used to it, but I find it difficult to read BDD-style tests. There’s too much seemingly unnecessary DSL and the attendant block syntax.

Arne Schroppe and Daniel Eggert:

We structure our tests by using the Given-When-Then pattern—every test is split into three parts.

The given section sets up the environment for the test by creating model objects or bringing the system under test to a certain state. The when section contains the code we want to test. In most cases, this is only one method call. In the then section, we check the result of our action: Did we get the desired output? Was the object changed? This section consists mainly of assertions.

[…]

This makes using mocks even more convenient. We can specify that a mock should be verified right at the point where we create that mock[…]

[…]

[We] added a new dispatchGroup property to all managed object contexts. We then exclusively used -performGroupedBlock: in all our code.

With this, we could wait for all asynchronous work to be done inside our tearDown method[…]

Jon Reid:

It may look odd to inject NSUserDefaults, and that’s where this example may fall short. Remember, NSUserDefaults is standing in for a dependency that creates trouble. It would make more sense for the injected value to be an abstraction (that is, an id satisfying some protocol) instead of a concrete object. But I’m not going to discuss that in this article; let’s keep going with NSUserDefaults for our examples.

[…]

We have five different forms of [dependency injection]. Each comes with its own set of pros and cons, so each has its place.

[…]

My advice for folks starting off with mock objects is to avoid using any mock object framework, at first, as you’ll have a better sense of what’s going on. My advice for folks starting off with DI is the same. But you can get even further in DI without a framework, relying solely on ‘Poor Man’s DI,’ where you do it yourself.

Luis Solano:

Private means private. Period. If you feel the need to test a private method, there is something conceptually wrong with that method. Usually it is doing too much to be a private method, which in turn violates the Single Responsibility Principle.

[…]

What To Do: Extract that private method to a separate class, give that class a properly defined contract, and test it separately. When testing code that relies on this new class, you can provide a test double of that class if needed.

Mike Lazer-Walker:

Naturally, it’s not like these are two rival schools of programmers; you’d be hard-pressed to see a mockist and a statist dueling it out on the street. This dichotomy is useful, though, in terms of recognizing that there are times when mocks are and are not the most appropriate tools in your tool belt. Different kinds of tests are useful for different tasks, and the most effective test suites will tend to have a blend of different testing styles. Thinking about what you are trying to accomplish with an individual test can help you figure out the best approach to take, and whether or not fake test objects might be the right tool for the job.

[…]

Many experienced testers warn that you “shouldn’t mock what you don’t own,” meaning that you should only create mocks or stubs of objects that are part of your codebase itself, rather than third-party dependencies or libraries. There are two main reasons for this, one practical and one more philosophical.

Klaas Pieter Annema:

Regardless of your method of testing, when testing user behavior, you want to stay as close to the user as possible. You want to make it appear to your code as if the user is interacting with it. Imagine the user is looking at a view controller, and then taps a button, which presents a new view controller. You’ll want your test to present the initial view controller, tap the button, and verify that the new view controller was presented.

By focusing on exercising your code as if the user had interacted with your app, you verify multiple things at once. Most importantly, you verify the expected behavior. As a side effect, you’re also simultaneously testing that controls are initialized and their actions set.

Orta Therox:

FBSnapShotTestCase takes a UIView or CALayer subclass and renders it to a UIImage. This snapshot is used to create tests that compare a saved snapshot of the view/layer and the version generated by your test. When it fails, it will create a reference image of the failed test, and another image to show the difference of the two.

What’s a Twitter Timeline?

Dan Frommer:

Many Twitter users have noticed that Twitter is now inserting tweets into their timelines that seemingly don’t belong. This is not an accident. Twitter has updated its help document, “What’s a Twitter timeline?

Scott Rosenberg:

The latest change is that the “favorite” — a tool most users rely on either to bookmark links they want to return to or to send a little head-nod of acknowledgment out to the tweet’s creator — is being put to use in a new way. Twitter is experimenting with showing you tweets from users you do not follow if those tweets are favorited by lots of other users (presumably, a lot of other users who you follow).

John Gruber:

So far, these changes are only evident when using Twitter’s first-party clients, but it’s a bad sign even if you use a third-party client like Tweetbot or Twitterrific. However, tweets that you favorite using a third-party client might start showing up in the timelines of your followers who do use Twitter’s own interfaces.

Update (2014-08-25): Jesper:

The reason I don’t like social media is that it takes two things that are polar opposites and duct tapes them together. Your own utility – to save links, to write text, to move files or materials, to keep notes, to communicate with yourself in the future, to communicate with some other specific people – and the social media outlet’s desire to fulfil its own objectives first.

[…]

When Twitter thinks it’ll improve everyone’s lives by inserting appropriate favorites, I don’t think they’re making that decision primarily for the filthy lucre. They’re doing it, in their minds, to make Twitter a better place to be in. The problem is that no one at Twitter seems to see that (or at least win any arguments about) nearly everyone else in this equation thinks it’s a worse result.

An Aperture User Tries Lightroom

Josh Anon:

Given the unfortunate news about Apple not actively developing Aperture anymore, I decided to try Lightroom while shooting in Svalbard. I’m trying to figure out if I should keep using Aperture for the immediate future and wait for Photos to be more fleshed out or to switch to Lightroom now and not have to migrate even more photos later (I have terabytes of digital photos from 12+ years of shooting digital cameras and scans of slides about 20 years ago managed in Aperture).

He has a good list of irks. I looked into switching to Lightroom but found it much harder to get used to than I expected. There are so many things about Aperture that seem to make more sense.

Ode to Susan Kare’s Chicago

Alissa Walker (via John Gruber):

It was square, squat, and inherently cute. It was friendly. It was easy to use. I’m talking about the beige box with the blue grinning face that came to live with us in 1985. But I’m also talking about the font that came with it. It was the typeface Chicago that spelled out “Welcome to Macintosh,” ushering us into a new age of personal computing. But it was also a new age for digital type. Here was a typeface created explicitly for the Macintosh, part of designer Susan Kare’s strategy to customize everything from the characters to the icons — that happy computer, the wristwatch, an actual trashcan — to make it feel more human and less machine.

I liked Espy Sans better than Chicago’s replacement, Charcoal.

Yet Another Integer Underflow Bug

Nick Hamann (via David Smith):

However, when haystack.len() is less than 20, haystack.len() - 20 will be a very large number; we have an underflow error on our hands. This bug was causing the code to erroneously use the TwoWaySearcher in general for haystacks of length less than 20, but in particular for the case of "bananas".contains("nana"). The fix is to add 20 to the needle instead of subtracting it from the haystack […]

Type-safe URL Routes in Swift

Chris Eidhof:

I think it’s a really nice way of building APIs. The Github enum makes it very clear which endpoints are available, and the form of their parameters. By defining these things once, we can make it much harder for users of this API to make mistakes. For example, it’s not possible to pass in a nil username, because the UserProfile takes a non-optional string. If we wanted to add optional parameters, we have to be explicit about that.

The other nice thing is that all of the above code is independent of any networking library.

Macro-like Syntax Extensions Through Pseudo-closures

Christoffer Lernö:

For normal closures there is no way to fix this problem. We can only have the closure return to it’s caller, which in this case is the function times we added to Int.

In many languages with macros, we would construct syntax by directly working with the syntax tree created by the compiler. This is can get fairly advanced and isn’t very easy to read.

As we see in this example we could do a lot of nice things if we just had something which “looks like a closure but unwinds the stack like an exception”

I would really like to see something like this in Swift.

Implicitly Converting Functions to Return Optionals

Airspeed Velocity:

As we saw previously, if you pass a non-optional value to a function argument that expects an optional, it will get automatically converted into an optional by the compiler.

Ken Ferry points out something that goes one step further. If a function takes an argument of a function that returns an optional, and you pass into it a function that does not return an optional, the function will automatically be converted to return an optional.

Kännsch

Lukas Mathis:

As part of her Master’s degree at ETH Zürich, Laura Peer has developed an Android keyboard that solves this problem. The keyboard, called Kännsch, analyzes the text messages stored on the device it’s installed on. Together with a prebuilt database of words that different dialects have in common, this analysis allows the keyboard to accept Swiss German text without wrongly correcting words.

A keyboard extension would not be able to do this on iOS.

Choosing Secure Passwords

Bruce Schneier:

This is why the oft-cited XKCD scheme for generating passwords -- string together individual words like ‘correcthorsebatterystaple’ -- is no longer good advice. The password crackers are on to this trick.

[…]

Last year, Ars Technica gave three experts a 16,000-entry encrypted password file, and asked them to break as many as possible. The winner got 90% of them, the loser 62% -- in a few hours. It’s the same sort of thing we saw in 2012, 2007, and earlier. If there’s any new news, it’s that this kind of thing is getting easier faster than people think.

lidx

lidx is a “Unicode compatible full text indexer based on LevelDB” (via Hoà V. DINH). There’s a simple C API. It does not seem to do query parsing.

SPF Records and Too Many DNS Lookups

Some years ago, I added an SPF record to my domain. This makes it more likely that e-mails I send will get through to their recipients. The basic idea is that you declare (in your DNS record) which servers should be sending mail from your domain; any message not sent from one of those servers is probably spoofed. My SPF record for c-command.com looked something like this:

v=spf1 ip4:69.163.248.94 include:dreamhost.com include:fogcreek.com include:amazonses.com mx -all

The IP address was for my server. The SPF record also includes the SPF record for DreamHost, since I often send mail from their shared mail servers; Fog Creek, since I use FogBugz to send e-mails to customers; and Amazon SES, which I use to send order confirmation e-mails and serial number lookups. The mx means to look up the mail servers in my domain’s MX DNS record. The -all means that these are the only authorized servers.

It turns out that many mail servers don’t care if your SPF record is invalid. But some do, and I found this out when I was unable to send messages to a customer who had configured his server more strictly. When moving my site to a different server, I had updated the SPF record with the new IP address but accidentally included a space before it, which made the SPF record syntactically invalid.

I fixed this and, after waiting for the DNS to propagate, validated my SPF record. As expected, the syntax was now correct. However, the SPF record was still invalid:

Results - PermError SPF Permanent Error: Too many DNS lookups

I had not seen that before, but it turns out that RFC 7208 says:

Some mechanisms and modifiers (collectively, “terms”) cause DNS queries at the time of evaluation, and some do not. The following terms cause DNS queries: the “include”, “a”, “mx”, “ptr”, and “exists” mechanisms, and the “redirect” modifier. SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation, to avoid unreasonable load on the DNS. If this limit is exceeded, the implementation MUST return “permerror”.

My SPF record looked like it only had four lookups:

$ host -t txt dreamhost.com | grep spf1
dreamhost.com descriptive text "v=spf1 ip4:62.229.62.0/24 ip4:69.64.144.0/20 ip4:98.124.192.0/18 ip4:66.33.206.0/24 ip4:66.33.195.34 ip4:208.113.189.254 ip4:208.113.200.0/24 ip4:66.33.216.0/24 ip4:208.97.187.128/25 ip4:64.90.62.0/24 ip4:64.90.63.0/25 ip4:64.90.63.128/26 include:_spf.goo" "gle.com include:sendgrid.net ~ALL"
$ host -t txt fogcreek.com | grep spf1
fogcreek.com descriptive text "v=spf1 ip4:64.34.80.172 ip4:69.90.190.164 include:_spf.google.com include:spf.mail.intercom.io include:amazonses.com -all"
$ host -t txt amazonses.com | grep spf1
amazonses.com descriptive text "v=spf1 ip4:199.255.192.0/22 ip4:199.127.232.0/22 ip4:54.240.0.0/18 -all"
$ host -t mx c-command.com
c-command.com mail is handled by 0 mx1.sub5.homie.mail.dreamhost.com.
c-command.com mail is handled by 0 mx2.sub5.homie.mail.dreamhost.com.

Unfortunately, the lookups within the dreamhost.com and fogcreek.com SPF records count, too. And those SPF records themselves have includes. The limit is quickly exceeded.

I was able to reduce the number of DNS lookups by removing include:dreamhost.com, because combination of my server’s IP address and the MX record were sufficient. DreamHost itself sends e-mails via Google and SendGrid, but it doesn’t do this on my behalf. Likewise, I could replace include:fogcreek.com with the IP addresses of the actual FogBugz mail servers, which are the only ones that FogCreek uses to send messages from my domain.

Now my SPF record looks like:

$ host -t txt c-command.com | grep spf1
c-command.com descriptive text "v=spf1 ip4:67.205.8.149 ip4:64.34.80.172 ip4:69.90.190.164 include:amazonses.com mx -all"

and it validates:

SPF record passed validation test with pySPF (Python SPF library)!

I will have to update it if any of the hard-coded IP addresses change, though.

Knots 3D

Knots 3D (App Store):

Tie, untie and rotate 93 knots with your finger in 3D! Knots 3D, our popular how-to knot app, will give you a whole new perspective on knots! Have you ever wondered what a knot looks like rotated 40° or maybe 90°? Or maybe you want to see what a Trilene knot or Constrictor knot looks like from the back? Use your finger to spin the knot and see how it looks from any angle in 3D!

Choose from 93 different knots and see how they’re tied in incredible detail. Watch the knot draw itself or use your finger to tie and untie the knot. Its easy to see where the virtual rope goes in and out and around. (Something about a rabbit and a hole and a tree right?) Zoom in on the knot to get a closer look or flip it around for another perspective.

Via Josh Centers and John Gordon.

iOS Resolution

John Gruber:

This recommendation is based not on aesthetics — how the controls look — but on the size of human fingertips. That’s the real constraint. 44 points isn’t a magic number; it’s a by-product of the size of the pixels on the original 2007 iPhone display (pre-retina, one point equaled one pixel). On every iPhone to date, from the original through the 5S and 5C, there has been a single consistent point resolution: 163 points per inch. That means a 44 × 44 point UI element has remained exactly the same physical size (as measured in inches or millimeters).

The original iPad introduced a second point resolution: 132 points per inch. This has remained consistent on the large (9.7 inch) iPads. The iPad Mini (both original and retina) uses the iPhone’s 163 points-per-inch resolution. Apple’s recommended target sizes did not change for the 9.7-inch iPad: they simply made the recommended tap targets physically larger. 44 points on an iPhone or iPad Mini is roughly 0.27 inches (6.9 mm). 44 points on a 9.7-inch iPad is 0.33 inches (8.4 mm). Everything is bigger by a factor of about 1.24.

Saturday, August 23, 2014

Swift Function Currying

Russ Bishop:

Now forget all that stuff we just discussed because Swift supports automatic function currying. Just separate the parameters inside their own parens and you’re done:

func takeFive<T:IntegerArithmeticType>(a:T)(b:T)(c:T)(d:T)(e:T) -> T {
    return a + b + c + d + e
}

[…]

A caller might ask us for a function that runs queries against a certain database. We can use a curried function (possibly private) that takes connection info as its first parameter, followed by query information as its second; the caller gets back a curried function that takes only the query parameters. The caller can then use this returned function without ever being aware of the details. We don’t have to create queue or thread specific ambient context information to track some sort of “current” connection. The storage lifetime of the connection information is tied to the lifetime of the closure’s environment. When the closure goes away, so too will the saved context. This also lets us have multiple active connections or pass them between queues and threads. In short, we can hide the details without jumping through any hoops or writing boilerplate objects just to carry some state data around.

Better Bash Scripting

Robert Muth:

I start every bash script with the following prolog:

#!/bin/bash
set -o nounset
set -o errexit

This will take care of two very common errors:

  1. Referencing undefined variables (which default to “”)
  2. Ignoring failing commands

[…]

Bash has a number of (underappreciated) ways to manipulate strings.

[…]

Some commands expect filenames as parameters so straightforward pipelining does not work. This is where <() operator comes in handy as it takes a command and transforms it into something which can be used as a filename.

Amazon vs. Hachette

Glenn Fleishman:

In May 2014, presumably to increase negotiating pressure on Hachette, Amazon removed pre-order buttons on Hachette books, eliminated discounts on Hachette books, and delayed shipments of Hachette books to purchasers. Amazon did the same with Warner Brothers DVDs around the same time for several weeks, and a few days ago pulled pre-orders for physical versions of Disney movies. Amazon is also engaged in a similar action against Bonnier Media in Germany, where antitrust laws are stronger and more strictly enforced.

[…]

The precise details of why Amazon and Hachette are at loggerheads remain unknown, although it appears the primary disagreement — at least according to insiders and public statements by both companies — is that Amazon wants to price all ebooks at no more than $9.99 while still making a profit from them, and Hachette is resisting. Under the antitrust consent degree to which Hachette agreed, Amazon was free to set retail prices for two years. That period is over, and Hachette now wants to set the retail price for ebooks, offering Amazon a percentage of the retail price. In essence, Hachette is looking to use the agency model, which gives pricing control to the publisher, whereas Amazon wants to stick with the wholesale model, in which resellers pay a fixed wholesale price and set whatever retail price they want. In many cases, the agency model provides a higher profit to a bookseller.

Christopher Wright (via John Gruber):

Amazon has pointed out that charging huge prices for ebooks—prices that, cost-wise, make them indistinguishable from paperbacks—is stupid. My apologies to all the publishers and writers who will be offended by this, but Amazon is right. They are absolutely making self-serving statements, but those self-serving statements are, from the perspective of a reader who likes buying books, and prefers buying more books with the same amount of money, 100% indisputably true. Their vision advances the market in a way that is better for customers. They have a position that has a solution.

Hachette’s position is “Amazon is trying to control the market.” Well, I actually agree with that position. But they haven’t offered a solution to that argument. They have no vision on how to create a market that effectively competes with Amazon that answers any of the claims Amazon has made about how their vision is better for consumers, or about how their vision is better for other publishers, like me. Sure, Amazon is opening the market wide only until they can sew it back up again, putting a nice little monogramed “Amazon” on the side of the duffel bag that will store the severed heads of all the publishers who dare cross them in the future, but their vision includes a description of how this change will make everything better while Hachette’s vision includes a description of how everything will remain exactly the same.

Siding with Hachette, in other words, doesn’t stop Amazon from being a monopoly.

Thinking for Programmers

Leslie Lamport had a great talk at Microsoft Build 2014:

Everyone thinks they think. If you don’t write down your thoughts, you’re fooling yourself.

[…]

No programming language, no methodology, obviates the need for specification. A specification is a separate task from coding.

[…]

If you don’t start with a spec, every piece of code you write is a patch.

[…]

Thinking doesn’t guarantee that you won’t make mistakes. Not thinking guarantees that you will.

Unfortunately, he doesn’t get into an example of what you can do, e.g. model checking, with a TLA+ specification.

Swift Name Mangling

Gwynne Raskind:

Swift’s name mangling is somewhat different from C++’s. Swift uses an encoding clearly based on the C++ scheme in principle, but containing considerably more information and expressing concepts only available in a more mature type system.

[…]

Swift will have generated over 100 more symbols, but this is the complex mangled name we’ll tear apart: __TFCCC4test1a1b1c1dfS2_FTS0_1xS1_1vFT1xSi_Si_OVS_1e1f

Swift and Debuggability

Russell Ivanovic:

Currently in Swift, those stack traces are even worse. I won’t post one until they actually release it to be fair to Apple…but why oh why when they were making a ‘modern’ programming language could they not solve this? I know, the Objective-C runtime is hailed by many the world over as being fast, and awesome. But it’s 2014, the things I actually care about are the problems Microsoft and Sun Microsystems solved, memory management and reliability. If it comes at the expense of a tiny amount of speed, I’ll happily take it.

[…]

As much as people hate Java, and to some extent I’m in that camp too, here’s an equivalent crash from our Android app […] Yes I know, ha ha Null Pointer, Java, LOL. But that’s an exact line number friends. What did the user do? They tapped the subscribe button. Which page where they on? The Podcast Dialog. Zero ambiguity. Guess how many of our Android crashes we get that for? 100%. In iOS we’d be lucky if even 30% of our crashes had stack traces we can line up to actual things we can then reproduce.

Xcode Messes With Time Machine…Too Much

Jerry Krinock:

So Xcode / xcodebuild has excluded not only the Intermediate Build Files directory from Time Machine, but the parent directory of this directory as well.

This is not too good if you have, for example, as I do, another subdirectory in that parent folder for storing other needed files such as version archives (zipped products, disk images and dSYM files).

Implementing a MyBool Type in Swift

Apple:

The boolean Bool type in Swift underlies a lot of primitive functionality, making it an interesting demonstration of how to build a simple type. This post walks through the creation of a new MyBool type designed and implemented to be very similar to the Bool type built into Swift. We hope this walk through the design of a simple Swift type will help you better understand how the language works.

Fixing the “Visual Voicemail Unavailable” Error

Paul Horowitz:

If you’ve ever encountered the “Visual Voicemail is currently unavailable” error on when going to check new voicemail on the iPhone, there are two quick tricks that almost always fix the problem. So before calling the actual voicemail number like you’re some kind of cave dweller in the stone age of cell phones, try these speedy fixes first.

I was getting this error for several days. Rebooting my phone didn’t help, but toggling Airplane Mode did.

Contractually-obligated Testing

Graham Lee:

Having a contract is a bit like having unit tests, except that the unit tests are always running whenever your object is being used. Try out Eiffel; it’s pleasant to have real syntax for this, though really the Objective-C version isn’t so bad.

Finally, the contract is implemented by some simple message interception (try doing that in your favourite modern programming language of choice, non-Rubyists!).

Monday, August 18, 2014

On Vesper and Working Efficiently

Brent Simmons:

And then it gets just a little bit worse still: Mail on iOS 8 does have the ability to keep swiping to get the default action. Mail must be doing this as a custom thing or using private APIs to get this.

Which means that if we adopted the standard behavior, people would ask us why we don’t “just” do what Mail does.

Which argues for not touching this at all, since we already do a custom thing which works.

But that, again, means we’ve got this custom code to maintain and a bit of UI that’s quite unlike what users expect. (Which isn’t necessarily the worst thing. There can be good reasons for doing something different.)

“It’s a Coup”

I highly recommend the Edge Cases episode Swift Is a Really Good Thing and a Step Back. There’s much to like about Swift, but much has been lost as well: instantiating classes by name, the ability to write your own Core Data–like framework, message passing (contra vtable dispatch), swizzling to work around bugs and to add features, proxies/bridges, and more.

The quote in this post’s title, from Andrew Pontious, refers to the general lack of outrage over the loss of dynamism. In broad strokes, the C++ people have asserted their vision that the future will be static, and the reaction from the Objective-C crowd has been apathy. Apple hasn’t even really tried to make a case for why this U-turn is a good idea, and yet the majority seems to have rolled over and accepted it, anyway.

Since the episode was released, there’s been some good news: Wolf Rentzsch is not leaving Edge Cases, as was implied. More mixed is the news of the significant changes that Apple has made to Swift in beta 5.

The latest version of The Swift Programming Language discusses the new dynamic modifier:

Apply this modifier to any member of a class that can be represented by Objective-C. When you mark a member declaration with the dynamic modifier, access to that member is always dynamically dispatched using the Objective-C runtime. Access to that member is never inlined or devirtualized by the compiler.

Because declarations marked with the dynamic modifier are dispatched using the Objective-C runtime, they’re implicitly marked with the objc attribute.

Previously, there was only the @objc attribute, and this made it seem like message passing was deprecated. The only way to get it was via the Objective-C compatibility layer, and the @ sign emphasized that it was not part of the language proper.

One way to interpret the addition of the dynamic modifier, which lacks a @, is that Apple plans for message passing to be at least an optional part of Swift going forward. It’s currently implemented using the Objective-C runtime, but it’s no longer tied to @objc. In a future release, there could be pure Swift classes that use message passing.

However, the other half of this change is that methods in Objective-C classes are no longer dynamic by default. The dynamic modifier doesn’t actually make things more dynamic; rather, Apple has made everything more static but allowed you to opt out by annotating individual methods. To define an Objective-C method, you used to type just -. Now you must type func dynamic. This reminds me of how you have to type nonatomic on most Objective-C properties because the default is usually not what you want.

The latest version of Using Swift with Cocoa and Objective-C says:

While the @objc attribute exposes your Swift API to the Objective-C runtime, it does not guarantee dynamic dispatch of a property, method, subscript, or initializer. The Swift compiler may still devirtualize or inline member access to optimize the performance of your code, bypassing the Objective-C runtime. When you mark a member declaration with the dynamic modifier, access to that member is always dynamically dispatched. Because declarations marked with the dynamic modifier are dispatched using the Objective-C runtime, they’re implicitly marked with the @objc attribute.

Requiring dynamic dispatch is rarely necessary. However, you must use the dynamic modifier when you know that the implementation of an API is replaced at runtime. For example, you can use the method_exchangeImplementations function in the Objective-C runtime to swap out the implementation of a method while an app is running. If the Swift compiler inlined the implementation of the method or devirtualized access to it, the new implementation would not be used.

The good news is that Apple has found a way to speed up Objective-C classes in Swift. Presumably, this only applies to methods that are compiled into the same binary as their callers. My guess is that calls into the Cocoa frameworks cannot be optimized in this way.

The bad news is that, by default, your objects will no longer work with KVO or swizzling. If the designer of a class doesn’t anticipate a reason for a particular method or property to be dynamic, that lack of foresight gets baked in at compile time.

In my view, this is a mistake. It makes sense for dynamism to be the default because the costs are low. Objective-C message dispatch is very fast—famously running on 68030 hardware and of course the original iPhone. And, secondly, the Pareto principle applies: when message passing is a bottleneck, most of the gains can be obtained by making just a few hot spots more static (e.g. using IMP-caching).

The costs for not using message passing, on the other hand, can be high because they make the code more rigid/brittle. You cannot retroactively make compiled code more dynamic/flexible. And yet, since dynamic is not the default, the odds are that a lot more methods will be static than need to be. Most of the time, objc_msgSend is not why your code is slow, yet Swift acts like it needs to protect you from this.

The common case is that message sending is fast enough and that programmers are not smart enough to predict all the ways their code will be used in the future. So Apple optimize for that and make dynamic the default.

Sunday, August 17, 2014

Weird E-mail to Download Dropbox 1.0

Jerry Krinock:

It seems like either the Saturday night crew at Dropbox has made a major mistake, or this is some kind of new phishing attack that came pretty close to succeeding.

The same thing happened to me. There is information in the e-mail that I’m pretty sure no one but me and Dropbox would know. So I think the e-mail is legitimate, which is pretty strange.

Font Legibility vs. Attractiveness

John Gruber:

I don’t think Apple has ever promoted Helvetica Neue as being more legible than, say, Lucida Grande. Apple has moved to Helvetica because it’s more attractive, and, with modern display resolutions (especially retina displays), Helvetica is legible enough. One may fairly argue that legibility should always trump aesthetics — but one could argue thus for all font choices, not just UI fonts.

The same was true of Mac OS X 10.0’s pervasive system-wide anti-aliasing. It was less legible but more aesthetically pleasing. In the long run, as displays got better and better, people stopped complaining about it.

If I’m complaining less, it’s only because I’ve lost hope that Apple is ever going to make legibility a priority. Retina displays are not yet widely available on Macs. Even where they are available, Apple has found ways to reduce legibility.

Update (2014-08-19): David Barnard:

I’m just not sure I can ever get on board with the new “to hell with legibility” Apple.

Update (2014-08-23): Ken Segall:

That’s not the only crime against fonts committed in this video. It opens with the following screen, featuring text over an image.

Thin white type over a light image? Unless this was designed to be some kind of eye test, it is in gross violation of Apple readability standards.

What’s the Matter With PGP?

Matthew Green:

Now let’s ignore the fact that you’ve just leaked your key request to an untrusted server via HTTP. At the end of this process you should have the right key with high reliability. Right?

Except maybe not: if you happen to do this with GnuPG 2.0.18 -- one version off from the very latest GnuPG -- the client won’t actually bother to check the fingerprint of the received key.

[…]

Adding forward secrecy to asynchronous offline email is a much bigger challenge, but fundamentally it’s at least possible to some degree. While securing the initial ‘introduction’ message between two participants may be challenging, each subsequent reply can carry a new ephemeral key to be used in future communications. However this requires breaking changes to the PGP protocol and to clients -- changes that aren’t likely to happen in a world where webmail providers have doubled down on the PGP model.

[…]

I realize I sound a bit cranky about this stuff. But as they say: a PGP critic is just a PGP user who’s actually used the software for a while. At this point so much potential in this area and so many opportunities to do better. It’s time for us to adopt those ideas and stop looking backwards.

Meta Notifications

Matt Henderson:

What I need is a notification system that reliably alerts me when things aren’t normal. Such a system would receive those periodic email notifications from my various apps and utilities, and would notify me whenever they didn’t receive them on the expected periodicity.

Major Changes to Gatekeeper in Mac OS X 10.9.5

Apple:

Beginning with OS X version 10.9.5, there will be changes in how OS X recognizes signed apps. Version 1 signatures created with OS X versions prior to Mavericks will no longer be recognized by Gatekeeper and are considered obsolete.

Important: For your apps to run on updated versions of OS X they must be signed on OS X version 10.9 or later and thus have a version 2 signature.

[…]

Do not use the --resource-rules flag or ResourceRules.plist. They have been obsoleted and will be rejected.

Apple does not seem to have given any reason for why such a big change—breaking many third-party applications—is so important that it needs to be introduced in a maintenance update of the OS. Is there a danger for people using 10.6–10.8, which presumably will not be updated?

Daniel Jalkut:

I’ve been burned too many times by default code signing behaviors, so I long ago switched to an approach which many will consider too complicated, but which has nonetheless saved my bacon on repeated occasions. The “resource rules” change from Apple wouldn’t have even registered on my radar, because the final code signing of all my bundled frameworks, plugins, XPC services … every darned executable, is controlled by a custom build phase which is run very late in my apps’ build process, right before the final code signing of the overall app that Xcode handles at the very end.

[…]

A common kind of customization you might want to make is to e.g. add arguments to codesign that will cause the preservation of entitlements, so that e.g. an XPC service with its own entitlements will not have those blown away by your re-signing of the app. See “man codesign” for more information about the “-preserve-metadata” option and other flags.

I take this a step further and do all of my code signing in a shell script that runs after Xcode finishes its build and my other build scripts have run. It’s annoying to have to maintain this script, but the alternative—leaving it to Xcode’s built-in code signing support—has never seemed to work. A version-controlled script lets me see exactly what’s happening and in what order. I’m less subject to Xcode’s whims and can easily share logic among my applications.

Daniel Jalkut:

However, for a variety of reasons many of us either need to build with older versions of Mac OS X or Xcode. We face a conundrum that can be solved by signing (or more accurately, re-signing) the apps on 10.9, ensuring that the signature is up to snuff even if the code was compiled and the app was assembled with earlier tools.

This is a fairly straight-forward process, but there are some gotchas and you should be aware of what effect running codesign with various flags will have on your finished product.

[…]

In my tests I ran into some issues having to do with the fact that some of my apps have custom “designated requirements.” I have ironed out all the kinks yet but it seems to help in this scenario to re-establish all the code signing for the bundle first and then as a final icing on the cake, re-sign the app package with the custom designated requirement.

Felix Schwarz:

Currently I have to build parts of Remote Buddy in Xcode 3 running on OS X 10.6.8.

[…]

The only way to obtain a v2 signature is by code signing under 10.9, but since Xcode 3 doesn’t run on anything newer than 10.6.8, I’ll have to separate the build process from the signing, packaging and submission process.

Jeff Johnson:

As TN2206 indicates, custom resource rules no longer work on 10.9.5 or Yosemite Developer Preview 5. The effect, for us, is that none of our shipping apps will currently be accepted by Gatekeeper on those versions of OS X. This was quite a shock. Fortunately, there is a “happy” ending to the story. We needed a solution to the problem quickly, and ideally a solution that didn’t require us to completely rearrange our source code repository. The potent combination of desperation and brilliance, if I may be so modest, led me to the solution.

[…]

I’m not going to make any editorial comments here on the change to Gatekeeper in 10.9.5, because this post is intended for developers, to aid them in their work. And my comments would be NSFW.

David Hamilton:

If developers don’t act quickly, large numbers of common apps could be affected. Developer John Bafford published a command-line script on GitHub Gist that identifies the signature version of all programs in a Mac’s applications folder.

Including Apple’s own applications, it looks like about two-thirds of the ones I have installed are using version 1 signatures.

Amazon’s Strategy: Horizontal Company, Vertical Devices

Ben Thompson:

I suppose this makes a certain kind of sense, but it reeks of what a former manager of mine calls a “double bank shot.” Amazon seems to be arguing that through this rather convoluted chain of events, all of which carry significant challenges and risks that are outside Amazon’s expertise (content creation, ecosystem development, etc.), they will be better placed to increase e-commerce’s share of retail.

Here’s my question: why not spend all that money – and time and executive attention – on simply growing e-commerce? Instead of pushing for the Prime Rube Goldberg machine, how about simply advertising Prime? And instead of pursuing a separate ecosystem, with all of the challenges and incentive risk that implies, why not focus on both building better apps and on creating partnerships with Apple in particular (who certainly has no intention of competing in e-commerce; Google is obviously much more of a competitor)?

Moreover, I’m concerned about the internal incentives that Amazon is creating for itself. Amazon is increasingly competing with its suppliers, particularly in the digital space, and I just noted that potential partners like Apple are instead rivals. More concerning is the effect of devices on the company’s overall strategy.

Matt Drance:

I think it’s pretty simple: Android + Google Shopping Express + mobile payments completely shut Amazon out of customer engagement.

I don’t really understand the argument that this is a threat to Amazon. Or that, if it is, that this is a response that would work.

Friday, August 1, 2014

Alamofire

Mattt Thompson:

Alamofire is an HTTP networking library written in Swift. Think of it as AFNetworking, reimagined for the conventions of this new language.

Of course, AFNetworking remains the premiere networking library available for Mac OS X and iOS, and can easily be used in Swift, just like any other Objective-C code. AFNetworking is stable and reliable, and isn’t going anywhere. But for anyone looking for something a little more idiomatic to Swift, Alamofire may be right up your alley. (It’s not a mutually-exclusive choice, either! AFNetworking & Alamofire will peacefully co-exist within the same codebase.)

Swift Retain/Release and Pointer Arithmetic

Russ Bishop (via Wolf Rentzsch):

While creating ThreadLocalSlot<T>, I needed to call the posix posix_getspecific and posix_setspecific methods. Not only that, I needed to store an Objective-C object in a plain old void*. How can we accomplish that in Swift?

The key is Unmanaged. It contains magic sauce to let us turn an AnyObject into a COpaquePointer, which is implicitly convertible to most of the other C-pointer types in Swift. It also lets us apply retain or release to an object arbitrarily. Granted, you can certainly shoot yourself in the foot, but we all lived dangerously before ARC.

Russ Bishop:

You might end up kicking yourself, but UnsafePointer<T> and its cousins all have arithmetic operators already defined so pointer manipulation is very simple:

Office for iPad Updates

Andrew Cunningham:

All four apps can now export files as PDFs, crop pictures inline, and reset changes made to pictures. Word, Excel, and PowerPoint can also use third-party fonts, presumably in addition to the Microsoft- and Apple-supplied fonts that come with iOS and the Office apps themselves. Excel, Powerpoint, and OneNote pick up more features that will be appreciated by heavier users of the desktop Office apps.

It’s great to see Microsoft using a shorter update cycle.

Core Data Editor Is Now Open Source

Christian Kienle:

In a little while I will remove Core Data Editor from the Mac App store and offer Core Data Editor as a free download from my website. One of the main reasons for doing so is my health. I can maintain a project like Core Data Editor but I cannot add significant features on my own anymore.

GitHub:

Core Data Editor lets you easily view, edit and analyze applications‘ data. Core Data Editor is compatible with Mac and iOS applications and supports XML, SQLite and binary stores, visualizes all relationships and is able to edit the data and generate Objective-C code for the data model.

The Adobe Illustrator Story

Terry Hemphill (via Khoi Vinh):

When Adobe Illustrator first shipped in 1987, it was the first software application for a young company that had, until then, focused solely on Adobe PostScript. The new product not only altered Adobe’s course, it changed drawing and graphic design forever.

Watch the Illustrator story unfold, from its beginning as Adobe’s first software product, to its role in the digital publishing revolution, to becoming an essential tool for designers worldwide. Interviews include cofounder John Warnock, his wife Marva, artists and designers Ron Chan, Bert Monroy, Dylan Roscover and Jessica Hische.