Friday, July 22, 2016 [Tweets]

Xcode 8 Illegal Hard Links Prevent Cloning

After I installed Xcode 8 Beta 3, I could no longer back up my hard drive. SuperDuper reported errors like:

Error creating hard link /Volumes/HD Clone 14A/Applications/Xcode-beta.app/Contents/Applications/Accessibility Inspector.app/Contents/Frameworks/AccessibilityAudit.framework/Versions/A/Resources/en.lproj/AuditIssues.strings to /Volumes/HD Clone 14A/Applications/Xcode-beta.app/Contents/Applications/Accessibility Inspector.app/Contents/Resources/en.lproj/AuditIssues.strings for inode (null)

Cloning HD, error creating hard link for file in Xcode-beta.app.

At first I thought that the drive was damaged, but the error still occurred after reformatting it. SuperDuper’s Dave Nanian:

Structure became illegal (hard link into app bundle) in 10.10.3 - break link by duplicating file...

I assume they just did this in the latest beta. (It was previously an issue with Retrospect & Anaconda.)

Indeed, Xcode-beta.app does contain a hard-linked file:

ls -l /Applications/Xcode-beta.app/Contents/Applications/Accessibility\ Inspector.app/Contents/Frameworks/AccessibilityAudit.framework/Resources/en.lproj/
total 48
-rw-r--r--@ 2 mjt  staff   6141 Jul 14 18:08 AuditIssues.strings
-rw-r--r--@ 1 mjt  staff     42 Jul 14 18:08 Localizable.strings
-rw-r--r--@ 1 mjt  staff  10726 Jul 14 18:08 LocalizableOSX.strings

Note the “2” for “AuditIssues.strings”. Here are the two files with the same inode:

find /Applications/Xcode-beta.app/ -name AuditIssues.strings -print -exec stat -f "%i" {} \;
/Applications/Xcode-beta.app/Contents/Applications/Accessibility Inspector.app/Contents/Frameworks/AccessibilityAudit.framework/Versions/A/Resources/en.lproj/AuditIssues.strings
38530212
/Applications/Xcode-beta.app/Contents/Applications/Accessibility Inspector.app/Contents/Resources/en.lproj/AuditIssues.strings
38530212

The fix is to make the two files independent copies:

cd "/Applications/Xcode-beta.app/Contents/Applications/Accessibility Inspector.app/Contents/Resources/en.lproj/"
mv AuditIssues.strings AuditIssues.strings.old
cp AuditIssues.strings.old AuditIssues.strings
rm AuditIssues.strings.old

Now the files have different inodes:

find /Applications/Xcode-beta.app/ -name AuditIssues.strings -print -exec stat -f "%i" {} \;
/Applications/Xcode-beta.app/Contents/Applications/Accessibility Inspector.app/Contents/Frameworks/AccessibilityAudit.framework/Versions/A/Resources/en.lproj/AuditIssues.strings
38530212
/Applications/Xcode-beta.app/Contents/Applications/Accessibility Inspector.app/Contents/Resources/en.lproj/AuditIssues.strings
39006606

Update (2016-07-22): Mike Bombich (developer of Carbon Copy Cloner) on the similar issue with Anaconda:

This turns out to be an issue specific to *.app/Contents/PkgInfo and *.app/Contents/Resources/*.lproj files. OS X does not want to permit the creation of a hard link between one of these items in an application bundle to another file in a non-application-bundle folder. I was unable to find an explanation for this behavior in Apple’s documentation, nor in the source code for HFS or the OS X kernel.

Pixellating or Blurring Text Creates Identifiable Patterns

Kashmir Hill (via Nick Heer):

If you’ve ever pixelated an email address or blurred a phone number before putting an image onto the internet in order to protect someone’s privacy, I’ve got bad news for you: Researchers at the University of California-San Diego have found that the popular Photoshop redaction techniques are decodable such that the underlying text can be read.

The researchers were able to recover text from a variety of redacted screenshots that they found online, said computer science professor Hovav Shacham by email. They were, for example, able to figure out the blurred email address in this screenshot of a conversation between a corrupt DEA agent and the then-CEO of Bitcoin exchange Mt. Gox.

What Exactly Is “Compressed Memory”?

John Siracusa:

In Mavericks, the OS has one more option before it has to resort to swapping: compressed memory. Mavericks will find the least-recently-used data in memory and compress it, usually to about half its original size. Et voilà, more free memory.

[…]

Memory compression is a triple play for Mavericks. It’s a performance win; compressing and decompressing data in RAM is much faster than reading from and writing to disk, even an SSD. It’s an energy win; the less time spent moving data between RAM and disk, the more time the system can spend in its idle state. And finally, it’s a capability win; Mavericks can handle much more demanding workloads than previous versions of OS X before crying uncle.

This seems like a great feature, but I’ve never fully understood how it’s reported in Activity Monitor. What do the “Compressed Memory” numbers for each process and the “Compressed” total actually mean? This AskDifferent post lists the columns in Activity Monitor, but commenter James K Polk has the same questions as me:

If the activity monitor says a given process uses 621.4 MB of memory and 615.4 MB of compressed memory, does that mean that the process is really only using up 6 MB of memory? Or that 615.4 out of 621.4 MB was compressed down to some unspecified size? Or something else?

In other words, does a high number for Compressed mean that the compression has been effective or that the system is nearing capacity because most of what can be compressed already is?

It’s also not clear how compressed memory interacts with the other reported numbers. For example, why did Siracusa’s App Memory go down when the Compressed memory went up? I would have expected that App Memory would include the part that’s compressed.

And, presumably the memory that is paged out to disk is compressed. Does Swap Used take that into account?

Sandboxing Wisdom

Daniel Jalkut (tweet):

[I’ve] managed to produce two versions of my app, one of which causes the sandbox container to be apparently unwritable to the other after running! Specifically, preferences are not saved and console messages indicate an attempt to write preferences outside the host app’s sandbox.

[…]

These kinds of issues scare the bejeezus out of me because I really fret my users running into data migration problems after I ship an update, and because the relative opacity of the sandboxing system makes a lot of issues very hard to debug.

Daniel Jalkut:

In a nutshell: for the past 4 years or so, sandboxing has been a massive, amorphous “bug” that I have to wrap my head around. So, so tired.

Rarely a day goes by when I don’t worry that I made a huge mistake betting on sandboxing and MAS for the long run.

Peter Maurer:

Answer from a very tired sandbox wrangler: Don’t do it. Don’t waste your time on custom settings, etc. Instead, import once…

…via open dialog automatically, then make additional imports (for whatever reason) available via menu or preferences.

Ilja A. Iwas:

We released GarageSale 7 this week, still sandboxed, but won’t be submitted to the MAS. Ah, that sweet feeling of relief.

Daniel Jalkut:

This tool [asctl] appears to offer extensive insight into the sandbox’s understanding of containers. I wish I had discovered it earlier!

Apple doesn’t seem to have posted the asctl man page, but this online version has the same date stamp as the man page on my 10.11 system.

Thursday, July 21, 2016 [Tweets]

“This Regular Expression Has Been Replaced With a Substring Function”

Stack Exchange (Hacker News):

The direct cause was a malformed post that caused one of our regular expressions to consume high CPU on our web servers. The post was in the homepage list, and that caused the expensive regular expression to be called on each home page view. This caused the home page to stop responding fast enough. Since the home page is what our load balancer uses for the health check, the entire site became unavailable since the load balancer took the servers out of rotation.

[…]

The regular expression was: ^[\s\u200c]+|[\s\u200c]+$ Which is intended to trim unicode space from start and end of a line. A simplified version of the Regex that exposes the same issue would be \s+$ which to a human looks easy (“all the spaces at the end of the string”), but which means quite some work for a simple backtracking Regex engine.

[…]

This is not classic catastrophic backtracking (talk on backtracking) (performance is O(n²), not exponential, in length), but it was enough. This regular expression has been replaced with a substring function.

Tuesday, July 19, 2016 [Tweets]

AppleScriptObjC in Script Debugger 6

Shane Stanley:

The most important new AppleScriptObjC feature, and the most obvious, is how Script Debugger displays results. Instead of «class ocid»..., you will see much more.

[…]

First, although case matters in AppleScriptObjC, code completion is case-insensitive. You can type NSS or nss, and get the same result; the correct case will be inserted. You can also use the tab key within the completion list; this is very helpful where there are multiple methods with similar names.

[…]

Script Debugger includes terminology for the following frameworks: Foundation, AppKit, Quartz, AVFoundation, AddressBook, Contacts, CoreImage, CoreLocation, CoreWLAN, EventKit, JavaScriptCore, MapKit, OSAKit, and WebKit. The information is collated from the frameworks themselves and from header files, with some filtering applied to remove many methods that cannot be used from AppleScriptObjC.

[…]

Finally, there is an important limitation. Script Debugger runs scripts on a background thread, so any code that needs to be run on the main thread needs to use the method performSelectorOnMainThread:withObject:waitUntilDone: to do it. If not, you are likely to freeze or crash Script Debugger.

Previously: Script Debugger 6.

SQLITE_ENABLE_SQLLOG

Scott Perry:

PSA: SQLite on Sierra/iOS 10 is built with SQLITE_ENABLE_SQLLOG, which makes it easy to create replayable SQL logs

SQLite:

This file contains experimental code used to record data from live SQLite applications that may be useful for offline analysis. Specifically, this module can be used to capture the following information:

  1. The initial contents of all database files opened by the application, and
  2. All SQL statements executed by the application.

The captured information can then be used to run (for example) performance analysis looking for slow queries or to look for optimization opportunities in either the application or in SQLite itself.

[…]

At runtime, logging is enabled by setting environment variable SQLITE_SQLLOG_DIR to the name of a directory in which to store logged data.

MacKeeper Threatens YouTube Video Maker

Mike Wuerthele:

Infamous software developer MacKeeper has demanded that four videos critical of its maligned tune-up utility suite be removed from the internet, threatening the teenager behind the videos with $60,000 in court costs and legal fees.

[…]

In August 2015, ZeoBIT, creators of MacKeeper, agreed to a settlement in 2015 to put $2 million in a compensation fund to cover attorney fees, refunds and administrative costs to U.S class action claimants who purchased MacKeeper prior to July 8, 2015.

The complaint alleged that “ZeoBIT intentionally designed MacKeeper to invariably and ominously report that a user’s Mac needs repair, and is at-risk due to harmful (but fabricated) errors, privacy threats, and other computer problems, regardless of the computer’s actual condition.” Court documents state that 513,330 people are registered owners of the software in the U.S.

Previously: MacKeeper.

Apple Music Learns From iTunes Match

Kirk McElhearn:

When Apple Music was released just over a year ago, Apple also debuted iCloud Music Library, a way of storing your iTunes library in the cloud. There were two ways to seed the cloud, either with iTunes Match or Apple Music. If you were an iTunes Match subscriber, matching your songs in your local library to your cloud library was done one way, and if you were just an Apple Music subscriber, matching was done differently.

This created some confusion about the way tracks were matched and stored in iCloud Music Library. Now, Apple is changing this, and will use the same matching method for both services. The company said that Apple Music now uses acoustic fingerprinting and provides matched files without digital rights management (DRM), or copy protection, just like iTunes Match.

Before, if you only had Apple Music, you only got the problematic metadata-based matching.

John Gruber:

I’m sure there are reasons for the way things are, but from the outside, combining iTunes Match and Apple Music should have been there from day one.

See also: Jim Dalrymple, iMore.

Monday, July 18, 2016 [Tweets]

The Strange Case of the System Preferences Window Width

Tim Schröder:

Apparently, the System Preferences window on my computer running OS X El Capitan was considerably wider than 668 (or even 595) pixels. Some research later it turned out that the width of the System Preferences window depends on the system language: The window will be 668 pixels wide when English is the primary language, but will have a different width for other languages. For example, with German set as primary language, as it is on my computer, the window is 762 pixels wide.

[…]

While Apple’s preference panes that come with OS X dynamically adjust their width to the actual width of the System Preferences window, this is not true for any custom preference pane, that will instead be displayed centered with more or less wide blank margins.

Medium URL Fragment Tracking

sime_vidas (via Ole Begemann):

Notice how this URL does not contain a hash (at the end). If you visit this URL, a hash will be added to the URL after the page loads. The hash value is some jumbled combination of letters and digits. What’s the purpose of this hash?

harv3st:

The idea is that when you share that page you will share it with the hash at the end. The visitors of the link you share will have their own hash generated to track their referrals. Medium will be able to see who visited the link that you shared, and build a tree of referrals (who the users you referred shared it with, who they shared it with etc). It’s a great metric to use in analytics when looking at user acquisition through social channels.

blaxus:

I hate this, I can’t tell you how many times I get a duplicate bookmark because I thought I didn’t have the article already in my bookmarks.

Exponential Time Complexity in the Swift Type Checker

Matt Gallagher:

But the line doesn’t get past the Swift type checker. Instead, it emits an error that the expression is too complex to solve. It doesn’t look complex, does it? It’s 5 integer literals, 4 addition operators, two negation operators and a binding to a Double type.

How can an expression containing just 12 entities be “too complex”?

[…]

If you don’t typically combine these features in your code, then you’re unlikely to see the “expression was too complex” error. However, if you are using these features, it isn’t always straightforward to suddenly stop. Mathematics code, large “function”-style expressions and declarative code are easier to write with these features and often require a complete rethink to avoid them.

[…]

A note about this approach though: unlike other languages, Double(x) is not equivalent to x as Double in Swift. The constructor works more like another function and since it has multiple overloads on its parameter, it actually introduces another overloaded function into the search space (albeit at a different location in the expression).

[…]

Posts like this: “[swift-dev] A type-checking performance case study”, indicate that the Swift developers believe resolving function overloads in the type checker is inherently exponential. Rather than redesigning the type checker to eliminate exponential complexity, they are redesigning the standard library to try and skirt around the issue.

Joe Groff:

Changing stdlib interfaces is done with an eye toward fixes like SE-0091 that mitigate inherently exponential work.

Most of the proposals around function labels and types are trying to kill type checker tech debt too.

“Rewrite the type checker” is up there on list of things we want to do.

Previously: Speeding Up Slow Swift Build Times, Swift 1.0 Performance and Compilation Times, Slow Swift Array Type Inference, Swift Type-checking Performance Case Study.

The Secret Life of Types in Swift

Slava Pestov:

I’m going to attempt to start by giving an overview of how types work in Swift, from the parser down to the lower layers of code generation in the frontend. Swift is a strong, statically-typed language with an advanced type system more reminisicent of functional languages such as OCaml and Haskell than something like C, so this seems like as good a place to start as any.

[…]

Types in Swift form a mini-language in of themselves, with a grammar consisting of nominal types as leaves, and structural types such as function types as interior nodes. Types are formed from TypeLocs and TypeReprs early on in semantic analysis. Further down in the compiler, sugar is removed and types are canonicalized, simplifying structural walks and equality comparisons. Substitution is a fundamental operation frequently used in the implementation of generics, and it is important to think about the role of types and declarations when performing substitutions for member access. Various higher-order operations simplify tedious boilerplate when manipulating types throughout the compiler.

Slava Pestov:

Now, let’s peel back a layer and dive into the type system of SIL, the Swift Intermediate Language. SIL adds a layer of detail missing from formal types, drawing a distinction between values and addresses, and making function types more explicit by introducing explicit annotations for argument and return value conventions.

[…]

At this point, we still cannot compile our code, but at least we can detect a type mismatch at the level of SILFunctionTypes, instead of just mis-compiling incorrect code. A situation where the formal types of the expressions match, but the lowered types do not is called an “abstraction difference”. Abstraction differences are handled by SILGen wrapping the substituted function value inside a re-abstraction thunk.

The re-abstraction thunk forwards arguments, calls the function, and forwards the result, taking care to handle any abstraction differences in the arguments and results. If the substituted argument is trivial but the original argument is passed indirectly, the thunk will load the value from its address and pass it to the substituted function. Similarly, if the substituted result is trivial but the original result is returned indirectly, the thunk takes the substituted result value, and stores it into the indirect return address given to the thunk.

Sunday, July 17, 2016 [Tweets]

Swift Classes to Be Non Publicly Subclassable by Default

SE-0117 (original, revision 1, revision 2):

The major observation here is that not all classes make sense to subclass, and it takes real thought and design work to make a class subclassable well. As such, being able to subclass a public class should be an additional “promise” beyond the class just being marked public. For example, one must consider the extension points that can be meaningfully overriden, and document the class invariants that need to be kept by any subclasses.

Beyond high level application and library design issues, the Swift 1 approach is also problematic for performance. It is commonly the case that many properties of a class are marked public, but doing this means that the compiler has to generate dynamic dispatch code for each property access. This is an unnecessary performance loss in the case when the property was never intended to be overridable, because accesses within the module cannot be devirtualized.

Chris Lattner:

As expected, this proposal was extremely polarizing, with valid arguments on both sides. The opinions held by supporters and opposers are held very strongly, and hundreds of emails were generated in a healthy debate about this topic.

[…]

On the first point, there are three related arguments against SE-0117:

First is that clients of Apple frameworks often choose to subclass classes that Apple publicly documents as being “not for subclassing”, as a way of “getting their job done,” typically as a way to work around claimed bugs in Apple frameworks. The core team and others at Apple feel that this argument is analogous to the argument that Swift should “support method swizzling by default”. Swift loves dynamic features, but has already taken a stance against unanticipated method swizzling, by requiring an API author to indicate where they allow method swizzling with the ‘dynamic’ keyword.

Yes, it’s absolutely analogous. It’s become obvious that “unanticipated” dynamism is not something that Apple wants to support with Swift. It’s clearly not Swifty, if by Swifty you mean the vision of the core team.

Second is that clients of some other public API vended by a non-Apple framework (e.g. a SwiftPM package) may end up in a situation where the framework author didn’t consider subclass-ability, but the client desires it. In this situation, the core team feels that a bigger problem happened: the vendor of the framework did not completely consider the use cases of the framework. This might have happened due to the framework not using sufficient black box unit testing, a failure of the imagination of the designer in terms of use cases, or because they have a bug in their framework that needs unanticipated subclass-ability in order to “get a job done”. Similar to the first point, the core team feels that the language is not the right place to solve this problem. Instead, there is a simple and general solution: communicate with the framework author and get them to add the capabilities that you desire.

Yes, there’s a bigger problem, and, yes, the language can’t “solve” this problem. That doesn’t imply that the language should forbid building a temporary workaround. In my view, the language should be helping to get the job done, not enforcing an idealized solution that may not even be possible because the vendor may be busy, uncooperative, or no longer available.

Third is a longer-term meta-concern, wherein a few people are concerned that future pure-Swift APIs will not consider subclass-ability in their design and will accidentally choose-by-omission to prevent subclass-ability on a future pure-Swift API (vended by Apple or otherwise). The core team feels that this is an extremely unlikely situation for several reasons. First of which is that it heavily overlaps the first two concerns. More significantly, any newly-designed and from-scratch APIs that are intended for Swift-only clients will make use of a breadth of abstractions supported by Swift—structs, enums, protocols, classes.

Indeed, this proposal is just one piece of a large trend. Swift is chipping away at dynamism for classes: subclassing, swizzling, hiding private classes and private methods. And the future, it appears, is APIs that rely more on structs, enums, and protocols, which are even more static. There are definitely some benefits to this direction, but I am concerned that it will lower app quality over the long term. This specific proposal may not have a huge impact because it affects neither Objective-C APIs (past) nor non-class Swift APIs (future).

To reiterate, as a summary, the core team agrees with conviction that it is the right default for public classes to be non-subclassable outside their module, unless they carry some additional indication by the API author that the class was designed to be subclassed.

Here’s my slightly exaggerated summary of the two points of view:

Me: I agree that dynamism shouldn’t be abused, but there are library bugs and limitations, and sometimes we need these tools to cope with them. I hate coding these workarounds and would love to remove them and unclutter my code as soon as the underlying issues are resolved. But bugs that affect the customer are much worse than temporary ugly code. Of course, ideally library vendors wouldn’t ship any bugs, but this is the real world. Nudging the API author to “think carefully” is well-intentioned but naive. The proposed solution is worse than the problem.

Apple: Making library vendors opt into dynamism will encourage them to think more about their designs. They will foresee how their APIs will be used. Making it impossible for developers to work around library bugs will foster communication with the vendor, who will then fix them. The fixing will be easier because the vendor won’t have to take into account developers’ workarounds. We don’t particularly care if your app is broken for months or years while waiting for a bug to be fixed. Developers won’t feel pressured to work around library bugs because competing apps will be subject to the same restrictions.

Here are some of the more interesting comments from the discussion:

Kevin Lundberg:

I do not want to be constrained by authors of libraries or frameworks into interacting with a system in only the ways they forsee. By making the default be non-subclassable, if a designer does not put thought into all the ways a class can be used then I as a consumer of the library am penalized.

Another point I can think of is mocking in tests. I’m unaware of any fully featured mocking solution in swift, and subclassing a class to override methods for mocking purposes is one way to make unit tests work with third party dependencies. If a class was not designed for subclassing, then writing tests where the class’s behavior needs to be suppressed would not be possible.

[…]

I’ve had issues before when working with third party C# code where the author didn’t declare a method as virtual, but the problem I was trying to solve required me to override that method. Luckily the code was open source, so I just embedded and edited the source into my project instead of using the prebuilt binaries, but that becomes a maintenance headache, and it is not possible for components that do not make the source available.

L. Mihalkovic:

Can’t really help for feel like it is training wheels all around… or padlocks on every kitchen cupboards.

Kevin Lundberg:

It’s not possible to accidentally override a method like it is in java or objective-c, so the proposal won’t help people who might accidentally override something. If a developer tries to override a method or class they probably have a specific reason in mind for doing so, and taking away the options that this ability presents, by nature of it being the default behavior, doesn’t sit well with me as it has the potential to take away a good tool from my toolbox.

I agree that API authors should have the power to restrict this dimension of a type’s usage, but I feel that it should be a conscious choice to do so.

Karl:

I really enjoy designing elegant, well-defined APIs and this behaviour for classes has bothered me for some time.

On the other hand, I have also subclassed things that weren’t meant to be subclassed (e.g. I believe UITabBar was an awkward one back in the day, and UINavigationController has so many broken behaviours it’s almost a requirement to subclass and patch it, even though I believe Apple disapproves). I could fall back to Objective-C, but that’s an implementation detail. In some theoretical future with an all-Swift UIKit, what do I do about those issues?

After thinking about it, I decided that in this theoretical future, no App would be able to use those hacks, and so all Apps would have the same broken behaviours and degrade the quality of the platform to such an extent that Apple is forced to do something about it. Ultimately, that’s exactly what we want; they need to see broken Apps everywhere in order to prioritise fixes. That improves code quality all-around.

Tino Heth:

I can’t fight the feeling that many fans of ideas like this believe that good designed libraries come for free by simply adding restrictions — which, at least in my opinion, just isn’t true: No matter what the defaults are, good libraries are hard to build, so I predict this proposal would not only fail in increasing framework quality, but also will make it much harder for users of those frameworks to work around their flaws, which are just a natural part of every software.

Michael Peternell:

I think it’s a step backwards. […] It’s not bad to allow sealing of classes. I don’t see real value in it though. And “sealed” should not be the default. Either the class if final or not: for me that’s a valuable distinction. “sealed vs. unsealed” is not.

Paul Cantrell:

In all the OO languages I’ve used, classes are open by default. That raises a question: is this really a good idea? Aren’t we ignoring established precedent? What about all the unauthorized subclassing we’ve done in the past?

I’m sympathetic to those accustomed to Objective-C, Ruby, Javascript, Python, and other languages with more fungible type systems who argue that it’s unreasonable to expect us all to use classes only as library authors intend. Monkey patching has saved many a day, they’d say. And it’s true, it has! I rely on it.

My counterargument: the ecosystem is changing.

[…]

The big exception to this is Apple itself, and the direction of this proposal implies a large cultural shift in how Apple deals with its developer community. Having the Swift language so aggressively prevent the dubious, brittle, bad-idea-but-it-gets-the-job-done workarounds that the Obj-C runtime allowed means that Apple’s platforms are going to have to be more consciously extensible, more transparent in their design decisions, and more responsive to unanticipated needs.

Tino Heth:

With “sealed by default”, the situation changes: Users are protected from some simple bugs, but nonetheless, they’ll encounter situations where the library doesn’t do exactly what they want. So, you take a look at the source, find the problem, and fix it. It’s no bug at all, it’s just a tiny degree of freedom that is missing because it wasn’t important to the author. You can create a pull request as well, but it doesn’t offer a real improvement to the author, who is already busy with dozens of similar requests by other users -> you end up with a custom branch with all the housekeeping associated with it.

So overall, I’m quite sure that the proposal won’t improve software quality, but rather degrade it.

Ricardo Parada:

I am afraid that developers will not take the time to specify which methods are overridable resulting in libraries that are difficult to patch, extend.

In my 26+ years of object-oriented design and programming (other languages, Objective-C since 1990 and Java since 2001) I have worked with object oriented libraries and subclassed methods that the authors probably never anticipated. I have been able to fix problems, enhance classes by creating subclasses with fixes and enhanced behavior.

In java for example I have seen that sometimes I would have been able to fix bugs or enhance the existing classes had the author not chosen a method to be protected or private. Sometimes they had a good reason but sometimes they didn’t. Is have been able to survive using an awesome library that was discontinued and end-of-lifed thanks to subclassing that has allowed me to fix problems and enhance over the years as the Java language kept evolving.

Jakub Suder:

I agree that subclassing library classes that were not explicitly planned to be subclassed might sometimes lead to bugs. But just because a technique or feature of a language allows you to sometimes make mistakes, it doesn’t mean it should be completely disallowed. By this logic, we’d have to remove all instances of "!" any anything related to pointers from Swift. It’s possible for a feature to allow you to shoot yourself in the foot, and still be useful at the same time.

[…]

I don’t think the problem is significant, and I’m afraid the proposed solution is worse than the problem itself.

Jonathan Hull:

I don’t think this proposal will achieve its stated objective of forcing people to think about subclassing more. It will just add confusing boilerplate.

Things like Swift optionals work well because they make the (often forgotten) choices explicit in the context that they are used. In the world of Human Factors, we call it a forcing function. This proposal has the inverse structure, and will be ineffective, because the “forcing” part of it shows up in a different context (i.e. trying to use a framework) than the decision is being made in (writing the framework). This type of thinking leads to things like Java and the DMV.

[…]

Those who were prone to be thoughtful about their design would have been anyway. Those who are not thoughtful about their design will just leave these annotations off… leaving us with no recourse to extend/modify classes. When people complain, they will add the annotations without actually thinking about the meaning (i.e. stack overflow / the fixit tells me I need to add this word to make the compiler happy). All this does is put framework users at the mercy of the framework writers.

Brad Hilton:

I […] give a strong, strong, strong -1 to this proposal. To make classes non-subclassable by default is only going to lead to unanticipated pain and frustration. Also agree with other comments that subclassable and overridable conflate access control with class behavior. If we want to make it possible to define a class as non-subclassable to external users, I’d agree to something more consistent with existing swift access control like public(final) as has been proposed by other commenters. However, I agree that making classes final by default is a bad idea that will create a larger problem that it solves.

Jean-Daniel Dupas:

I can’t count the number of times it save my hours [to be] able to override arbitrary classes and methods.

Sometimes to simply add log point to understand how the API work. Other times to workaround bugs in the library. Or even to extends the library in a way that the author did not intent in the first place, but that was perfectly supported anyway.

I already see how libraries author will react to that new default. They will either don’t care and mark all classes as subclassable, or find to burdensome to get subclassability right and prohibit subclassing all classes.

Jean-Daniel Dupas:

Nonetheless, being able to subclass any class allowed me to solve a bunch of very bad memory leaks in the new NSCollectionView implementation, and made it usable for my project.

Thinking than you will have to work only with perfectly design libraries without any bug is utopian. And thinking you can predict every usages of your library by users is short sighted IMHO.

John McCall:

I sympathize with the argument about wanting to fix bugs and add features via override, but that’s never been maintainable in the long term; you always just end up with superclasses that everyone is terrified to touch because every subclass has its own invasive “fixes”, and that’s even when working within a single codebase. With libraries, you can pretty quickly get locked in to a specific version because your customizations don’t work with new releases; either that, or the maintainer just decides that they can’t fix of their mistakes and so goes off to rewrite it from scratch. Either way, it’s not good for the ecosystem.

Jeremy Pereira:

Thirdly, this is a huge breaking change. Not only is it a breaking change, but for a lot of people, the breakages will be outside of their control. Consider if I publish a module with a class with public methods and you subclass it in your code. Once this change is implemented, my code will still compile and pass its unit tests but your code is now broken and you are dependent on me changing my code to fix your code.

Tino Heth:

Defaults matter, because they transmit a message:

Every rule and obstacle we add to Swift is a statement that says “we favor bureaucracy over freedom”, and this will affect the community evolving around the language.

When you use a library in a way that wasn’t anticipated by its author, you’ll ran into issues occasionally; nonetheless, I think we should struggle for an open ecosystem that encourages others to experiment and fail, rather than to limit their possibilities in a futile attempt to protect them.

Garth Snyder:

I’ll just note that this proposal reminds me of the fortune file entry, “Whenever you see a sign that says ‘no exit’, it means there is an exit there.”

Specifically, under this proposal, whenever you see a nonsubclassable, non-final class (which I suppose would in fact be any class not explicitly marked as subclassable), it would mean that the library implementor IS in fact subclassing it. Otherwise, it would just be final. Therefore, it’s by definition a perfectly reasonable class to specialize. The implementor just doesn’t want YOU doing it.

Maybe the implementor has a very good reason for this. But in the modal case, probably not.

[…]

There should absolutely be a way to say “don’t subclass this.” But do you really need anything more than a comment that says “don’t subclass this?” Perhaps as a compromise, and as a concession to the value of automated checking, this feature could be reformulated as a warning system. A class marked as nonsubclassable could be extended only be including a corresponding acknowledgment keyword in the extending class, a kind of Swift version of -IHaveBeenWarnedThatAPFSIsPreReleaseAndThatIMayLoseData.

Paul Norton:

Because of that experience, I am fully convinced that library authors will never imagine all the ways developers will use a library’s API.

[…]

I also think it would eventually force a second change; some sort of override to the default, at which point we’ve extended the language further to get closer to where we started.

Andre:

Personally, Im not against sealed by default, but I think there are cases where closed source libraries have certain cases where workarounds are necessary, and just sealing by default will prevent those cases.

One could say, “well just use an open source one, or change vendors” but its not that easy in The Real World™ where we get certain SDKs shoved down our throats by the suits… and while that may be a separate issue to the one at hand, its still a problem that won’t resolve itself by simply locking down things…

In my own case, Ive fought with NSBrowser / NSTreeController in the past and the only way to resolve things was to subclass (and no, waiting 1 or 2 years for a fix is not acceptable if you already have a product in the wild).

Jonathan Hull:

Please stop saying that this proposal will bring more consideration to the design of libraries. It isn’t true. I haven’t even seen an argument for why it would be true, it is just taken for granted that it is true.

[…]

It sounds good, but at the end of the day, people are human and they will make mistakes. Best to either catch those mistakes in the context where they happen or to mitigate the effect of it. This proposal basically forces you to feel the full effect of other people’s mistakes (thinking that it will discourage them from making them in the first place).

[…]

The current proposal will only cause massive problems down the line, IMHO. We will find an escape hatch is needed, but we will have made optimizations based on assumptions of finality which prevent us from easily adding one.

L. Mihalkovic:

There are IMO no advantages to sealing by default. If there were, I cannot imagine how they can have so consistently eluded the designers and maintainers of so many great OOD languages in the last 30 years. Does it mean it is just a matter of time for the core team to take it the c++ standardization committee to make sure C++ gets enhanced the same way?

L. Mihalkovic:

After 30 years of Objc’s msg dispatching being touted as not a performance problem, all we hear for the last couple WWDC (did you pay attention to the ‘they are getting it’ during one of the session) is how much every single dynamic dispatch must be chased out of our systems, culminating with this ‘seal by default is best for you’. Why can’t developers [writing] code be made responsible for writing well or not?

Jonathan Hull:

There is also a dangerous difference between helping the programmer catch mistakes (e.g. don’t accidentally subclass the wrong method) and trying to prevent them from coding in a style you disagree with. I have been seeing far to many proposals of the second variety of late.

let var go:

It is the opposite of nearly every other OOP language’s behavior and the opposite of what anyone will expect who is coming to Swift after doing any OOP programming anywhere else. While I believe that Swift should be free to buck the trends of other languages where there are significant advantages, changing something this fundamental will introduce a new learning curve for even experienced programmers. The advantages better be significant, otherwise you are introducing a frustrating quirk into the language without any great benefit in exchange. But the advantages of default non-subclassability are marginal at best.

[…]

The developers who don’t make careful design decisions will just go with the default - in this case they will just leave the default in place, and their public classes will not be subclassable. That doesn’t improve anything, it just makes sloppy, poorly written code harder to fix in the off-chance that you are stuck working with it. In other words, quality will not improve, but productivity will suffer, because it will be harder to develop workarounds for the problems that will inevitably appear in even the best-designed APIs.

[…]

But this whole issue of default non-subclassability doesn’t fall into that category of “safety” at all. It doesn’t help a programmer produce safer code. The same hidden flaws will persist whether non-subclassability is the default or not. The difference is that those same hidden flaws will be more difficult to deal with after the fact.

Colin Cornaby:

The “final should be default because adding final after the fact is destructive” arguments are interesting, but ultimately not convincing to me. If you thought your class was safe for subclassing, but it ultimately wasn’t, this solves nothing. You’ll mark your class as subclassable, and you will ship it, and there will be issues, but it will still be too late to take things back. If you know your class is not safe for subclassing, you should mark it as final. There is no advantage here in that scenario.

This is all part of building a safe public API. Public API design can be difficult, but if you don’t understand safe subclassing designs, you are likely to miss the issues and mark your class as subclassable and ship it anyway. Again, the best way to tackle this is to find better ways to surface the issues. Making final the default still doesn’t solve the core issues of people not understanding the right design.

Jonathan Hull:

My point is that you are completely ignoring an entire class of risk that has a real-world $$$ cost. Every time I have to use a framework under this proposal, I am now completely at the mercy of the author. In the case of open source frameworks I can at least make a fork, but for closed source frameworks (often from large companies where us using their framework has been negotiated by the bosses) you have now just added weeks to my development cycle while I wait for big-company-who-doesn’t-really-care-that-much to update their stuff.

[…]

Are you offering to explain to my boss/client why I can’t add the feature in a reasonable timeframe like I can with Objective C frameworks? That it may not even be possible now in Swift even though the Android guy just did it in a few hours?

Do you know what I am going to tell my boss/client? “Don’t use Swift for frameworks” and “Try to avoid partnering with companies that have Swift frameworks”. “It is too much of a risk”. “We are giving them too much control over the future of our product…” I mean, it even affects the prices that companies can charge for crappy frameworks. If I am asking for a bunch of features that I need them to add to provide a basic feature, that affects negotiations/price (vs a world where I can add it myself if needed). Sealed-by-default gives them leverage.

Tony Allevato:

The argument shouldn’t be “we need open subclassing or we can’t fix broken APIs”; that’s a false choice. It should be “we need something to fix broken APIs”, and that “something” should be proposed and the need for it should be argued in its own right.

David Sweeris:

-1 for this proposal, but +1 for solving the issues it raises

Regardless of what ends up being the defaults, I’m a very strong -1 on conflating visibility and subclassability/extendability.

Jon Akhtar:

I completely agree, the programmer should have as much power as we can give them, even if it means allowing them to shoot themselves in the foot, because at the end of the day Swift isn’t an academic exercise, it is a real world programming language, so it should be optimized for solving real world problems not having some kind of technical, philosophical, and stylistic perfection when those come at the cost of the former.

Update (2016-07-17): Daniel Jalkut:

It’s absurd to imagine you can predict all valid subclassing patterns. […] Apple, nor any framework provider, can provide functionality sufficient to cover the breadth of innovation. Clever hacks built the industry.

To be clear, although the proposal was “returned for revision,” it is essentially accepted. It’s just the syntax that’s being debated now (e.g. changing subclassable to open).

Update (2016-07-18): Friedrich Markgraf:

Same issue with Apple’s removal of Xcode plug-ins it prevents unanticipated innovation

Marco Scheurer:

Another nail in the coffin. Swift: “No programmers except myself should be trusted”

Daniel Broad:

If objective-c had been like this we would have had only default coloured navigation bars until ios4.

Casey Liss:

I’m… not keen on the idea of final by default.

Do not want.

Ilja A. Iwas:

This is why you don’t let compiler engineers control the fate of your computing platform(s)

Orta Therox:

This feels like a real step against getting things done in Swift

Nick Lockwood:

I’m in two minds. It won’t impact existing Cocoa APIs as they’re all ObjC, & future Swifty APIs will use fewer classes anyway.

Radek Pietruszewski:

But values are never the stuff in need of hacking, it’s the classes that do complex stuff.

Mike Ash:

This “claimed bugs” language makes me uncomfortable.

Adam R. Maxwell:

I’ve been worried that guys designing languages/frameworks don’t maintain GUI apps using them, or they’d know there are bugs.

Florent Pillet:

I’ve been fighting with lack of dynamism on Android. When you find issues in the OS you have to rewrite the whole class

Paul Haddad:

My outsider’s perspective of Swift: X can be misused, so we’re banning X.

Seems like coding with safety scissors.

Robert Cottrell:

It seems like a lot of recent decisions are justified “it’s no so bad because you can just go and ask the vendor to fix it”.

Leon Breedt:

yes Radar is a fantastic bidirectional communication tool with a responsive vendor, what could go wrong?

Nacho Soto:

if Apple knows there’s no workaround for their bugs, maybe they’ll get better at shipping quality software.

Max Seelemann:

Well, apparently the core team never had to write software against Apple frameworks. They have no idea how buggy they are.

Friedrich Markgraf:

They just bring their stuff over to Craig’s house if it doesn’t work. They have a mechanism for fixes; we don’t.

Jeremy Tregunna:

This will raise the cost of developing software, and make bugs last longer. That’s the issue at stake here.

Or have you ever been at the mercy of a non-active / committed library author? :)

Krzysztof Zabłocki:

A lot of cool things I built for the community or in my own apps would be impossible to do if this happens.

Adam Kaump:

+ Encourages more thoughtful API design

+ Encourages community-driven changes to frameworks that can benefit everyone

Sean Reilly:

:( re Apple’s stance on the Swift final-by-default proposal.

Mike Ash:

“I think so, Brain, but don’t people need to ship software without waiting years for us to fix the bugs they encounter?”

Steven L:

for final in swift, is there no backdoor option? ’cuz if it’s truly enforced, that’s super painful and short-sighted

McCloud:

I think this is one of the worst decisions in the history of language design.

Scott James Remnant:

I disagree that an open method overridden from a superclass is implicitly open.

As the rationale for the proposal states, overridability is hard to get right, and there is no guarantee that the consumer of an API is going to think about it. The default for override methods should not be open or final, it should be the internal equivalent.

John McCall:

I don’t think that defaulting to non-open would be a good idea. Like I covered in the proposal, inherited open methods remain open; letting an override implicitly close off an open method would create a pretty unfortunate error-of-omission situation.

We could remove the default here and require the method to be explicitly open/nonopen/final, but then we really do pile up the modifiers[…]

L. Mihalkovic:

So simply as a matter of following the logic of the proposal, every subsequent extension of something explicitely marked as open for subclassing should defacto be placed back into the default non-subclassable state, forcing the author to have to explicitely validate the new set of relationships existing between the methods in the subclass. Otherwise the logic does not hold, and the original proposal does not hold water[…]

Károly Lőrentey:

I’m enthusiastic about sealed-by-default classes, but to be honest, I personally have no idea what default (if any) would be best for class members. Ask me again after I’ve worked with the new classes for a couple of months.

L. Mihalkovic:

This is what i find so unique about this situation: there is not 2 months to decide, there is not a couple of implementations to compare.. there is here and now to decide for the next 20 years, with zero experience with the api and very little external references (which nobody seems to [have] any practical experience with) ... nonetheless it must all be fleshed out before the 28th. I [sincerely] hope the core team is more prepared than they currently let out.

John Randolph:

- infinity for this proposal.

If adopted, it will mean that whenever I want to extend a class implemented by a short-sighted developer, I’ll have to resort to wrappers and classes that own instances of the lobotomized class, etc, etc.

Joe Groff:

Users who are third-party framework devs I expect will benefit the most.

They don’t have Apple’s resources to deal with all the backward-compat testing to cope with unconstrained subclassing and patching.

Jonathan Hull:

I would really like to see the methods match the open-ness or final-ity of their enclosing scope by default. Note: I also feel this way about access levels, which work this way except for public… I believe they should work the same way for public too (while keeping internal as the default level for top-level structures). If a class is public open, I am typically going to want 85%+ of the methods to also be public open. Having to annotate each of them adds a lot of visual noise, and is fairly easy to forget to add when refactoring amidst that visual noise. I already have this problem with public, so I expect it will only be worse for public open.

Update (2016-07-19): @Gary_BBGames:

I like Swift, but this will be an absolute shit sandwich

Gwynne Raskind:

The reasoning from the core team that working with vendors replaces the ability to subclass to work around problems simply doesn’t hold water for me. This is a very real and very common issue, and there are endless cases where vendors won’t or even can’t solve the problem, especially in closed-source code.

[…]

In short, saying “filing a bug will work” isn’t good enough to justify locking out the ability of developers to deal with problems in vendor code. It’s simply not true - it’s certainly almost never been true of Apple frameworks, and even when it has, that doesn’t help anyone “now”. (To be clear, I’m not suggesting Apple is unresponsive to Radars. However, I am saying that there’s no transparency, no confidence in getting fixes, and no hope of any kind of reasonable (from a local perspective) timeline for deployment of fixes.)

[…]

If not for the practical considerations, I’d love it! Conceptually speaking, I find it elegant, even harmonious. But again, in practice, the result isn’t so pretty.

Juan Laube:

-1, I really think this a step in the wrong direction.

I recognise the problem around this, and why something is needed. However, I don’t like the idea of restricting things by default. In the attempt to solve a problem, we will create more problems by introducing more workarounds to replace what now is being overridden.

Brent Royal-Gordon:

You know, one thing I haven’t seen mentioned is that, just as sealed-by-default preserves the options of library programmers, it also preserves the options of the language itself.

Suppose the people who think this is a huge mistake are correct, and we ultimately conclude that sealed-by-default is a disaster. What can we do about it? Well, we change Swift 3+n to open all classes by default. This would be source- and binary-compatible with all existing code; the only wrinkle is that classes compiled with a sealed-by-default compiler would still be sealed. (And that’s not even a problem yet, since stable ABIs are not a thing yet.)

The reverse, however, is not true. Going from open-by-default to sealed-by-default is source- and binary-incompatible. If we don’t do it now, we may never be able to do it.

Tino Heth:

In reality, nobody will measure the effect of this change, and those in favor of the proposal might even call the absent of a horrible catastrophe a “proof” for their opinion.

David Owens II:

As an API author, if I need to have a value type, I cannot use inheritance. And more important, especially with regards to many of the arguments against this proposal, you cannot fix any issues with these struct types with inheritance either. It’s at this point that I find your arguments extremely weak: if it is so crucial that inheritance be enabled by default for class types, why are you not more concerned about Swift’s focus on value types and using value semantics for APIs? After all, there are pretty much no APIs in Swift’s libraries that you will be able to patch this way.

I am, and I’ve been writing about that concern from the beginning. As I said at the top, this proposal is just one piece of the larger trend.

There’s absolutely nothing in this proposal that prevents Swift from providing tools to get you access to what you need. For example, imagine a world where you could download a developer Swift module that contains all of the unoptimized code.

This is the hypothetical “escape hatch” that people have been talking about. In theory it could work, if implemented, and if you were able to get all the unoptimized code. That seems rather unlikely to me, and it would be a lot of trouble to go through for the (I think) small benefits the proposal would provide. There are so many more pressing issues I would like the Swift team to work on than building restrictions and then an escape hatch for them.

Update (2016-07-21): Benjamin Mayo:

In general, language design should not be decided by the possible existence of buggy code. However much we strive to make perfect code, there will always be bugs.

Eli Perkins (via Natasha Murashev):

I would have loved to seen this implemented as an opt-in compiler-time flag, rather than a syntactical level keyword.

Peter Livesey:

It seems like for 3rd party libraries only, we are afraid that people will subclass things when they shouldn’t? Is this a real problem? I’ve honestly never seen anyone incorrectly subclass something in a 3rd party library when there was a good alternative. Maybe I have and I forget, but it happens so rarely that I don’t think it’s a real problem to fix.

Peter Livesey:

With this proposal: consumers are screwed until the library is fixed, but the change is backwards compatible.

Without this proposal: consumers are fine to choose what to do (and maybe make mistakes), but the change could be backwards incompatible.

To me, consumers not being screwed > changes being backwards compatible.

Tal Atlas:

I have no concerns intrinsically to the behavior discussed but rather to the complexity that this brings. Creating another type of access control and possibly keyword just adds complexity to an already fairly complex language.

Nevin Brackett-Rozinsky:

I am reminded of the atomic / nonatomic situation in Objective-C. Yes, atomic is generally safer, but almost every property in almost every class is declared nonatomic. It was a mistake to set atomic as the default, which caused a profusion of noise in property declarations.

Chris Lattner:

The proposal has been returned for revision, again. :-)

As with the first round of discussion, the community generated a large number of emails, exploring the various aspects of the proposal. While many community members agree with the thrust of the proposal, a number of people are concerned with the boilerplate being introduced by the proposal, among other issues. The core team spent over two and a half hours discussing this topic from first principles, and has come up with a similar-but-different approach that should reduce the boilerplate, while still accomplishing the primary aims of the proposal. John McCall will be revising the proposal today and we’ll restart a short discussion period about it tomorrow.

Karl:

Conflation of public and open; it feels like open is a new higher access level, like getting married, or going sudo or something. If this proposal was accepted, open should substitute public, and never be alongside it (the same way public private class makes no sense)

Garth Snyder:

In the original proposal (and the ensuing discussion), there was tacit agreement that subclassability/overridability and access levels should be orthogonal. However, given the direction that the design has taken since then, I think we should revisit that decision.

[…]

Third, developers already understand access levels and how they interact. If open is just an access level, all of this proposal’s changes can be fully and naturally described in one line: “public no longer includes the right to subclass or override. To get the behavior formerly known as public, use open instead.” Clear, concise, and not very controversial.

Update (2016-07-23): See also: Core Intuition.

Friday, July 15, 2016 [Tweets]

Lepton Image Compression

Dropbox (Slashdot):

We are pleased to announce the open source release of Lepton, our new streaming image compression format, under the Apache license.

Lepton achieves a 22% savings reduction for existing JPEG images, by predicting coefficients in JPEG blocks and feeding those predictions as context into an arithmetic coder. Lepton preserves the original file bit-for-bit perfectly. It compresses JPEG files at a rate of 5 megabytes per second and decodes them back to the original bits at 15 megabytes per second, securely, deterministically, and in under 24 megabytes of memory.

We have used Lepton to encode 16 billion images saved to Dropbox, and are rapidly recoding our older images. Lepton has already saved Dropbox multiple petabytes of space.

See also: StuffIt X.

Improving Color on the Web

Dean Jackson:

The past few years have seen a dramatic improvement in display technology. First it was the upgrade to higher-resolution screens, starting with mobile devices and then desktops and laptops. Web developers had to understand high-DPI and know how to implement page designs that used this extra resolution. The next revolutionary improvement in displays is happening now: better color reproduction. Here I’ll explain what that means, and how you, the Web developer, can detect such displays and provide a better experience for your users.

[…]

The Web has often struggled to handle colors correctly. I’m sure there are some readers out there who painfully remember Web-safe colors! While we’ve moved on from that, we still have limitations, such as HTML and CSS having been defined to work only in the sRGB color space. Just like the example of hober’s shoes above, this means there are many colors that your CSS, images, and canvas are unable to represent.

[…]

WebKit now supports the (new to CSS Color Level 4) color-gamut media query.

[…]

This is what members of the WebKit project have proposed for CSS. The current idea is to add a new function called color() that can take a color profile as well as the parameters defining the color.

Gus Mueller:

This writeup is an incredibly great explanation of wide gamut issues with a touch on deep color as well. If you are a developer who uses color in any way, you’re going to want to read this. Wide gamut displays are already here.

Previously: iPad Pro, True Tone, and Color Gamut.

Running System 1 on El Capitan

Rich Trouton:

As part of some research which I’m doing on Mac filesystems, I wanted to see if it was possible to get Apple’s System 1 running on OS X El Capitan. The reason that I am specifically interested in System 1 is that this OS used Apple’s shortest-lived filesystem: Macintosh File System.

After discussing the issue, my colleague @mikeymikey pointed me in the direction of using the Mini vMac emulator application to accomplish this. He also pointed me towards the correct places where I could download a System 1 disk image and the needed Mac ROM file.

The Windows Shutdown Crapfest

Moishe Lettvin (2006, via @SwiftOnSecurity):

The most frustrating year of those seven was the year I spent working on Windows Vista, which was called Longhorn at the time. I spent a full year working on a feature which should’ve been designed, implemented and tested in a week. To my happy surprise (where “happy” is the freude in schadenfreude), Joel Spolsky wrote an article about my feature.

I would like to try to explain how this happened.

[…]

So that nets us an estimate -- to pull a number out of the air -- of 24 people involved in this feature. Also each team was separated by 6 layers of management from the leads, so let’s add them in too, giving us 24 + (6 * 3) + 1 (the shared manager) 43 total people with a voice in this feature. Twenty-four of them were connected sorta closely to the code, and of those twenty four there were exactly zero with final say in how the feature worked. Somewhere in those other 19 was somebody who did have final say but who that was I have no idea since when I left the team -- after a year -- there was still no decision about exactly how this feature would work.

Thursday, July 14, 2016 [Tweets]

Facebook’s Mobile Device Testing Lab

Frederic Lardinois (via Peter Steinberger):

The mobile device lab currently occupies 60 racks in the data center. Each rack holds 32 phones, for a total of almost 2,000 devices, but, as Facebook’s Antoine Reversat told us, the plan is to bring this number to 64 devices per rack.

Each rack features its own Wi-Fi signal and is also an EMI enclosure to make sure that neighboring racks can’t pick up the Wi-Fi signals from its neighbors.

Every time an engineer makes changes to one of Facebook’s main mobile apps, that new version of the app is automatically tested on these devices to ensure that there are no crashes or performance issues.

[…]

All of the phones also need to be connected to a PC or Mac in order to receive the latest code. Because of this, there are PCs and Mac Mini’s under every rack. Facebook uses eight Mac Minis per rack for iOS testing (because each one can only talk to four iPhones) or four OCP Leopard servers for testing Android devices.

Legal Decisions

Orin Kerr:

The U.S. Court of Appeals for the 9th Circuit has handed down a very important decision on the Computer Fraud and Abuse Act, Facebook v. Vachani, which I flagged just last week. For those of us worried about broad readings of the Computer Fraud and Abuse Act, the decision is quite troubling. Its reasoning appears to be very broad. If I’m reading it correctly, it says that if you tell people not to visit your website, and they do it anyway knowing you disapprove, they’re committing a federal crime of accessing your computer without authorization.

[…]

At this point you may be thinking: Hey, wait, didn’t the en banc 9th Circuit rule in Nosal I that using a computer in violation of its terms of use is not a CFAA violation? If intentionally using a computer in violation of the terms of use is legal authorized access, as the en banc 9th Circuit held in Nosal I, why is intentionally using a computer after receiving a cease-and-desist letter criminal access “without authorization”? In one case, the user goes to the website and sees the terms; in the other, the website owner contacts the user and shows the terms to them. But it’s the same thing, right?

Bruce Schneier:

In a truly terrible ruling, the US 9th Circuit Court ruled that using someone else’s password with their permission but without the permission of the site owner is a federal crime.

Mark Rumold:

In a dangerously flawed decision unsealed today, a federal district court in Virginia ruled that a criminal defendant has no “reasonable expectation of privacy” in his personal computer, located inside his home. According to the court, the federal government does not need a warrant to hack into an individual’s computer.

MathML Improvements in WebKit

Frédéric Wang:

This new feature is obvious: You can now create a hyperlink for any part of a mathematical formula!

[…]

In the following screenshot, you can see that the letters f, x and y are now drawn with this special mathematical italic glyphs and that WebKit uses the conventional fraktur style for the Lie algebra g. Note that the prime is still too small because WebKit does not make use of the ssty feature yet.

[…]

As said in my previous blog post, the rendering of large and stretchy operators have been rewritten a lot and as a consequence the rendering has improved. Also, I mentioned that the width of operators may depend on their height. This may cause accumulated approximations during the computation of preferred widths. The old flexbox-based implementation incorrectly forced layout during preferred computation to avoid that but a quick workaround for that security concern caused the approximate preferred widths to be used for the logical widths. With our new implementation, the logical width is now correctly calculated. Finally, we added partial support for the mpadded element which is often used to tweak spacing in mathematical formulas.

Pinboard Turns Seven

Maciej Cegłowski (via Manton Reece):

I’ve added revenue this year because I’m no longer afraid of competitors, and I’d like to encourage people who are considering doing their own one- or zero-person business. The site costs something like $17K/year to run, so you can make a good living at this artisanal SaaS stuff.

As you can see, most everything has been steady year-to-year for a while now. Revenue dropped a bit in 2015 (as I moved to an annual subscription system), then picked up substantially this year as the first wave of subscription renewals came due, and people had the option of renewing for multiple years.

Wednesday, July 13, 2016 [Tweets]

Mailbox Names via IMAP

Bron Gondwana:

So IMAP supports arbitrary hierarchy separators. In practice only / and . appear to be common, though I’m sure there are still systems out there using \ which brings its own special hell in C-like programming languages which use \ as an escape character (as anybody who’s ever programmed for Windows will know).

Some operating systems use case significant file systems, others don’t. So on some systems, README.TXT and Readme.txt are the same file, but on others they aren’t. Of course IMAP chose to leave case sensitivity up to the implementation... sort of.

[…]

I spent a lot of time workshopping our options, and in the end the RFC requirement that ALLCAPS INBOX had to match LIST and the fact that every other server always returns it as INBOX in that case convinced me that the folders really had to be subfolders of ALLCAPS INBOX, rather than using Inbox as the name. Also, any other spelling of INBOX needed to not be allowed at the top level, because of the case insensivity rule.

Apple Faces Patent Lawsuit Over iPhone’s Battery Technologies

Joe Rossignol:

Somaltus, LLC has filed a complaint against Apple today in an Eastern Texas district court, accusing the iPhone maker of infringing upon its 2010 patent related to complex battery technologies. The small Frisco, Texas-based firm also filed lawsuits against Asus, Lenovo, Samsung, Sony, and Toshiba over the same patent.

[…]

Specifically, it appears that the infringement claim at least partially relates to the iPhone’s process of charging in fast-charge mode until the battery reaches 80% capacity, and then adjusting to trickle-charge mode above 80% capacity.

Wasn’t Apple doing that with PowerBooks in the 90s?

Swift Playgrounds Aren’t HyperCard

Adam Banks:

HyperCard, “like a software erector set,” would crystallise computing into building blocks that any user could snap together to implement the functionality and user interface they had in mind. That’s not what Swift Playgrounds does today, however. Apple’s newest attempt to democratize coding presents a very inviting experience to the budding developer, but it insists that you code. And even after having done so, you still don’t get a deliverable app—only a work in progress.

[…]

Keith Martin, a senior lecturer at the University of the Arts London (UAL) with a long-term interest in interactive development, also wanted Apple to think beyond code. “Swift Playgrounds seems to be a tacit admission that Swift is not easy. The trouble is, it doesn’t actually address the fundamental issues, it just tries to show stuff in a cutesy form.” The difficult concepts that made learning Objective-C (Apple’s favoured language before Swift) feel like “banging my head against a wall” are still unavoidable.

[…]

Yet while hypertext went everywhere, programming without coding went nowhere.

[…]

As [Douglas] Adams recognised, HyperCard didn’t dumb down; it simplified up. The way it shoehorned objects and classes into a mundane Rolodex metaphor made advanced principles concrete, so users could bash them around and see for themselves what they achieved instead of having to learn dry theory before they could even start on syntax.

Tuesday, July 12, 2016 [Tweets]

Amazon’s Chinese Counterfeit Problem Is Getting Worse

Ari Levy (via John Gordon and John Gruber):

In May, CNBC.com reported on a Facebook group, now consisting of over 600 people, whose members have seen their designs for t-shirts, coffee mugs and iPhone cases show up on Amazon at a fraction of the price of the originals. The designers described it as a game of whack-a-mole, where fakes pop up more quickly than they’re taken down.

[…]

To unsuspecting consumers, fake products can appear legitimate because of the Fulfillment by Amazon program, which lets manufacturers send their goods to Amazon’s fulfillment centers and hand over a bigger commission, gaining the stamp of approval that comes with an FBA tag.

[…]

Making matters worse, when buyers unhappy with the cheaper alternatives leave a bad review, it drags down Bergman’s standing because the reviews are all thrown together.

[…]

As a marketplace, Amazon isn’t legally responsible for keeping counterfeit material off the site as long as it responds to complaints and takes action when it’s brought to the company’s attention.

Amazon faces a sort of strategy tax.

Update (2016-07-21): Ari Levy (via John Gruber):

Birkenstock is walking away from Amazon.com.

Plagued by counterfeits and unauthorized selling on the online shopping site, the sandals company will no longer supply products to Amazon in the U.S. starting Jan. 1. Additionally, Birkenstock won’t authorize third-party merchants to sell on the site, according to a letter the company sent to several thousand retail partners on July 5.

[…]

The only way to get Amazon’s support in creating a clean environment, according to Kahan, is by selling the entire catalog to Amazon. It’s part of the online retailer’s effort to be the one-stop shop for anything and everything.

[…]

Birkenstock will be telling consumers to purchase only from authorized retailers, and that any products listed on Amazon can’t be trusted. “So, buyer beware,” he wrote.

Monday, July 11, 2016 [Tweets]

The Pokémon Go Phenomenon

Serenity Caldwell et al.:

Most people have at least heard of Pokémon — Nintendo’s ever-popular title — which asks players to travel a fictional world in order to collect every creature out there. But today’s world is not the world of the 1990s: Nintendo and Niantic Labs have teamed up to let players catch Pokémon in the very world we live in, thanks to a combination of GPS, augmented reality, and dorky-cute graphics.

A good introduction for people like me who have basically only heard about Pokémon—until this weekend—through Swift example code.

James Vincent (Hacker News):

Nintendo’s stock continues to skyrocket following the release of Pokémon Go. After an increase of 9.3 percent with the game’s launch last week, the company’s share price rose 24.52 percent on Monday to ¥20,260 ($193) — its highest one-day surge since 1983, adding $7.5 billion to the firm’s market value. The game has topped app download charts in the US, Australia, and New Zealand, and according to some market researchers, has already been installed on 5 percent of all Android smartphones in America.

Mitchel Broussard:

Because it requires players to travel to real-world destinations in order to stock up on Poké Balls, eggs, potions, and compete at gyms, some individuals have been capitalizing on the game’s mechanics to trap and rob its players. According to a Facebook post from the O’Fallon Police Department in Missouri, four people were arrested over the weekend after using a Lure Module at a PokéStop to draw in unsuspecting players and rob them at gunpoint.

Aaron Levie:

Nintendo’s mobile strategy:
2008: what’s an iPhone
2010: what’s an Android
2012: nope
2014: still no
2016: change how society functions

Although it sounds like Nintendo’s contribution was mostly the IP. The game was developed by Niantic, of Ingress fame.

Previously: Nintendo.

Update (2016-07-11): Adam Reeve (via David Chartier):

To play the game you need an account. Weirdly, Niantic won’t let you just create one - you need to sign in with an existing account from one of two services - the pokemon.com website or Google. Now the Pokemon site is for some reason not accepting new signups right now so if you’re not already registered there you’ll need to use a Google account - and that’s where the fun begins.

[…]

Let me be clear - Pokemon Go and Niantic can now:

  • Read all your email
  • Send email as you
  • Access all your Google drive documents (including deleting them)
  • Look at your search history and your Maps navigation history
  • Access any private photos you may store in Google Photos
  • And a whole lot more

What’s more, given the use of email as an authentication mechanism (think “Forgot password” links) they now have a pretty good chance of gaining access to your accounts on other sites too.

Update (2016-07-12): @SwiftOnSecurity:

When you give a company keys to your account, you’re giving your keys to their employees and anyone who hacks them. Not a question of trust.

yan:

weird thing abt PokemonGo getting full goog account access is that iOS showed no permission dialog. goog should just revoke their app tokens

Adam Reeve has posted a FAQ.

Rosyna Keller:

I don’t understand… @NianticLabs fixed the Google scope bug in Ingress on April 19th but left it in Pokémon GO?!

William Turton:

But in a call with Gizmodo, Reeve backtracked his claims, saying he wasn’t “100 percent sure” his blog post was true. On the call, Reeve also admitted that he had never built an application that uses Google account permissions, and had never tested the claims he makes in the post.

Cybersecurity expert and CEO of Trail of Bits Dan Guido has also cast serious doubt on Reeve’s claim, saying Google tech support told him “full account access” does not mean a third party can read or send or send email, access your files or anything else Reeve claimed. It means Niantic can only read biographical information like email address and phone number.

[…]

A product security developer at Slack tested the token provided by Pokémon Go and found that it was never able to get data from services like Gmail or Calendar.

Nicole Lee:

Niantic Labs and The Pokémon Company issued a response to Engadget, confirming that it’s not actually reading your emails. Still, it has far more access than is necessary for the game and the company says that while it’s working on a fix for the client to only request the correct permission, Google will reduce Pokémon Go’s access on its end ‘soon.’

Update (2016-07-13): Lukas Mathis:

Much of the argument for Nintendo to create mobile games was based on the idea that Nintendo could not survive just selling its own consoles. I think it’s fair to say that the last few years have shown this to be false. Even with the Wii U being an abysmal failure, Nintendo is consistently profitable.

[…]

For Pokémon GO to achieve the same kinds of numbers, it will have to continue doing this well for quite a while.

That’s not to say that Pokémon GO can’t achieve those numbers - but how many of Nintendo’s other games will be lottery wins the size of Pokémon GO?

[…]

One final point: it feels a little bit disheartening to see the adulation Nintendo is currently getting for moving towards the same kind of manipulative, free-to-play, IAP-monetized games we get from tons of other rather questionable mobile gaming companies. It really took a very short amount of time for us to accept these games as the new normal.

Mitchel Broussard:

One week after it launched in the United States, Pokémon Go is now the biggest mobile game in the country’s history, in statistics focusing on the amount of daily active users (DAU) the app draws.

Update (2016-07-15): See also: Aeriform.

Apple and the Blind

Katie Dupree (via John Gruber):

The company, for example, made the first touchscreen device accessible to the blind via VoiceOver. Recent announcements of Siri coming to Mac this fall, and of newer innovations, like a magnifying glass feature for low-vision users, have continued the promise of improving the Apple experience for those who are blind and low vision.

[…]

The most recent example of community-driven innovation can be found on the Apple Watch. During a meeting, Herrlinger explains, a person who sees could easily peer down at their watch to keep an eye on the clock. A person who is blind, however, hasn’t had a way to tell time without VoiceOver.

After confronting the conundrum, Apple solved the issue by making a feature that tells time through vibrations. The addition, Herrlinger says, is coming to watchOS 3 this fall.

[…]

For Castor, Braille is crucial to her innovative work at Apple — and she insists tech is complementary to Braille, not a replacement.

“I use a Braille display every time I write a piece of code,” she says. “Braille allows me to know what the code feels like.”

In coding, she uses a combination of Nemeth Braille — or “math Braille” — and Alphabetic Braille. Castor even says that with the heavy presence of tech in her life, she still prefers to read meeting agendas in Braille.

The History of “This Web Site Is Well-crafted” Hints

Adrian Holovaty:

Over time, technology stabilizes and the techniques become expected. 10+ years ago, in the era of .cgi and .asp, I remember geeking out with Simon Willison about beautiful URL structures we’d seen. No file extensions! Readable! Hackable!

To us, they were signals that a web development team sweated the small stuff. It’s like the famous Steve Jobs story about making the inside of the hardware look just as nice as the outside, even if nobody ever sees it, because you have pride in your work.

With this in mind, I put together a list of these hints, as I remember them. Perhaps it’s of some historical interest, or maybe it’s just fun nostalgia. Almost all of these have become mainstream by now.

Praise for the Fujitsu ScanSnap

Kirk McElhearn:

If I had known, I would have opted for the more expensive ScanSnap iX500 (Amazon.com, Amazon UK), which has a larger document feeder, and wifi, and is faster. And I’ve thought from time to time that, if mine dies, I’ll replace it with the better model, but it seems to be a workhorse. It’s rare that I have a lot of documents to scan, and it’s no hassle to have the device connected to my Mac.

But, for now, this is one of the best pieces of hardware I’ve ever bought. It’s an essential tool for a modern home or office, where we are inundated with paper.

I tried many document scanners over the years, but none worked reliably. I wanted to go paperless, but not if the hardware was always getting in the way. About nine years ago, I got a ScanSnap S500m. It seemed expensive, but it ended up being one of my best purchases ever. It’s so easy to use, almost always does the right thing, and mine is still going strong today—although the plastic has yellowed like a Mac 128K.

Friday, July 8, 2016 [Tweets]

Continuous: C# and F# IDE for iPad

Frank A. Krueger (via Federico Viticci):

Continuous gives you the power of a traditional desktop .NET IDE - full C# 6 and F# 4 language support with semantic highlighting and code completion - while also featuring live code execution so you don’t have to wait around for code to compile and run. Continuous works completely offline so you get super fast compiles and your code is secure.

Continuous gives you access to all of .NET’s standard library, F#’s core library, all of Xamarin’s iOS binding, and Xamarin.Forms. Access to all of these libraries means you won’t be constrained by Continuous - you can write code exactly as you’re used to.

Switching to Apple’s Two-Factor Authentication

Dan Moren:

Apple has, for a while now, offered two separate additional security measures to protect your Macs, iOS devices, and iCloud account, but thanks to some inexpert nomenclature, it can be a little difficult to tell them apart.

The first, two-step verification, has been offered for several years. It prompts you to enter a four-digit code when you sign into your iCloud account, purchase something from one of Apple’s stores on a new device, or make changes to your Apple ID. Those codes were delivered by push notification to an authenticated device of your choosing, or via SMS text message.

[…]

The newer two-factor authentication is an improvement upon that process, which Apple started rolling out last year. While the principle is similar, the execution is refined. The verification code is now six digits and is automatically sent to all of your authorized devices.

[…]

Though Apple didn’t provide an obvious way to make that jump, the key is simply to deactivate your existing two-step authentication[…]

Dan Moren:

If you want to see a list of trusted devices and those that can receive two-factor codes (which largely but not entirely overlap), go to the iCloud preference pane on your Mac, or the iCloud section of Settings on your iOS device, and look at your account, then select Devices. That’ll provide a list of every device logged into your iCloud account; selecting each will tell you if they’re trusted and can receive two-factor codes.

[…]

As mentioned in a subsequent update, two-factor authentication does not remove the need for app-specific passwords, but it does seem that you no longer need them for any Apple services.

Mozilla-Yahoo Contract Clause

Kara Swisher (via Hacker News):

Under terms of a contract that has been seen by Recode, whoever acquires Yahoo might have to pay Mozilla annual payments of $375 million through 2019 if it does not think the buyer is one it wants to work with and walks away.

That’s according to a clause in the Silicon Valley giant’s official agreement with the browser maker that CEO Marissa Mayer struck in late 2014 to become the default search engine on the well-known Firefox browser in the U.S.

Mozilla switched to Yahoo from Google after Mayer offered a much more lucrative deal that included what potential buyers of Yahoo say is an unprecedented term to protect Mozilla in a change-of-control scenario.

Slower by Design

Mark Wilson:

The short answer is no. Facebook actually slows down its interface to make users feel safe, a Facebook spokesperson confirmed in an email. “While our systems perform these checks at a much faster speed than people can actually see, it’s important that they understand what we do behind the scenes to protect their Facebook account,” the spokesperson wrote. “UX can be a powerful education tool and walking people through this process at a slower speed allows us to provide a better explanation and an opportunity for people to review and understand each step along the way.”

If half of Facebook’s billion users spend 5 seconds waiting on this check, that’s 694,444 hours, or 28,935 days of collective time lost. But Facebook isn’t alone. Websites and apps now operate on the magnitude of milliseconds. But such speed can make users skeptical or even confused, so companies are responding by building slower, more deliberate interfaces. Wells Fargo admitted to slowing down its app’s retinal scanners, because customers didn’t realize they worked otherwise, while various services on the web including travel sites, mortgage engines, and security checks are all making a conscious effort to slow down their omnipotent minds because our puny human brains expect things to take longer.

Why is it that Kayak has to slow down its search so people believe it’s working hard to find them the best deals, but no one doubts Google’s quick search results?

Thursday, July 7, 2016 [Tweets]

Protecting Your Network From Photos Uploads

Adam C. Engst (May 2015):

My Internet connection runs at 30 Mbps down and 5 Mbps up, and when I turned on iCloud Photo Library for the first time, Photos completely destroyed Internet performance for every device in the house: Web pages loaded slowly, Google Hangouts struggled, Netflix buffered repeatedly, Rdio stuttered, and even Dark Sky on the iPhone timed out getting climate data. I had to promise to pause syncing whenever Tristan needed to do homework (which is whenever he’s home, it seems), and it was clearly something that couldn’t run during our work days.

I recently enabled iCloud Photo Library for a small library in our household, and it did more than reduce the Internet performance. It made all our Macs and devices stop working. Web pages immediately showed errors. Mail and Dropbox wouldn’t sync at all. Apple TV couldn’t play anything. Wi-Fi calling didn’t work. This is with a pretty fast cable connection. Oh, and quitting Photos doesn’t provide relief because uploads continue via a helper process.

Every other network-intensive app that I use—Arq, CrashPlan, Dropbox, etc.—includes a bandwidth limiter. (Apps that upload seem to cause more problems than ones that download.) Photos has no throttle, just an off switch, which doesn’t really help because neither of its settings does what I want. Let it run, and no other app on any device can realistically access the Internet. Turn it off, and the photos never upload. It boggles the mind that the app was released this way and not fixed in the 15 months since (or, seemingly, in Sierra).

The standard advice is to install the Network Link Conditioner and use it to limit the bandwidth available to your Mac. To do this, you need to be a registered developer. Then you can download the “Hardware IO Tools for Xcode 7.3” and double-click the Network Link Conditioner.prefPane.

Note that if your Mac’s login account is a Standard rather than Admin user, you will not be able to click the button to enable Network Link Conditioner after installing it. System Preferences will beachball forever. However, because it affects the entire Mac, you can enable it from an Admin account and it will still limit the bandwidth of Photos running in another account. Even once it’s installed and enabled, Network Link Conditioner won’t work if you boot the Mac and log into a Standard account. You have to first log into an Admin account in order for it to load properly.

The problem with using Network Link Conditioner is that the network will also be slowed down for every other process on the Mac. Also, Photos may still monopolize the throttled connection and prevent other apps from doing anything. To fix this you would need to use a more involved method to limit the bandwidth for a particular process (via Rosyna Keller). I have not tried this, but it looks like that process would be cloudd and that it handles more than just Photos syncing, so this would still be an imperfect solution.

Previously: iCloud Photo Library: the Missing FAQ, More Problems With iCloud Photo Library Uploads.

And, speaking of Photos, Glenn Fleishman:

Yup, that’s right: hidden photos appear in plain sight in albums and the main view in Photos. Media marked hidden disappears only from Moments, Collections, and Years. If you use iCloud Photo Library, the same is true, because the photos or videos you’ve hidden need to sync among your devices so that they are in the same state on all of them.

Update (2016-07-08): Garrett Murray:

Had the same problem when Photos first came out. Took 3 weeks of night-only NLC uploading on my Mac to finish initial sync.

When “No Longer Available” Strikes in iCloud Music Library

Kirk McElhearn:

But things get complicated when music that you have added to your iCloud Music Library from Apple Music is pulled. Labels can withdraw the right to stream certain songs and albums at any time, but you won’t be notified. You may see albums and songs in your library, but their titles are a slightly lighter color (depending on the view), and their iCloud status is No Longer Available.

[…]

In most cases, this is little more than an annoyance. But there are certain situations where this availability is an iCloud Music Library problem. Look at the screenshot below: it’s my iTunes library in Albums view. You’ll see that there are two instances of Chicago’s At Carnegie Hall. This is because the first one I added to my library suddenly became No Longer Available. When I searched for the album, I found it and added it to my library, and the only difference is the addition of (Live) after its title. Somehow, the record label tweaked the name of the album, and it was considered to be a totally different album.

He also has a bunch of “No Longer Available” tracks with missing metadata.

Update (2016-07-23): Christopher Thielen (via e-mail):

With macOS Sierra’s “Optimize Storage” removing previously watched iTunes purchases, what do you think would happen if the movie is no longer available for download?

The iTunes Terms and Conditions recommends users create a backup but even a Time Machine backup would lose the file should it be off the main computer (“optimized”) long enough.

Android Flash Keyboard Hijacks Lock Screen, Violates Privacy

SecurityWeek News (via @SwiftOnSecurity):

A third-party keyboard application for Android that had over 50 million installs was found to collect user data and send it to a remote server, Pentest Limited researchers reveal.

[…]

Right from the start, however, Flash Keyboard raises a red flag, given that it asks for a great deal of permissions that it isn’t supposed to have. It can run at startup, can read and write home settings and shortcuts, can use network and Bluetooth as it likes, can modify system settings, disable the lock screen, force-stop other applications, and read the status of phone, user ID, and more. […] Moreover, Flash Keyboard uses device admin APIs that allow it to replace the standard Android lock screen with its own custom lock screen, which is monetized by displaying custom ads.

[…]

The researchers discovered that the application was communicating with servers in several countries, including the United States, the Netherlands, and China, and that it sent the following information to them: device manufacturer and model number, IMEI, Android version, user email address, Wi-Fi SSID, Wi-Fi MAC, mobile network, GPS co-ordinates, information about nearby Bluetooth devices, and details of any proxies used by the device.

Concurrent Core Data, Now Easier Than Ever

Arkadiusz Holko:

Our main thread-bounded operations use viewContext. Background work can be performed on a context returned by the factory method newBackgroundContext(). However, usage of performBackgroundTask(_:) is recommended because of the under-the-hood optimizations.

All contexts are independent of each other, there are no parent/child relationships here. To receive changes from other contexts we simply set automaticallyMergesChangesFromParent flag to true on a context. Despite its name (*FromParent*), it works correctly with the NSPersistentContainer setup in which contexts are siblings:

Not sure I understand that last bit.

Update (2016-07-07): James O’Leary says that, despite the name of the property, it treats the persistent store itself as an implicit parent context.

Tuesday, July 5, 2016 [Tweets]

BBEdit 11.6

Bare Bones Software:

At the end of the 30-day evaluation period, BBEdit will remain permanently functional with a revised feature set that includes its powerful text editing capabilities but not its web authoring tools or other exclusive features. BBEdit’s exclusive features may be re-enabled at any time with a purchased license.

[…]

There is a new command-line tool: bbresults. This tool reads data from stdin which is expected to be typically formed Unix error messages. This data is then used to create a BBEdit results window which provides navigation of errors and warnings within BBEdit itself.

[…]

Added Toothpaste as a factory-supplied color scheme.

[…]

When an untitled document is active in a window, the window’s entry in the Window menu will be annotated with some text derived from the beginning of the document’s contents.

I also like the new toolbar design, which is more compact and shows the document’s full path (with tilde).

Update (2016-07-08): John Gruber:

In the old days, there was BBEdit (paid) and BBEdit Lite (free). Then BBEdit Lite went away. Then we got TextWrangler, which was free.

I like this setup better. Download BBEdit for free. Use all of its features free for 30 days. After that, you still have a terrific Mac text editor, free of charge. But as soon as you need it, you can pay to enable the full feature set.

Monday, July 4, 2016 [Tweets]

Jefferson’s Pull Request

Thomas Jefferson (via Patrick Woods):

Lots of good discussion from everyone!

Biggest changes:

  • Weeding out some of my verboseness (which, although lovely, is a bit superfluous)
  • Remove some of the focus on current events, especially at the end, and make it feel more timeless
    • We hope to keep these states for longer than just a couple years, right?