Tuesday, September 2, 2014

“Use Cellular Data For” Switch Doesn’t Work

Apple:

You can also enable or disable cellular data for certain iOS apps and features from this setting.

Choose Settings > Cellular to view the cellular data usage for each app. Tap to turn off cellular data for an app.

Unfortunately, this feature seems to have stopped working with iOS 7.1.2. I went over my 200 MB bandwidth limit in both July and August—having never done so before. Apps such as OmniFocus and Overcast, which I’ve always set to not use cellular data, used tens of MB of data each month.

Omni seems to have received other reports of this problem and explained how I could turn off automatic syncing in OmniFocus. I think this helped, but the app has still used 5 MB of data in the last four days, when it shouldn’t have used any at all.

Announcing the Textbundle Format

Brett Terpstra:

The Textbundle format is very simple. A folder containing a plain text file, a JSON data file, and an assets sub-folder. An app, such as Ulysses, can write a Textbundle out and pass it to Marked, and all of the necessary components are automatically included. Images, additional text files, and any metadata needed are all there and safe from sandboxing restrictions.

Sandboxing is the primary motivation, and Textbundle solves the major issue of referencing external files in Markdown.

LaunchBar’s New Staging Area

Norbert Heger:

LaunchBar collects items that participate in a multiple selection in a so called staging area. You can add or remove (stage or unstage) items with a few keystrokes.

[…]

Once you’ve staged multiple items, you can act on these items pretty much the same way as you do with single items. Press ↩ to open them, press ⇥ to send them to an action, move them to a folder, and so on.

[…]

You can quickly show a list with all currently staged items by pressing ⇧→.

[…]

While this list of staged items is visible, you can press ⌫ to remove items from the staging area. And you can press ⌥↑ or ⌥↓ to rearrange items in the list. This is useful when the order of items is relevant, e.g. in case of songs (when you wish to play them in a particular order) or contacts (when you want a recipient to be first in the To-field of an email).

Protocols and Assumptions

Airspeed Velocity:

So what’s the solution – should RangeReplaceableCollectionType mandate the kind of index validity behaviour our remove algorithm relies on? Or are the assumptions invalid and we need a better algorithm? (of which more in a later article) The Swift standard library is still evolving rapidly with each beta so it’s possibly a little early to tell. For now, be careful about the assumptions you make – just because all the current implementations of a particular protocol work a certain way doesn’t mean other implementations will.

What “Coder” Means

Dave Winer:

The act of turning the English words into Morse code is coding.

That is what coder means. Someone who encodes things.

There was a time when you’d write your code on big sheets of paper, and then sit down at a machine called a keypunch, and transfer the instructions from paper to 80-column cards with holes, that machines could read. It would be fair to call this coding. But we haven’t done development that way for a very long time!

Developing software involves a lot of thinking, and trial and error, learning, experimenting, listening to users, getting feedback and trying new approaches. The coding part of it, if we still did it, which we don’t, would be a relatively insignificant part of the job.

I doubt that most people think that’s what “coder” means today. They just use it as a shorter word for “programmer.” Leslie Lamport seems to see coding as translating a (perhaps implicit) specification into code. We understand that writing is primarily thinking (or researching, etc.), not typing. So it is for people who write code rather than prose. Do people really not understand this?

A lot of managers think that programming is a menial job, and hire people accordingly. They value subservience. That’s where the word coder comes from, and why it’s so bad.

If there is a problem, I think the solution would be to educate about what coders actually do, not to come up with a fancier title. If “writer” works—and I think it does—I have no problem with “coder.” That said, I tend to describe myself as a “developer” because I do lots of non-coding/code-thinking work such as customer support, documentation, and business and server stuff.

Discourse Reaches 1.0, Without RSS

Jeff Atwood:

Version numbers are arbitrary, yes, but V1 does signify something in public. We believe Discourse is now ready for wide public use.

That’s not to say Discourse can’t be improved – I have a mile-long list of things we still want to do. But products that are in perpetual beta are a cop-out. Eventually you have to ditch the crutch of the word “beta” and be brave enough to say, yes, we’re ready.

Jeff Atwood (via John Gordon):

I am of the belief that RSS is kind of a semi-dead format at the moment.

However if someone submitted a GitHub pull request that added proper RSS support, I wouldn't turn it down!

I loved the idea of Discourse, but I remain unimpressed with it so far. In my view, the current design is user-hostile, to the point where I avoid forums that use it. I prefer to visit sites that use any number of low-tech forums from before Web 2.0. Not including RSS support seems to underscore that their vision for what the product should be is radically different from mine.

TextExpander Snippet Expansion Comes to Every App in iOS 8

Smile Software (via Federico Viticci):

Prior to iOS 8, only apps which implemented the TextExpander touch SDK could expand snippets directly.

Under iOS 8, the TextExpander keyboard will work system-wide and reliably share snippets with the TextExpander app. The keyboard will also include full VoiceOver accessibility support.

Update (2014-09-02): Clark Goble:

The keyboard I’m most looking forward to myself is SwipeSelection. Apple even changed the keyboard API to make keyboards like SwipeSelection possible in iOS 8. If TextExpander including sensical cursor movement in their keyboard ala SwipeSelection I’d probably get it immediately. Although it should be a selectable option.

It’s what’s possible now, but it seems like a custom keyboard is not really the best way to integrate TextExpander into iOS. Why should I have to use their keyboard user interface (and forego other custom keyboards) just to get their code to see what I’m typing?

The Poisoned NUL Byte, 2014 Edition

Chris Evans:

The effect of all these command line arguments is to bloat both the stack (which grows down) and the heap (which grows up) until they crash into each other. In response to this collision, the next heap allocations actually go above the stack, in the small space between the upper address of the stack and the kernel space at 0xc0000000. We use just enough command line arguments so that we hit this collision, and allocate heap space above the stack, but do not quite run out of virtual address space -- this would halt our exploit!

[…]

The main point of going to all this effort is to steer industry narrative away from quibbling about whether a given bug might be exploitable or not. In this specific instance, we took a very subtle memory corruption with poor levels of attacker control over the overflow, poor levels of attacker control over the heap state, poor levels of attacker control over important heap content and poor levels of attacker control over program flow.

Yet still we were able to produce a decently reliable exploit! And there’s a long history of this over the evolution of exploitation: proclamations of non-exploitability that end up being neither advisable nor correct. Furthermore, arguments over exploitability burn time and energy that could be better spent protecting users by getting on with shipping fixes.

Swift Default Protocol Implementations

Mattt Thompson:

All of this highlights a significant tension between methods and functions in Swift.

The Object-Oriented paradigm is based around the concept of objects that encapsulate both state and behavior. However, in Swift, it’s simply impossible to implement certain generic functions as methods on the struct or class itself.

[…]

Because of the constraint on the element of the sequence generator being Equatable, this cannot be declared on a generic container, without thereby requiring elements in that collection to conform to Equatable.

Relegating behavior like contains, advance, or partition to top-level functions does a disservice to the standard library. Not only does it hide functionality from method autocompletion, but it fragments the API across a Object-Oriented and Functional paradigms.

Photo Security Tips

Christopher Breen:

If you’d disabled photo sharing from your iPhone to your iCloud account those pictures would have remained on your phone. Although the horse has left the barn, here’s what you might have done.

Sriram Krishnan:

First, you deserve an apology from all of us who work in tech. This should be easier and more bullet-proof but it isn’t. We keep working on making it better.

Second, the title of this post is a lie. Nothing is ever completely safe unless you prefer to only use computers in an underground bunker disconnected from any wires. And even that may be insecure. The below are reasonable practices which will hopefully keep you safe while not making your normal usage of technology and gadgets impossible. Sadly, the only way to make sure something never falls into the wrong hands is probably to never have it in a digital form. This is especially true for those of you who get more attention from the bad guys than the rest of us - they’re always going to be trying to find the weakest link in.

I don’t actually want my photos to be in the cloud, with the last 1,000 taking up space on each of my iOS devices. But the alternative is to use a much less efficient workflow. I’d prefer it the photos were automatically transferred directly to my Mac, either over Wi-Fi or USB, without having to open Aperture, pick a project, initiate the import, delete the photos after importing, and then quit Aperture.

Monday, September 1, 2014

Dropbox Cuts Prices, Increases Storage, Adds Pro Features

Casey Newton:

Today Dropbox announced a revamped version of its paid offering for individuals, called Dropbox Pro, that costs $9.99 a month for 1 terabyte of storage. Previously, $9.99 got you just 100 gigabytes; storage maxed out at 500GB, which cost a whopping $500 a year.

Dropbox:

Simple collaboration is one of the reasons people choose Dropbox Pro, but we’ve heard you ask for more ways to protect the stuff you share. That’s why we’re bringing new sharing controls to Dropbox Pro.

Adam C. Engst:

Dropbox has also rejiggered its Packrat unlimited version history feature. For free accounts, Dropbox maintains all older versions and deleted files for only 30 days, but in the past, Dropbox Pro users could pay an extra $39 per year for Packrat, which maintained all older versions and deleted files indefinitely. Dropbox has now renamed Packrat to Extended Version History and set it to preserve only 1 year of older versions and deleted files. The price of Extended Version History for Dropbox Pro users remains $39 per year, and existing Dropbox Pro users with Packrat can opt in to keep unlimited version history before 1 November 2014. (Dropbox for Business users continue to have unlimited version history.)

Anand Goes to Apple

Anand Lal Shimpi:

On April 26, 1997, armed with very little actual knowledge, I began to share what I had with the world on a little Geocities site named Anand’s Hardware Tech Page. Most of what I knew was wrong or poorly understood, but I was 14 years old at the time. Little did I know that I had nearly two decades ahead of me to fill in the blanks. I liked the idea of sharing knowledge online and the thought of building a resource where everyone who was interested in tech could find something helpful.

[…]

But after 17.5 years of digging, testing, analyzing and writing about the most interesting stuff in tech, it’s time for a change. This will be the last thing I write on AnandTech as I am officially retiring from the tech publishing world.

Enidigm (June 2014):

Benchmarkgate was I think their term to describe the persistent, repeated and deliberate cheating of benchmarks by several smart phone manufacturers, by inserting code that looked for a benchmark and then gave the phone 100% access to the cores, pushing all power savings aside. Only Motorola and Apple seemed to not cheat, Samsung was the worst. One can only speculate how this affected their access to smart phone developers.

John Paczkowski:

An Apple rep confirmed that the company was hiring Shimpi, but wouldn’t provide any other details.

Mike Beasley:

Earlier this year AnandTech’s Brian Klug also left the site for a role at Apple with a focus on building mobile processors for the company’s iOS lineup.

I’m not sure what this will mean for AnandTech, but it’s good that Apple continues to be able to hire top talent.

Vlad Savov:

Shimpi’s departure note on AnandTech states that the site’s editorial staff has been expanded over the course of this year to prepare for his absence.

Ryan Smith:

Having read AnandTech for 15 years and having worked for Anand for almost 10 of those years, it was until recently hard to imagine reading AnandTech and not seeing articles by Anand, or to be writing for AnandTech but not be writing for Anand himself. Anand has been a constant in the tech world both as a source of news an analysis for us all, and as a mentor to me. These days I can happily say I was wrong about not being able to match wits with The Boss, and now I am going to get to put that to the test.

Late to Launch

Dr. Drang:

Earlier this month I learned what I was missing. After building an overly complicated set of scripts for adding common entries to my work diary, I learned how much simpler a set of LCP actions would be. I now have a color-coded group of actions for all my common diary entries.

I was also late to using Launch Center Pro (App Store), and I use it in a similar way, only with OmniFocus instead of Drafts. I started using it when OmniFocus 2 for iPhone initially did not support TextExpander touch. It does now, but I found that I prefer Launch Center Pro’s buttons to typing abbreviations that the iPhone’s keyboard always seems to auto-correct away from what I actually typed.

I really like Launch Center Pro’s functionality, but editing actions is a pain. The URL text field is narrow, you have to manually percent-encode everything, and there is no undo history or version control like if I were editing scripts on my Mac.

BBEdit Codeless Language Module for Swift

Curt Clifton:

Keyword, comment, and string highlighting work. Top-level classes, structs, enums, functions, and extensions are indexed and can be folded. Because of limitations in the matching power of codeless language modules, nested declarations are not indexed and are not fold-able.

The basics seem to work well. It doesn’t handle access control keywords yet. A full language module would probably be necessary to handle overloaded methods well.

Understanding Apple’s Mastery of the Media

Mark Gurman:

Apple’s public relations (PR) department is probably the best in the world — certainly more impressive at shaping and controlling the discussion of its products than any other technology company. Before customers get their first chance to see or touch a new Apple product, the company has carefully orchestrated almost every one of its public appearances: controlled leaks and advance briefings for favored writers, an invite-only media debut, and a special early review process for a group of pre-screened, known-positive writers. Nothing is left to chance, and in the rare case where Apple doesn’t control the initial message, it remedies that by using proxies to deliver carefully crafted, off-the-record responses.

[…]

Two months in the making, this article is the product of over a dozen interviews with journalists, bloggers, and PR professionals, including many who have worked at Apple.

and:

Apple’s PR team isn’t above quietly spreading negative press about competitors. For instance, when a publication “has written something negative about Android, [Apple PR] would send those stories around,” telling writers something like “that’s how we feel.” As just one example, Apple PR sent this email to two 9to5Mac reporters earlier this week, attempting to underscore an Android app’s failures.

Apple Patches “Find My iPhone” Exploit

Arik Hesseldahl:

Apple said Monday it was “actively investigating” the violation of several of its iCloud accounts, in which revealing photos and videos of prominent Hollywood actresses were taken and posted all over the Web.

Owen Williams:

Users on Twitter were able to use the tool from GitHub — which was published for two days before being shared to Hacker News — to access their own accounts before it seems Apple patched the hole today. The owner of the tool noticed it was patched at 3:20am PT.

Adrian Kingsley-Hughes:

The code exploited a vulnerability with the Find My iPhone sign in page that allowed hackers to flood the site with password attempts without being locked out. By employing bruteforcing techniques, hackers could use this to guess the password used to protect the account.

James Cook:

So was Apple’s Find My iPhone vulnerability to blame for the iCloud hack? The speech that outlined the vulnerability took place at the Def Con conference in Russia on Aug. 30, leaving potential hackers only a small period of time to exploit the vulnerability, unless they were already aware of the brute force exploit. Evidence suggests that the leaked celebrity photos were gathered over a period of weeks, or even years, instead of a quick one-day attack, meaning that there may be a completely different vulnerability in iCloud that has yet to be discovered.

These days, an Apple ID is the key to a lot more than just photos.

Update (2014-09-02): Apple (via Mark Gurman and Jacob Kastrenakes):

After more than 40 hours of investigation, we have discovered that certain celebrity accounts were compromised by a very targeted attack on user names, passwords and security questions, a practice that has become all too common on the Internet. None of the cases we have investigated has resulted from any breach in any of Apple’s systems including iCloud or Find my iPhone.

It sounds like the Find My iPhone bug was real, just not used for this particular incident. It’s not clear whether the passwords were guessed or whether the accounts were compromised via Apple’s support staff through security questions or social engineering.

Nik Cubrilovic:

What we see in the public with these hacking incidents seems to only be scratching the surface. There are entire communities and trading networks where the data that is stolen remains private and is rarely shared with the public. The networks are broken down horizontally with specific people carrying out specific roles, loosely organized across a large number of sites (both clearnet and darknet) with most organization and communication taking place in private (email, IM).

[…]

In reviewing months worth of forum posts, image board posts, private emails, replies for requests for services, etc. nowhere was the FindMyPhone API brute force technique (revealed publicly and exploited in iBrute) mentioned. This doesn’t mean that it wasn’t used privately by the hackers – but judging by the skill levels involved, the mentions and tutorials around other techniques and some of the bragged about success rates with social engineering, recovery, resets, rats and phishing – it appears that such techniques were not necessary or never discovered.

[…]

Apple accounts seem particularly vulnerable because of the recovery process, password requirements and ability to detect if an email address has an associated iCloud account. […] It would be a good idea for Apple to kill the interface on signup that shows new users if their email account is available to use as an iCloud account or not. It would also be a good idea to make the recovery process one big step where all data is validated at once and the user is not given a specific error message. It would also be wise to attach rate limits and strict lockout on this process on a per-account basis.

[…]

Two-factor authentication for iCloud is useless in preventing passwords or authentication tokens being used to extract online backups.

Rich Mogull:

Apple did patch the vulnerability on 1 September, limiting the damage, although we don’t know how long the vulnerability existed and how widespread abuse may have been before the tool was released.

But based on Apple’s statement, the iBrute tool or some other direct attack on iCloud or Find My iPhone was not the source of the celebrity photo theft. That statement, however, was carefully constructed in case conflicting information later emerges in the investigation.

Sunday, August 31, 2014

Microsoft Excel 2011 for Mac Keyboard Shortcuts

Rows and Columns

Select Current Row
Shift-Space
Select Current Column
Control-Space
Insert Row Above
(Shift-Space,) Control-I
Insert Column Left
(Control-Space,) Control-I
Delete Row
(Shift-Space,) Control-Hyphen
Delete Column
(Control-Space,) Control-Hyphen

Multiple Cells

Fill Right
Control-R
Fill Down
Control-D
Clear Cells
Forward Delete (fn-Delete)

Cell Formats

Format Cells Dialog
Command-1
Format Number General
Control-~
Format Number With Thousands
Control-Shift-1
Format Time
Control-Shift-2
Format Date
Control-Shift-3
Format Currency
Control-Shift-4 ($)
Format Percentage
Control-Shift-5 (%)

Cell Borders

Toggle One Border
Command-Option–Arrow Key
Add All Borders
Command-Option-0
Remove All Borders
Command-Option-Hyphen

Cell Editing

Enter Edit Mode
Control-U
Move Insertion Point to Beginning
Home (fn–Left Arrow)
Move Insertion Point to End
End (fn–Right Arrow)
New Line in Same Cell
Control-Option-Return

Sheets

Next Sheet
Control-Page Down
Previous Sheet
Control-Page Up
Scroll to Selected Cell
Control-Delete

Source: Microsoft Excel Keyboard Shortcuts. Contrast with Numbers Keyboard Shortcuts.

Monday, August 25, 2014

The Swift Wish List

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

FastCoding

Nick Lockwood:

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

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

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

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

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

Building 3D With IKEA

Kirsty Parkin:

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

Sunday, August 24, 2014

objc.io on Testing

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

Pawel Dudek:

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

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

Arne Schroppe and Daniel Eggert:

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

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

[…]

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

[…]

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

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

Jon Reid:

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

[…]

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

[…]

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

Luis Solano:

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

[…]

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

Mike Lazer-Walker:

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

[…]

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

Klaas Pieter Annema:

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

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

Orta Therox:

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

What’s a Twitter Timeline?

Dan Frommer:

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

Scott Rosenberg:

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

John Gruber:

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

Update (2014-08-25): Jesper:

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

[…]

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

Update (2014-09-02): Brent Simmons:

What I do care about is that my blog isn’t part of a system where its usefulness is just a hook to get me to use it. It works the way I want to, and the company running the servers (DreamHost) doesn’t care one fig what I do.

[…]

The things that will last on the internet are not owned. Plain old websites, blogs, RSS, irc, email.

An Aperture User Tries Lightroom

Josh Anon:

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

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

Ode to Susan Kare’s Chicago

Alissa Walker (via John Gruber):

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

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

Yet Another Integer Underflow Bug

Nick Hamann (via David Smith):

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

Type-safe URL Routes in Swift

Chris Eidhof:

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

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

Macro-like Syntax Extensions Through Pseudo-closures

Christoffer Lernö:

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

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

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

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

Implicitly Converting Functions to Return Optionals

Airspeed Velocity:

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

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

Kännsch

Lukas Mathis:

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

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

Choosing Secure Passwords

Bruce Schneier:

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

[…]

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

lidx

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

SPF Records and Too Many DNS Lookups

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

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

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

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

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

Results - PermError SPF Permanent Error: Too many DNS lookups

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

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

My SPF record looked like it only had four lookups:

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

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

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

Now my SPF record looks like:

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

and it validates:

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

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

Knots 3D

Knots 3D (App Store):

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

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

Via Josh Centers and John Gordon.

iOS Resolution

John Gruber:

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

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

Saturday, August 23, 2014

Swift Function Currying

Russ Bishop:

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

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

[…]

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

Better Bash Scripting

Robert Muth:

I start every bash script with the following prolog:

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

This will take care of two very common errors:

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

[…]

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

[…]

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

Amazon vs. Hachette

Glenn Fleishman:

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

[…]

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

Christopher Wright (via John Gruber):

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

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

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

Thinking for Programmers

Leslie Lamport had a great talk at Microsoft Build 2014:

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

[…]

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

[…]

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

[…]

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

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

Swift Name Mangling

Gwynne Raskind:

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

[…]

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

Swift and Debuggability

Russell Ivanovic:

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

[…]

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