Friday, August 28, 2015 [Tweets]

Live Help Menu Searching via NSUserInterfaceItemSearching

Gus Mueller (tweet):

When rendering the documentation (542MB of it, 1.22GB pre-render!), FMWrite also creates a SQLite index (1MB) of all the text content, which I then copy into Acorn’s resources folder at build time. Acorn then ships with this SQLite file.

You don’t really need to build your own documentation app. But you do need an index of your documentation to ship with your app. SQLite worked great for us.

Step 2: Let me introduce you to NSUserInterfaceItemSearching, which is a class which shipped in 10.6 but I didn’t notice till about six months ago. It’s a pretty simple protocol—you just register a class which conforms to it, and you’re asked for entries when the user searches for something via the Help menu.

Note that you don’t have to implement your own index and conform to this protocol to get live searching in the Help menu. You get that for free if you’re using Apple Help and have an hiutil index. The protocol is for when you want to search the help locally but host it on your server.

Type Profiling and Code Coverage Profiling for JavaScript

Saam Barati:

Web Inspector now has two great tools designed to make debugging JavaScript programs easier: the Code Coverage Profiler and the Type Profiler. The Code Coverage Profiler visually displays exactly which sections of your JavaScript program have executed. The Type Profiler visually annotates important variables with the collected set of type information for those variables. Both tools make understanding and debugging your JavaScript programs in Web Inspector better than ever.

[…]

The Type Profiler updates in real time. As new information is introduced in your program, the Type Profiler updates its annotations. As you see in the video, when the announceAnimal function is called a second time, the type displayed for the animal parameter updates from Dog to Animal. This happens because the Type Profiler tracks the inheritance chain for values it profiles. The Type Profiler also shows other aggregate types in an intelligent way. As you use the Type Profiler, you’ll see that the types it shows you are both intuitive and helpful.

[…]

Because the type profiling machinery is compiled into JSC’s bytecode, JSC is then able to utilize its multi-tiered compiler infrastructure to optimize the overhead of type profiling. JSC’s DFG JIT is able to successfully optimize JavaScript code in large part due to the tendency that most JavaScript code is written with specific types in mind. Because of this, the DFG JIT can speculatively transform its IR based on gathered profiling information. Then, when executing this speculative code, if it finds that an assumption is broken at runtime, the DFG will OSR exit back into JSC’s baseline JIT. The bytecode operation op_profile_type is a very expensive operation and it appears with high frequency when the Type Profiler is enabled. When we transform this bytecode operation into DFG IR, we’re often able to optimize away the overhead of ProfileType by completely removing it from the executing code. We’re able to do this because by the time we decide to DFG compile the bytecode stream, it is likely that the types which were profiled in the Baseline JIT and the LLInt are the same types that the DFG will speculatively compile against.

AWS Privilege Separation

Michael Wittig (comments):

  1. You have AWS access credentials for your IAM user in the bastion account on your machine (usually in ~/.aws/ or in your environment variables). You make a call to the AWS API to get temporary credentials by providing a MFA token. If the MFA token is valid, you’ve created a temporary session for your IAM user in the bastion account.

  2. You receive temporary credentials to authenticate as your IAM user.

  3. With the temporary credentials, you can assume a role in another account (this wasn’t possible before, because assuming a role is only allowed for this user if the user is authenticated with MFA). To assume a role in another account, the role must explicitly be allowed to be used with your account! The maximum permissions a role should have is PowerUserAccess. Don’t allow the role to interact with IAM!

  4. You receive temporary credentials and can begin working with your AWS account.

Shipping an App With App Transport Security

Tim Ekl (tweet):

This article is aimed at a different purpose: to look at the different speed bumps that can show up while building an app alongside ATS, and to explain how to get around them. There are lots of great little tricks that have only cropped up in OS X release notes or on Stack Overflow, or that can only be discovered by building a sample app.

[…]

With this more extensive ATS dictionary in our app’s Info.plist, we turn the “allows insecure HTTP loads” flag back off for the example.com domain and all its subdomains. When our app makes any connection to a host in that domain, then, we’ll be receiving the full protection of ATS.

This exception mechanism can handle even more complex scenarios. For example, consider what might happen if most servers in example.com were correctly secured with HTTPS, but one server – say, insecure.example.com – wasn’t yet fully ATS-compatible. We can handle this by defining another more specific exception for just that host[…]

[…]

In both of these error cases, we can set the environment variable CFNETWORK_DIAGNOSTICS to 1 in order to get more information on the console about the failure. After turning this variable on in our app’s scheme, you’ll notice a new log line with a path to a diagnostic file; this file, in turn, is filled with information about all the actions the CFNetwork layer is taking on behalf of your app’s networking code.

[…]

If you have access to an OS X machine running 10.11 or later, the command-line utility nscurl provides some basic ATS debugging capabilities.

Tristan Emrich:

While Google remains committed to industry-wide adoption of HTTPS, there isn’t always full compliance on third party ad networks and custom creative code served via our systems. To ensure ads continue to serve on iOS9 devices for developers transitioning to HTTPS, the recommended short term fix is to add an exception that allows HTTP requests to succeed and non-secure content to load successfully.

Note that this allows all HTTP requests to succeed, not just ones pertaining to Google ads.

Nick Heer:

So in a year where malware-laden ads are becoming increasingly frequent, Google’s response is not to convert their ad network to HTTPS, but rather to tell developers to reduce the security of their apps.

Google update:

To be clear, developers should only consider disabling ATS if other approaches to comply with ATS standards are unsuccessful.

Previously: App Transport Security.

The Facebook App’s 18,000 Classes

quellish:

Recently someone on reddit asked “How on earth is the Facebook app size so large ?”. The person asking the question realized that the ~100Mb compressed App Store archive wasn’t all assets - a very large portion was the application binary.

Note that you don’t have to jailbreak your device to see the contents of an app. You can just download the .ipa file to your Mac with iTunes.

And if you ever wonder about JavaScript slowing sites down, just try scrolling the linked blog in Safari.

Thursday, August 27, 2015 [Tweets]

Capturing Swift Error Context

Erica Sadun:

Say you’re working with a type and you want to throw an error that reflects the context of where it originates. You can do that, mostly, using a few built-in compiler keywords. __FUNCTION__, __LINE__, and __FILE__ provide literal interpolation about the details of a calling function[…]

[…]

Use a protocol to automatically pick up on type context. The default implementation in the following Contextualizable extension refers to self.dynamicType in a way that a method signature cannot.

I’ve long been doing this sort of thing in Objective-C with macros. It’s a bug help when debugging or tracking down what happened on a customer’s Mac. Unlike the macros, this won’t build up a stack trace of how the error was propagated, although you could approximate that using -[NSThread callStackSymbols].

Previously: Swift and Cocoa Error Handling, JSErrorStackTrace, NSXReturnThrowError.

A Salute to Solo Programmers

Jean-Louis Gassée (comments):

Parkinson’s Law tells us that “work expands so as to fill the time available for its completion”. Applied to software, this means that applications tend to bloatware, obese programs whose complexity makes them nearly impossible to debug and maintain. Today, we look at happier counterexamples, past and current, of ambitious products created by “hermit programmers”.

[…]

As it turns out, the size and complexity of operating systems and development tools do not pose completely insurmountable obstacles; we still find programs of hefty import authored by one person. One such example is Preview, Mac’s all-in-one file viewing and editing program. While the Wikipedia article is out of date and tepid, the two-part Macworld article titled The many superpowers of Apple’s Preview (here and here) does justice to the app’s power and flexibility. Read it and join me in my appreciation for this labor of love from a solo, unnamed programmer who, I’m told, has been at it since the NeXT days.

[…]

Newer than Preview but no less ambitious, we have Gus Mueller’s Acorn, an “Image Editor for Humans”, now in version 5 at the Mac App Store. To get an idea of the breadth and depth of the app, scan the documentation on the company’s web site.

Facebook App Changes iOS System Share Sheets

Chris Adamson:

In a nutshell, Facebook doesn’t want developers pre-populating posts for users, at all. It’s not good enough to allow the user to edit or delete the post you’ve prepared for them, you can’t offer them post contents at all.

And somehow, they are able to enforce this programmatically.

My boss was gobsmacked when I told him this on Slack and could hardly believe it. Can Facebook seriously hack the iOS frameworks to get this behavior? How is that technically possible, and even if they can, how are they still in the App Store?

Or, does Apple let them do it? One plausible scenario here is that since Facebook and Apple are special friends – enough so to have Facebook deeply integrated into Settings, Contacts, and elsewhere – iOS looks to see if the Facebook app is present, and hands off the compose logic to a controller provided by Facebook if so.

Java Is Magic: the Gathering (or Poker) and Haskell Is Go (the Game)

Michael O. Church:

Of course, all of this that I am slinging at OOP is directed at a culture. Is object-oriented programming innately that way? Not necessarily. In fact, I think that it’s pretty clear Alan Kay’s vision (“IQ is a lead weight”) was the opposite of that. His point was that, when complexity occurs, it should be encapsulated behind a simpler interface. That idea, now uncontroversial and realized within functional programming, was right on. Files and sockets, for example, are complex beasts in implementation, but manageable specifically because they tend to conform to simpler and well-understood interfaces: you can read without having to care whether you’re manipulating a robot arm in physical space (i.e. reading a hard drive) or pulling data out of RAM (memory file) or taking user input from the “file” called “standard input”. Alan Kay was not encouraging the proliferation of complex objects; he was simply looking to build a toolset that enables to people to work with complexity when it occurs. One should note that major object-oriented victories (concepts like “file” and “server”) are no longer considered “object-oriented programming”, just as “alternative medicine” that works is recognized as just “medicine”.

[…]

Where is this whole argument leading? First, there’s a concept in game design of “dryness”. A game that is dry is abstract, subtle, generally avoiding or limiting the role of random chance, and while the game may be strategically deep, it doesn’t have immediate thematic appeal. Go is a great game, and it’s also very dry. It has white stones and black stones and a board, but that’s it. No wizards, no teleportation effects, not even castling. You put a stone on the board and it sits there forever (unless the colony is surrounded and it dies). Go also values control and elegance, as programmers should. We want our programs to be “dry” and boring. We want the problems that we solve to be interesting and complex, but the code itself should be so elegant as to be “obvious”, and elegant/obvious things are (in this way) “boring”.

Swift 2 Beta 6

Russ Bishop:

A new try? keyword has been added. This attempts an operation that may throw (fail). If it succeeds the result is wrapped in an optional. If it fails the error is ignored and nil is returned. This seems like a pragmatic compromise but I have to imagine someone lost a battle somewhere because a lot of programmers are going to slap a try? on it and ignore all errors.

This is a good addition that was suggested last month. I’m not worried about errors being ignored because the compiler warns if the result of try? is unused. It lets you ignore the specific error that you got, but you still have to handle the fact that there was an error.

Variadic parameters can appear anywhere in the parameter list; presumably the compiler disambiguates them by type and/or by consuming values off the right-hand side of argument list until the non-variadic arguments are satisfied.

It looks to me like it’s simpler than that, and you simply use a named parameter to signal the end of the variadic parameter. Perhaps in the future it will be possible to support multiple variadic parameters in this way. For now, the main benefit is that you can more easily use trailing closures.

extend was renamed appendContentsOf and splice was renamed insertContentsOf

It’s good to see Apple keeping some of Foundation’s good ideas.

Most APIs that take closures or @autoclosure parameters use rethrows properly so you can pass throwing methods to map, filter, etc. It also allows short-circuiting operators like &&, ||, or ?? to work with expressions that throw.

This should make error handling easier than before.

There are still some bugs, though:

Declaring multiple globals in a single var or let may cause corruption of their values; the workaround is to declare them with separate var or let statements.

Erica Sadun:

You can combine try? with ?? for fallback values but you must surround the try in parens[…]

Erica Sadun:

Beta 6 introduces a lazy property on sequences.

[…]

This property is implemented in CollectionType, LazyCollectionType, and LazySequenceType extensions. You use it to delay evaluation on things like map and filter that are normally eager.

Erica Sadun:

Join has become joinWithSeparator, which you call after a sequence, interposing a separator between the elements of a sequence.

The Death of Scripting

Graham Lee (comments):

And so it’s sad to see scripting die out as the popular platforms for application development fail to support it. Instead of the personal control of the script – I will take this information from that app, and put this part of it in that app – we have the corporate control of the API. This app maker and that app maker are BFFs, sign in here to let them share everything. After all, they know best.

Ultimately the death of scripting is hubristic. We know how you want to use a computer. If you’re trying to do something that we didn’t sell to you, you must be holding it wrong.

Graham Lee:

There’s bash, and powershell, and ruby, and…even Perl is still popular among sysadmins. There’s never been a better time to be a programmer or other IT professional trying to automate a task.

True, but there’s never been a worse time for someone who doesn’t care about computers to use a computer to automate a task. Apps are in-your-face “experiences” to be “used”, and for the most part can’t be glued together.

Brent Simmons:

There are counter-examples, of course — the apps I work on (Mac versions of OmniFocus and OmniOutliner) are highly scriptable. But the trend toward silos, sandboxing, and highly-controlled experiences is clear.

(First thing I did was look to see if Slack has a scripting dictionary. Of course not. Neither does HipChat. Apps these days.)

Update (2015-08-27): Dr. Drang:

I think Lee’s pessimism is temporally misplaced—at least in the Apple world. While I’d never say that scripting Apple devices is in an ideal state, the situation certainly looks better than it did two or three years ago.

[…]

Things are still more locked down on the iOS side, but we now have app extensions to ease some of the pain and Workflow for more complicated interapp trickery.

Wednesday, August 26, 2015 [Tweets]

Safer Block-based NSNotificationCenter API

Arkadiusz Holko:

I wanted to learn how Clang decides when to show a warning, so I did what any reasonable person would do and dove into its source. Retain cycle checking is performed during the semantic analysis phase. Sema::checkRetainCycles is an overloaded method responsible for these checks.

[…]

In case of a message send, the compiler checks for retain cycles only when a selector looks like a setter, i.e., it starts with the word add or set. This check is rather simplistic. A warning isn’t presented to the user when using NSNotificationCenter, because the compiler doesn’t know the lifecycle of that object.

So he made a MCSNotificationController wrapper so that the compiler can detect the retain cycle. It also makes sure that you don’t register for the same notification more than once and automatically unregisters in -dealloc.

Previously: NSNotificationCenter With Blocks Considered Harmful, How Not to Crash #3: NSNotification.

Common Android Lock Patterns

Dan Goodin (via Jamie Zawinski):

Data breaches over the years have repeatedly shown some of the most common passwords are “1234567”, “password”, and “letmein”. Løge said many ALPs suffer a similar form of weakness. More than 10 percent of the ones she collected were fashioned after an alphabetic letter, which often corresponded to the first initial of the subject or of a spouse, child, or other person close to the subject. The discovery is significant, because it means attackers may have a one-in-ten chance of guessing an ALP with no more than about 100 guesses. The number of guesses could be reduced further if the attacker knows the names of the target or of people close to the target.

How to Survive Working at Home

Daniel Jalkut:

Actually being your own boss is one of the greatest challenges of working from home, and in my experience it’s helpful to be, well, bossy with yourself to the extent you are comfortable. Give yourself strict deliverables; I write a checklist in the morning and get very grumpy with myself if the checklist is not completed or rationalized by the end of the day.

[…]

At home, nobody tells you when to stop working. Establish a rule with yourself, or with your family, for when the workday ends and the “lifeday” begins.

I’ve found that having a rough schedule for each day—both when to work and what type of work to do when—helps a lot.

tpwn Privilege Escalation Vulnerability

Juli Clover (comments):

Just days after Apple patched the DYLD_PRINT_TO_FILE security hole with the release of OS X 10.10.5, a developer has found a similar unpatched exploit that could allow attackers to gain root-level access to a Mac.

Luca Todesco shared information (via AppleInsider) on the “tpwn” exploit on GitHub over the weekend. It affects all versions of OS X Yosemite, including OS X 10.10.5, but does not affect OS X El Capitan.

Luca Todesco:

1) I cannot really discuss specifics, but this particular bug would have been hard to find via a traditional IOKit fuzz, since it requires an invalid ‘task’ port passed over to IOServiceOpen. Most fuzzers use mach_task_self for that, and fuzz method calls/traps/properties/etc.

2) When IOServiceRelease is called, vtable+0x20 is called. the vtable pointer is controlled, at +0x20 I place a stack pivot, which sets RSP = RAX and pops 3 times. At 0x18 I place a POP RAX;RET gadget to let the chain begin after 0x28. Payload then locates the credentials structure, sets UID to 0 by bzero()ing, cleans up the memory corruption, decreases the task count for current user and increases task count for root. It then unlocks locks held by IOAudioEngine to prevent your audio from freezing up, and then returns to the userland context.

Luca Todesco:

There is no weakness in address randomization I relied on for exploitation.

It relies on two distinct bugs, an info-leak to obtain a pointer to an allocation in the kalloc.1024 zone and a memory corruption primitive (deriving from a NULL pointer dfr. in IOKit) allowing me to OR 0x10 anywhere in kernel memory.

To break kASLR I corrupt the size of a vm_map_copy struct, which allows me to read the adjacent allocation to the struct, which is a C++ object. First 8 bytes of said C++ object is a pointer to the vtable, which resides in __TEXT of some kernel extension. Since I can calculate the unslid address from userland without any issue, by subtracting what gets leaked with what gets calculated you get to know the kASLR slide.

Just to clarify: The code execution part has 100% reliability rate. The kASLR leaking part does have some chance in it, however empirical evidence indicates that the failure rate is extremely low.

Jeremy Kirk:

Todesco, who said he does security research in his spare time, said he notified Apple of the problems “a few hours before the exploit was published.”

“This is not due to me having issues with Apple’s patch policies/time frames, as others have incorrectly reported,” he wrote.

He also developed a patch called NULLGuard, which he’s included in the GitHub material. Since he does not have a Mac developer certificate, he wrote that he can’t distribute an easy-to-install version of the patch.

How to See Your iPhone’s Precise Signal Strength

Josh Centers:

Dial *3001#12345#* and tap the green call button to put your iPhone into a secret Field Test Mode

[…]

Instead of dots, you should now see a negative number in the upper left, like -102. This is your exact signal strength, measured in decibels, called the Received Signal Strength Indication (or RSSI if you want to impress technical support). The higher the number, the better, but note that these are negative numbers, so -1 would be an outstanding signal, while -1000 would be beyond poor. In the real world, you’ll probably see signal strengths somewhere between -40 (a five-bar signal) and -120 (a one-bar signal).

Sunday, August 23, 2015 [Tweets]

Ways to Think About Cars

Benedict Evans:

Cars are going to change a lot in the next few decades. Electricity on one hand and software on the other change what a car is, how it gets made and who might own one. They might also change the key players. As is often the case when an industry is going to be turned upside-down, there are actually a number of separate things happening, which feed into each other and accelerate the pace of change.

[Objective] C++: What Could Possibly Go Wrong?

Peter Steinberger :

First, Swift interoperates with Objective-C and C, but it doesn’t work with C++ directly. Therefore, if you want to use Swift, being knowledgeable of Objective-C++ might actually help you, because it enables you to write a wrapper that wraps any third party library that might only exist in C++ with Objective-C.

[…]

This is not your grandmother’s C++. We have auto, which is type deduction. We have shared pointers, which is basically ARC. We have weak, which is also something we have in the Objective-C run time. We have lambdas, which is just a fancier name for blocks, and we have move semantics, which is something I’ll explain later because it’s a little crazy.

[…]

There are gotchas! One thing you’ll notice when you play with Objective-C++ is compile time. Depending on how much of it you start using, things will get slower, and they might take twice or three times as long. It’s still much faster than compiling Swift (at the moment), but it is noticeable and you should be mindful of not blindly renaming all your files to .mm because you can, only where it makes sense, and where you should.

[…]

The last thing we can do is write our own smart pointer that wraps CGPathRef and knows how to deal with Core Foundation objects. Don’t think I’m crazy, this is actually what WebKit does internally, they deal with a lot of Core Foundation objects and they want to get it right. We use something that’s CFPointer, and it’s not really much code, maybe 100 lines if you want to have move semantics and all those nice little details.

The Harmful Consequences of Postel’s Maxim

Martin Thomson (via Pieter Hintjens):

Jon Postel’s famous statement in RFC 1122 of “Be liberal in what you accept, and conservative in what you send” - is a principle that has long guided the design of Internet protocols and implementations of those protocols. The posture this statement advocates might promote interoperability in the short term, but that short term advantage is outweighed by negative consequences that affect the long term maintenance of a protocol and its ecosystem.

[…]

An implementation that reacts to variations in the manner advised by Postel sets up a feedback cycle:

  • Over time, implementations progressively add new code to constrain how data is transmitted, or to permit variations what is received.
  • Errors in implementations, or confusion about semantics can thereby be masked.
  • As a result, errors can become entrenched, forcing other implementations to be tolerant of those errors.

Bloom Filters

Jamie Talbot:

“Ok, let me see if I have this right,” says Sarah. “You want to be able to quickly exclude posts that a user has read, so that you don’t suggest those posts again. And a Bloom filter is a good fit for this problem, because it will never let through a post that the user has read, and even though it might exclude a post that they haven’t read, that’s ok because they’ll never know what they don’t see? And it’s very fast?”

Michael Nielsen (comments):

In this post I take an unusual approach to explaining Bloom filters. We won’t begin with a full-blown explanation. Instead, I’ll gradually build up to the full data structure in stages. My goal is to tell a plausible story explaining how one could invent Bloom filters from scratch, with each step along the way more or less “obvious”. Of course, hindsight is 20-20, and such a story shouldn’t be taken too literally. Rather, the benefit of developing Bloom filters in this way is that it will deepen our understanding of why Bloom filters work in just the way they do.

[…]

In actual applications of Bloom filters, we won’t know S in advance, nor |S|. So the way we usually specify a Bloom filter is to specify the maximum size n of set that we’d like to be able to represent, and the maximal probability of error, p, that we’re willing to tolerate.

[…]

Bloom filters have been used to solve many different problems. Here’s just a few examples to give the flavour of how they can be used. An early idea was Manber and Wu’s 1994 proposal to use Bloom filters to store lists of weak passwords. Google’s BigTable storage system uses Bloom filters to speed up queries, by avoiding disk accesses for rows or columns that don’t exist. Google Chrome uses Bloom filters to do safe web browsing – the opening example in this post was quite real!

[…]

Instead, the delete operation is implemented using an idea known as a counting Bloom filter. The basic idea is to take a standard Bloom filter, and replace each bit in the bit array by a bucket containing several bits (usually 3 or 4 bits).

CardDAV at FastMail

FastMail:

After much work and testing – and then some more work and testing – we’re delighted to announce the release of CardDAV support in FastMail. With CardDAV, you can access your FastMail contacts on your mobile phone, tablet or smart watch, with any changes you make on any device kept in sync – just like IMAP works with your email.

Unlike Apple and Google, you cannot restore your contacts to a particular time.

Saturday, August 22, 2015 [Tweets]

Checking for El Capitan

Jeff Johnson:

If you’re running on OS X 10.10.2 or later, the code tells you that you’re running on OS X 10.11. What happened? Let’s look at <AppKit/NSApplication.h> from the 10.11 SDK:

#define NSAppKitVersionNumber10_10 1343

So far, so good.

#define NSAppKitVersionNumber10_10_2 1344
#define NSAppKitVersionNumber10_10_3 1347

WHUT.

So yeah, instead of increasing the fractional part of the constant for 10.10.2 and 10.10.3, they increased the integer part. Sigh.

Update (2015-08-22): My solution is to check whether I’m running Mac OS X 10.10.0 or later, and then use -[NSProcessInfo isOperatingSystemAtLeastVersion:].

Git as a Document Format

Wil Shipley:

Undo and redo was sort of part of Core Data, but they tried to do it at the lowest level, where any time you changed the database, it just registered an undo event. This turned out to be a horrible idea. If you do any kind of housekeeping such as storing the user’s window position in the database, that suddenly becomes undoable. So, it turns out, if you have any auxiliary objects that get created, that also turns undoable. It’s not a good way to do undo.

[…]

In our perfect world of documents, we want fast loads. We don’t want to be forced to load all our data at once. We want fast saves. Fast is going to be one of the themes of our perfect world. Again we don’t want to re-save large blobs, and we’d love to have an editable format. We want autosaves to be instant, but not blow away the previous states of the document like Preview does. Undo and redo also need to be instant and never be corrupted by bad coding. We’d like them to be persistent, because that’s really cool and provides the ability to prune them.

For security reasons, you don’t necessarily want every version of your document in the document; we’ve learned that from the Microsoft Word exploits. The backup of our perfect file format should play nicely with Time Machine, which means that it shouldn’t have one giant monolithic file that changes by one byte and restarts the backup process. And, it should be incredibly easy to implement, because this is our perfect world, so why not?

[…]

As I said, you still need to decide on the file format for the control files; Git isn’t a file format that you would parse and turn into a series of drawing commands, it just gives you the files and their blobs really easily.

Lazy Filters and Maps

David Owens II:

Simply wrapping items in a lazy() call will convert our Sequence into a LazySequence. This gives us the performance benefits of the more iterative-style approach with the benefits of the semantically broken out operations.

Joe Groff:

map and filter produce copies which are likely cause of slowdown. lazy().map and filter should be as fast as loops.

Marcin Krzyzanowski:

I believe you, but I’m looking at map vs for-loop code in the very moment where loop is many times faster than lazy map.

Swift Funtime

Boris Bügling:

This talk will quickly revisit what we loved about the Objective-C runtime and then explore if/how those things are possible in Swift. It will dive into how to do dynamic introspection, changing behaviour and inspecting private API is still possible or why it is not. In addition to that, the audience will also learn a bunch about Swift under the hood and how using pure Swift or Objective-C compatible objects differ in practice.

Making Tab-Switching and Scrolling Faster in OmniFocus for Mac

Brent Simmons:

Setting up and tearing down the KVO observations isn’t a big deal, though. I was wrong about that. Updating the contents of a cell view is a big deal, however, and this is done when cells are recycled — but this is mainly a big deal because it triggers layout, which is slow.

So here’s what Instruments told me: NSStackView is slow (at least in our case).

But it also told me something else that completely surprised me: the app was spending a whole bunch of time setting and tearing down NSTrackingAreas.

He also replaced -enumerateObjectsUsingBlock: with a for loop.

Friday, August 21, 2015 [Tweets]

How Streaming Music Royalties Are Calculated

Sharky Laguana (via Marco Arment):

The reality is only some of your money is paid to the artists you listen to. The rest of your money (and it’s probably most of your money) goes somewhere else. That “somewhere else” is decided by a small group of subscribers who have gained control over your money thanks to a mathematical flaw in how artist royalties are calculated. This flaw cheats real artists with real fans, rewards fake artists with no fans, and perhaps worst of all communicates to most streaming music subscribers a simple, awful, message: Your choices don’t count, and you don’t matter.

[…]

The problem lies in the fact that this “Big Pool method” only cares about one thing, and one thing only: the overall number of streams. It does not care even a tiny little bit about how many subscribers generated those streams.

[…]

Click fraud is rarely discussed in the context of streaming music, but it’s fairly simple for a fraudster to generate more in royalties than they pay in subscription fees.

[…]

It’s worth noting that many (if not most) of these heavy-usage “subscribers” are probably not individuals at all. They are actually offices, restaurants, gyms, hair salons, etc. Businesses like these can stream up to 24 hours a day — far more you as an individual could ever hope to do. And they probably don’t share your taste in music either. But they pay the same $10 you do, so why do they get to decide where your money goes?

Swift Pattern Matching in Detail

Benedikt Terhechte (via Chris Lattner):

The main feature of switch is of course pattern matching, the ability to destructure values and match different switch cases based on correct match of the values to the cases.

[…]

So, how do you best implement this new restriction? You could just have an if / else switch for buy and for sell, but that would lead to nested code which quickly lacks clarity - and who knows maybe these Wall Street guys come up with further complications. So you define it instead as additional requirements on the pattern matches[…]

[…]

By default, and unlike C/C++/Objective-C, switch cases do not fall through into the next case which is why in Swift, you don’t need to write break for every case. You can opt into traditional fallthrough behaviour with the fallthrough keyword.

[…]

The case keyword can be used in for loops just like in switch cases.

case can also be used with guard, although only wildcard and identifier patterns work with for and guard.

Sandboxing Impression

Steven Vandeweghe:

Had to sandbox Impression (Mac) to release an update with 1 tiny bug fix. Result: it now seems to have tons of bugs that I can’t reproduce.

It doesn’t look like the sort of app that would be operating near the edge.

Cross-Platform UI in GitHub Desktop

Rob Rix:

Although the overall flow and architecture are shared, the implementations are often quite different. For example, although both platforms use WebKit, the bridging APIs are very different.

On OS X, the JavaScriptCore APIs allow us to pass arbitrary objects, functions, and arrays between Objective-C/Swift and JavaScript. Native code can call methods on JavaScript objects, and JavaScript code can call methods on native objects, without any special handling. We can also define protocols to specify which properties of our objects should be bridged.

CefSharp, on the other hand, does not bridge arrays or functions. JavaScript objects can call methods on native objects, but not on the properties of native objects. Native objects cannot call methods on JavaScript objects; you ask the ChromiumWebBrowser to evaluate a string of JavaScript source instead. Since the comparison graph is largely asynchronous, requiring both callbacks and arrays, this motivates a set of JavaScript shims baked into the comparison graph at build time.

GitUp 1.0 Is Open Source

GitUp (tweet):

GitUp is a bet to invent a new Git interaction model that lets engineers work quickly, safely, and without headaches. It’s unlike any other Git client out there from the way it’s built (it interacts directly with the Git database on disk), to the way it works (you manipulate the repository graph instead of manipulating commits).

[…]

GitUp is built as a thin layer on top of a reusable generic Git toolkit called “GitUpKit”. This means that you can use that same GitUpKit framework to build your very own Git UI!

Previously: GitUp 0.7.

Thursday, August 20, 2015 [Tweets]

Acorn 5

Big upgrade to my favorite image editor:

Shape Processors are filters for shape layers, which will move and tweak and generate and adjust shapes for you. And best of all, they are non-destructive and stackable (just like Acorn’s filters).

[…]

This is a lot more snapping going on now. Snap to Grid, guides, shapes in layers, other layers, selections, canvas bounds, etc.

[…]

Levels and Curves joins all the other non destructive filters—this is pretty awesome. You can use Levels and Curves on shape layers, even combine in the same filters list, tweaking both at the same time, and add a Curves filter multiple times to the same image.

[…]

We fixed hundreds of minor bugs. Bugs that built up over the years that very few people ever encountered, like “the shortcut key for zooming in doesn’t work when the keyboard layout is set to Dvorak - Qwerty ⌘”. So we fixed pretty much all of those. It took months and months of work, it was super boring and mind numbing and it was really hard to justify, and it made Acorn 5 super late. But we did it anyway, because something in us felt that software quality has been going downhill in general, and we sure as heck weren’t going to let that happen to Acorn. So we took a long break from adding features and just fixed stuff.

And if you reported one of these bugs that was fixed in Acorn 5 and we haven’t already sent you a license—let us know and we’ll make you one. (See, another good reason to report any bugs you find—free stuff!).

Gus Mueller:

But wait - Acorn already has Curves and Levels, right? Yes, but in Acorn 5 they are baked into the existing filter chain. So now you can add Levels to your Curves and then a blur and then why not add Curves again after that and finish with a Drop Shadow filter? Then save the file and open it up again and remove the second Curves because that’s just too much what were you thinking? And then you realize Curves and Levels are now non-destructive and that’s amazing.

I like the way the documentation is done, e.g. Shape Processor, Levels, Curves.

There’s no upgrade pricing, presumably because of the Mac App Store:

For a limited time (until the end of September, 2015) we are offering Acorn at a sweet discount price of $24.99. This discount is available to both new users and previous users of Acorn. When October rolls around Acorn will bump its price up again.

Go 1.5

Andrew Gerrand (comments):

The compiler tool chain was translated from C to Go, removing the last vestiges of C code from the Go code base. The garbage collector was completely redesigned, yielding a dramatic reduction in garbage collection pause times. Related improvements to the scheduler allowed us to change the default GOMAXPROCS value (the number of concurrently executing goroutines) from 1 to the number of logical CPUs. Changes to the linker enable distributing Go packages as shared libraries to link into Go programs, and building Go packages into archives or shared libraries that may be linked into or loaded by C programs (design doc).

[…]

The only language change is very minor, the lifting of a restriction in the map literal syntax to make them more succinct and consistent with slice literals.

The standard library saw many additions and improvements, too.

Tonic: Data Visualizing REPL for Node

Tonic (via Wolf Rentzsch, comments):

Tonic has an entire host of object viewers to help you visualize your data. From high level views like graphs and maps, to low level hexadecimal inspectors, you can pick and choose the best way to look at your data after creating it.

[…]

Time traveling in Tonic allows you to rewind your work to a previous point and pick up where you left off. That's because your work is checkpointed after every execution.

[…]

Tonic has built-in support for ES7 async and await making it incredibly async friendly. Instead of fiddling with chains of callbacks, you can write your asynchronous node.js code in a linear and straight-forward way.

Wednesday, August 19, 2015 [Tweets]

Top 10 Worst C# Features

Eric Lippert (via Chris Lattner, comments):

When I was on the C# design team, several times a year we would have “meet the team” events at conferences, where we would take questions from C# enthusiasts. Probably the most common question we consistently got was “Are there any language design decisions that you now regret?” and my answer is “Good heavens, yes!”

This article presents my “bottom 10” list of features in C# that I wish had been designed differently, with the lessons we can learn about language design from each decision.

WebKit Backdrop Filters

Brent Fulgham:

The User Interface design language for iOS 7 and OS X Yosemite changed to incorporate some beautiful backdrop blur effects. This layering gives a sense of depth, while preventing detail from the content underneath from cluttering the foreground.

The following image shows the WebKit media controls on top of a video. Notice that you can see some of the background content through the frosted glass effect.

[…]

Until recently, there was no standards-compliant method for producing these kinds of effects. Many designers were forced to create the illusion of blurred backdrops using pre-rendered background content and carefully clipping and positioning these assets to achieve the desired effect.

The regular system media controls respect the “Reduce transparency” setting in the Accessibility preferences pane. The WebKit background filters do not.

Generic “Functions” in Objective-C

Arkadiusz Holko:

Since the only way to declare generic parameters and return values is through a class interface, we’ll wrap our map method in a new class[…]

[…]

AHKArrayMapper’s only method takes an array of InputType objects and a block mapping from InputType to OutputType. It returns an array of OutputType objects. The implementation doesn’t really differ from the one without generics, because generics aren’t available in implementation files[…]

Objective-C generics are useful for interfacing with Swift and for documenting APIs. I’m not sure that it really makes sense to code with them this way.

Creating a Kill-Switched VPN With PIA and Little Snitch

Matt Henderson:

PIA provides a kill-switch feature, but just like Cloak, enabling it will affect local-network services. I’ve discovered a solution, however, achieving the same functionality without affecting local-network services, through the use of Little Snitch—a Mac OS X application-level packet filter—and it’s support for automatic profile switching.

[…]

So, in summary, whenever my Mac is not connected to a VPN (with the exeption of mobile tethering as described below), my “Public (Kill Traffic)” Little Snitch profile is automatically selected, preventing all incoming and outgoing connections.

[…]

I have one other Little Snitch profile, unrelated to VPN connectivity, called “Mobile”. This profile is activated whenever my Mac is connected to my iPhone’s or iPad’s “Personal Hotspot”. The purpose of this profile is to minimize my iOS device’s data usage. As you can see from the screenshot, this profile kills traffic from apps like Dropbox and BitTorrent Sync.

Update (2015-08-21): Matt Henderson:

The [iVPN] app seemed to function just fine in terms of establishing a VPN connection, and the data rate was fine. But the UI did behave a bit wonky at times. For example, often when I’d open the app (after being logged in), the main information window continually displayed a spinner, as if it were stuck. The second issue I noticed was that it didn’t offer the feature provided by Cloak and PIA to auto-detect the best server for connection. Finally, I found that it didn’t offer a kill-switch—which, alone, wouldn’t have been a show-stopper, as I found a work around with Little Snitch.

[…]

Having read this article, Sam from iVPN reached out. In a very thoughtful email, he explained how BitPay’s platform currently doesn’t allow for sub-management accounts, and so in fact, only the main administrator (who has access to all the account’s funds) can issue a refund, and he explained that BitPay’s refund process has been very unpredictable. He also sent a few screenshots of their forthcoming update to their Mac client and it looks very good!

Ripping CDs and Backing Up Content Is Illegal in the UK

Ernesto Van der Sar (via Nick Heer):

The High Court recently overturned private copying exceptions introduced last year by the UK Government, once again outlawing the habits of millions of citizens. The Intellectual Property Office today explains that ripping a CD in iTunes is no longer permitted, and neither is backing up your computer if it contains copyrighted content.

[…]

The IPO specifically notes that copying a CD to an MP3 player is not permitted. This means that iTunes’ popular ripping feature, which Apple actively promotes during the software’s installation, is illegal.

Also, under the current law iTunes is actively facilitating copyright infringement by promoting their CD-ripping functionality. This means that the company could face significant claims for damages.

Caitlin McGarry:

But the British government is apparently not thrilled with the High Court’s decision. The IPO office told TorrentFreak that the government is “carefully considering the implications of the ruling and the available options before deciding any future course of action.”

And if you live in the UK and have copies of your music library on your computer like a normal human, don’t fret too much. Apparently the government is pretty sure that no one has been taken to court over CD-ripping for personal use.

Testing Swift’s ErrorType

Marius Rackwitz:

Further investigation via LLDB reveals that the protocol has some hidden requirements.

(lldb) type lookup ErrorType
protocol ErrorType {
  var _domain: Swift.String { get }
  var _code: Swift.Int { get }
}

It becomes clear how NSError fulfills this definition: it has these properties, backed by ivars, which Swift can access without dynamic dispatch. What is still unclear is how Swift’s first class enums can automatically fulfill this protocol. Perhaps there is still some magic involved?

[…]

Sure, you could catch it as any generic error and then manually check the fields _domain and _code, but there are more elegant alternatives.