AppViz, WTF?

AppViz 3 is a major rewrite of a product loved by many developers. Most parts of the app are completely new, but we know that two new features will be particularly contentious: cloud storage and a subscription model.

We’re developers selling a tool used by other developers. We know we can’t bullshit you with marketing buzzwords and a bunch of hand-waving. This post will explain exactly why we’ve introduced these features and let you draw your own conclusions. At a minimum, it will provide insight into the challenges and how we approached their solutions. If we’re lucky, you’ll agree with our pragmatism and continue to support our efforts.

tl;dr We’re not trying to screw you.

Learning from our past…

A product like AppViz should be easy to build, right? It just downloads a bunch of numbers in tab-delimited format, crunches the data and then reports it in graphs and tables. If only that were true.

We all know that the pace of iOS development has been staggering. In just five years, we’ve gone from the first apps on iOS 2 to the radical redesign of iOS 7. The iPhone itself has gone from being available in just the US to selling in a total of 100 countries. We’ve seen a completely new iOS device called the iPad and spectacular hardware improvements across the board. Mac developers also got to join in on the fun at the end of 2010. Publishers started selling iBooks like we sell apps that same year.

All of this, and it’s pretty incredible that many developers are just now celebrating their wood anniversary.

And through it all, Apple is using a time-honored development process: they’re making it up as they go along. Throughout those five years there have been a huge number of changes to the data coming out of iTunes Connect:

  • Changes to the formats and columns in existing reports
  • Changes to the data values in the reports
  • New kinds of reports, like financial and earnings reports
  • New kinds of data, like new regions and sales types
  • New offerings like iAds, Newstand and iBooks

A lot of this data doesn’t come in a nicely formatted file; the only way to get it is by scraping a web page. If you’ve ever done this, you know how fragile it can be: a web developer that makes a simple change to a <div> can ruin your finely crafted parser.

We also all know that Apple never gives away details of its future plans. When things like new regions are added, you’re lucky to get a couple of days notice. And even when you do have some advance notice, like knowing that Mac apps will be added to the reports, you still don’t have any details until they show up on Apple’s server.

At which point, you have a huge problem: every customer needs a new version and they need it now. It doesn’t matter if it’s a holiday or you’re on vacation. You’re under the gun to write some new parsing code, get it tested, and deployed as soon as possible.

If you’re still thinking about how easy it would be to write your own app to track reports, let me share a little of my own experience. Much of the work in the new financial reporting and reconciliation module is based on an internal tool called BeanCounter. I thought this tool would be fairly easy to write: all I had to do was replicate the stuff I had in our Excel spreadsheets.

After six months, I had pretty much covered all the edge cases and weird report formatting issues, but still had to manually download the reports. In fact, this final hurdle of scraping web pages is what eventually led to the partnership between the Iconfactory and IdeaSwarm. So yeah, even developers with over 35 years of professional experience fall for the “this should be easy” naiveté.

Cloud Storage

I’ll be honest. I wasn’t wild about the idea of storing iTunes Connect credentials and our data on a remote server. We live in an online world where security breaches are just another piece of daily news. I knew it would be a lot of work to keep my data safe.

Unfortunately, there’s no API for iTunes Connect (even though we’ve been asking for years.) We’d love the chance to use something like OAuth instead of raw credentials. Unfortunately, that rapid pace of change I mentioned above pretty much precludes a stable API to access iTunes. As a pragmatic developer, you have to go with what you have, not what you want.

The reality for us and many other developers is that our product team keeps growing. Having sales and other financial data locked away on my laptop became more and more of a problem. The information coming from iTunes Connect helps run our business and I needed to share it with employees and partners. If you’re managing iTunes Connect information for some or all of your paying clients, you’ll have a similar problem.

Likewise, there are some kinds of data management that I don’t want to do. For example, adding events in the product details or reading reviews. Those tasks are better handled by a product manager and a person doing support. Again, the focus has shifted from the data itself to the people who manage it.

If you’re going to share data, you need to think long and hard about who’s going to have access and how it’s stored. In our case, there are two kinds of information that need to be protected: your iTunes Connect credentials and the report data that’s collected using those credentials.

We’re using 256-bit AES encryption for the iTunes Connect credentials. If you’re storing passwords with 1Password, you’re using the same encryption. We’re not going to divulge where the keys to decrypt this data are located, but we will say they’re not stored in source code or any other location on the server’s disk. They’re very hard for an attacker to access.

As far as our report data is concerned, we store it on Amazon S3 using Server Side Encryption (SSE). Access to this data is secured using SSL over a low latency connection to an Amazon server which uses AES-256 encryption. Amazon uses this same service for their own business-critical operations.

Passing data to the AppViz server before handing it off to the application on your Mac also has some big benefits for the user experience. Remember how frustrating it was when AppViz 2 couldn’t download your data because of some change that Apple had made on their site? With this new architecture, any changes to the data parser can be made directly on the server and minimize the downtime for all customers. There are monitors in place that let us know when reports aren’t importing correctly.

Finally, storing data in the cloud also allows us to offer new and exciting products. Personally, I’m dying to see things like:

  • The contents of the Dashboard module in an email as soon as the reports are ready to download.
  • Reports available on the web so that people don’t have to install an app to just read the basic information.
  • An iOS app that lets me keep an eye on the business while I’m on the go.

(Note: these are just ideas, not a promise that anything is going to get implemented!)

Private Storage

Still, with all of that said about cloud storage, there are still a lot of developers who are truly independent: one person with one set of reports. And these individuals love to be in complete control of their privacy and data. We want to keep these customers happy, too.

To do this, we’re planning on adding “private storage” to AppViz by the end of the year. This mode will offer the same resiliency to Apple’s changes since report collection and parsing remain on the server. The difference is that no reports or credentials will be stored after the data is exchanged. Now that our goal of implementing a robust download pipeline is accomplished, this secondary mechanism can be started.

When using private storage, iTunes Connect credentials will be passed to the AppViz server to initiate the connections at Apple. Data from those connections will then be collected and passed off to the application running on your Mac. After a successful transfer, the report data will be deleted from the server. No record of your credentials or data will be left behind.

Hopefully, you’ll agree that this is the best compromise between a constantly shifting data source and your own privacy.

Subscriptions

As a developer, you know that you spend a lot of time up front building a product and then amortize those costs over the years that it’s for sale. That initial hump can kill you, but long-term earnings make you do it over and over again :-)

Unfortunately, AppViz is not one of those products. It has huge ongoing costs based purely on maintenance. To give you an idea of the scale, there have been 32 releases for AppViz 2 over the past two years. That’s over one release per month and includes a lot of non-trivial work:

  • 67 new App Store countries
  • Financial regions going from 7 to 25
  • iAd support (with many releases to track changes on the web pages)
  • Report download changes (3 separate releases for changes in April 2012 alone)
  • New Newstand categories
  • New iBooks support
  • Rankings download changes
  • Rate limiting for rankings and reviews downloads
  • Adapting to changes on financial pages
  • New categories on iOS and Mac App Stores
  • Increased rankings from top 200 to 300

In the same time period, there was one release to support Mountain Lion, Gatekeeper and Retina displays.

The increase in the size of the development team is the best metric to show how maintenance has become such a huge cost. Initially there was one developer working on AppViz full-time: now there are three.

So, why don’t we just charge for more of the upgrades? AppViz doesn’t fit the “new features, paid upgrade” model. How would you feel if an upgrade fee was required to download and parse reports with a new region? Or if support was added for a new product category like Apple TV that you’re not using? My answer is that I’d feel like I was being held hostage: the app is broken until I upgrade or I’m forced to pay for something I don’t use.

For AppViz to be a viable venture in the future, the cost of the app must reflect the costs of this ongoing maintenance. In our view, subscriptions are the best fit.

Summary

There you have it, a couple thousand words to explain what used to be a huge “WTF?” Hopefully, this comprehensive essay shows that we’ve thought about the problem and have come up with a solution that’s both pragmatic and viable. If you still have questions or concerns, the folks at IdeaSwarm would love to hear from you.

A Quick Look plug-in for Provisioning

As every iOS developer knows, when your provisioning gets messed up, your life becomes a living hell. I don’t even want to think about how many millions of man hours have been wasted getting broken projects working again.

The root of the problem is always the .mobileprovision files that are kept in your Library > MobileDevice > Provisioning Profiles folder. The file either references a certificate that has expired or a device that no longer exists. There can also be issues with the entitlements that are contained in the profile when Team and App IDs don’t match.

A large part of the problem is that this file is not directly readable in a text editor like all the other parts of our Xcode projects. The file is encoded in the Cryptographic Message Syntax (CMS) described in RFC 3852.

After doing a bit of research, I found that decoding the payload of this file format is very simple thanks to some helpful functions in Apple’s Security framework. And once decoded, these .mobileprovision files contain nothing more than Property List (.plist) with a lot of useful debugging information.

I had previously been using a Quick Look plug-in from MacMation, but that site’s gone offline and the plug-in no longer worked in Mavericks. I had originally thought the problems on Mavericks were due to the new code signing requirements, but the root of the issue was that the content type UTI changed from com.apple.iphone.mobileprovision to just com.apple.mobileprovision so Quick Look ignored the old plug-in.

Eventually, I decided to write my own Quick Look plug-in and add a bunch of new stuff that I had been wanting to display:

  • Developer certificates: Making it easier to verify that your keychain items match what’s in the profile.
  • Provisioning Profile UUID: When someone on the project team checks in a new Provisioning Profile in the Build Settings, the only information you have is that UUID of that new file. Showing the UUID lets you find the right match.
  • Entitlements: Checking the Push Notification environment, ubiquity container identifiers, and keychain access groups is essential for any app that uses Apple’s services.
  • Links: Whenever the provisioning is broken you spend a lot of time in various sections of the Dev Center. Why not make it easy to get there?

The results of a few days work can be found on GitHub. If you’re lazy like I am, just download the .qlgenerator file and pop it in your Library > QuickLook folder. To get Quick Look to recognize the new plug-in you’ll need to either logout or poke Quick Look from the command line:

$ qlmanage -r

While you’re at the command line, do this to allow text to be copied from any Quick Look plug-in:

$ defaults write com.apple.finder QLEnableTextSelection -bool TRUE
$ killall Finder

(Macworld has more info about this nice hidden setting. Being able to copy text from a PDF preview is pretty damn handy!)

The next time you’re stuck in the Fifth Circle of Provisioning Hell, this simple plug-in may just bring you back to life. Viva!

Mac App Store Receipts and Mavericks

The storeagent and I aren’t getting along too well these days.

We’re in the process of getting a new release of xScope ready for release. As a developer tool, we’ve been compatible with Mavericks for several months now, but there are some minor bug fixes that we’d like to get out before the new version of OS X ships.

As you might be aware, this is the first time I’ve done a build on Mavericks itself. Things haven’t exactly been smooth sailing.

Today’s revelation is how storeagent creates the /Contents/_MASReceipt/receipt file in Mavericks. It’s subtly different, and will confuse the heck out of you until you understand what’s going on.

For the past few days, I’ve been testing a beta release of the .pkg using the standard command:

sudo installer -store -pkg /tmp/xScope.pkg -target /

This version had a CFBundleShortVersionString of “3.6.2b1″. The installer and receipt checking code was working great.

Until I did the final build and used the version string “3.6.2″. I got this message after I double-clicked the app and entered my Test User Apple ID:

After checking the code signing, bundle IDs and all other parts of the app, I finally fired up the debugger and discovered that the receipt validation code was failing when checking receipt attribute type 3, the Application version field (in Table 1-1).

After decrypting and checking the receipt payload, the value was “3.6.2b1″ not the version I just installed. Where did this old version number come from? Why did following the advice in the dialog and deleting the app not fix the problem. How come this old receipt kept showing up no matter what I did?

Receipts from older versions had never been a problem in previous versions of OS X, so there must be some new behavior in Mavericks. And it took me almost a whole day to figure out that new behavior.

It turns out that storeagent is doing some kind of in-memory cache of receipts that have been downloaded from iTunes. Since a network connection is needed to retrieve the receipt, keeping it around would prevent a little bit of network traffic. In previous versions, the receipt was presumably recreated each time it was requested, so you always had a fresh copy.

The workaround is fairly simple. It even gives me a bit of pleasure at this point:

$ killall -KILL storeagent

You’ll need to delete the app at this point and re-install it using:

$ sudo installer -store -pkg YourApp.pkg -target /

When you relaunch your app, you’ll see the Apple ID login dialog. Since storeagent is launched on demand by launchd, a new process will be started at this point. After entering your Test User credentials, a new, and valid, receipt will be written into the _MASReceipt folder.

One could imagine this caching of receipt data being a problem with apps that are downloaded from the App Store. If someone never reboots between two versions of the same app being “Ready for Sale”, it may trigger the same problem. I have no way to test this hypothesis.

For any Apple folks that might be reading, here you go: rdar://problem/15283740

Code Signing and Mavericks

The Change

Very simply put, you can no longer sign a bundle (like your .app) if any nested bundle in that package is unsigned. These nested bundles are things like helper executables, embedded frameworks, plug-ins and XPC services.

The result is that you’ll need to update your Xcode projects as soon as you start building on 10.9. It’s taken me several days to understand what these changes are, and with the help of Perry Kiehtreiber on the developer forums, I’d like to share what I’ve learned.

(Yes, I realize this essay is going to break the NDA, but since Apple is asking us to submit apps for Mavericks, I want as many developers as possible to avoid the utter confusion I faced earlier this week.)

The Effect

So what happens when you do your first app build on 10.9 using Xcode 5.0.1? If you embed a framework that’s unsigned, like the very popular Sparkle.framework, you’ll see a message during the final CodeSign build phase:

CodeSign build/Release/xScope.app
    cd /Users/craig/Projects/Mac/xScope
    setenv CODESIGN_ALLOCATE /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
    Using code signing identity "Developer ID Application: The Iconfactory"
    /usr/bin/codesign --force --sign D2A3FE1814B0BA31B1924F1C3C3B5C89643FBED5 --requirements =designated\ =>\ anchor\ apple\ generic\ \ and\ identifier\ \"xScope\"\ and\ ((cert\ leaf[field.1.2.840.113635.100.6.1.9]\ exists)\ or\ (\ certificate\ 1[field.1.2.840.113635.100.6.2.6]\ exists\ and\ certificate\ leaf[field.1.2.840.113635.100.6.1.13]\ exists\ \ and\ certificate\ leaf[subject.OU]\ =\ \"RYQWBTQRPT\"\ )) /Users/craig/Projects/Mac/xScope/build/Release/xScope.app
/Users/craig/Projects/Mac/xScope/build/Release/xScope.app: code object is not signed at all
In subcomponent: /Users/craig/Projects/Mac/xScope/build/Release/xScope.app/Contents/Frameworks/Sparkle.framework
Command /usr/bin/codesign failed with exit code 1

** BUILD FAILED **

The codesign command is reporting that “code object is not signed at all” and Xcode is adding the “In subcomponent” to tell you which framework is at fault (it could just have easily been HockeyApp or any other third-party framework you use.)

So how do you go about fixing this?

The Wrong Way

In the past, many developers have relied on codesign‘s --deep option to make sure the entire bundle is signed. Specifying this option in “Other Code Signing Flags” will get rid of the error during the build, but all you’re doing is just postponing the pain.

The reason is that --deep recursively signs the nested bundles. As it does this, it applies the parameters for the top-level bundle to all the nested bundles. Things like your app’s entitlements will cause the resulting bundles to not be valid.

In fact, if you try to download and install the resulting app, Gatekeeper will notify your customers that your app is damaged and can’t be opened, with a default button to move it to the Trash:

You’ll see the same thing if you check the binary using the command line:

$ spctl --verbose=4 --assess --type execute build/Release/xScope.app
build/Release/xScope.app: a sealed resource is missing or invalid

The Right Way

What’s the right way to make sure the embedded framework is correctly signed? The answer is to add another Build Phase to your target.

If you’re embedding frameworks, you’ll have a “Copy Files” phase that moves things like Sparkle.framework into the Frameworks destination. Just after this Build Phase, add a Run Script with the following shell commands:

LOCATION="${BUILT_PRODUCTS_DIR}"/"${FRAMEWORKS_FOLDER_PATH}"
IDENTITY="Developer ID Application: The Iconfactory"
codesign --verbose --force --sign "$IDENTITY" "$LOCATION/Sparkle.framework/Versions/A"

This short script tells Xcode to sign the framework that’s just been copied into the build product. In this case, it’s using the Developer ID for Gatekeeper. If you were doing a build for the Mac App Store you’d use your “3rd Party Mac Developer Application” identity. Add a codesign command for every framework you use.

If you have other embedded code, such as helper executables, plug-ins or XPC services, you’ll need to sign them appropriately after copying them into your app bundle.

Updated October 18th, 2013: Another alternative is to set the code signing identity in the Build Settings of the frameworks you’re building from source. The trick here is that the identity of the framework needs to match the identity of the app itself. You can’t have have an App Store distribution identity for the framework and a Developer ID for the app. I found it much easier to explicitly re-sign the frameworks than to pass configuration settings from MyApp.xcodeproj to MyFramework.xcodeproj. It’s also easier to manage because the project changes are the same for binary-only frameworks (like Sparkle) and frameworks we build from source (like Chameleon).

The Checks

You’ll want to do a quick check of the build product before uploading it to either your website or iTunes Connect. The first thing you’ll want to do is check the signed bundle meets its designated requirement:

$ codesign --verify --verbose=4 build/Release/xScope.app
--validated:/Users/craig/Projects/Mac/xScope/build/Release/xScope.app/Contents/Frameworks/Sparkle.framework/Versions/Current/.
build/Release/xScope.app: valid on disk
build/Release/xScope.app: satisfies its Designated Requirement

If there’s a problem, you’ll see a message that the app “does not satisfy its designated Requirement”. To view information about the signed code or the designated requirements, you can use these commands:

$ codesign --display --verbose=4 build/Release/xScope.app
$ codesign --display --verbose=4 build/Release/xScope.app/Contents/Frameworks/Sparkle.framework
$ codesign --display --requirements - --verbose=4 build/Release/xScope.app
$ codesign --display --requirements - --verbose=4 build/Release/xScope.app/Contents/Frameworks/Sparkle.framework

If this is a build you’ll be uploading to your website, you’ll want to make sure it will be accepted by Gatekeeper (and not display the “damaged” dialog.) Use spctl to do this:

$ spctl --verbose=4 --assess --type execute build/Release/xScope.app
build/Release/xScope.app: accepted
source=Developer ID

If this is an App Store build, you MUST check the .pkg file that gets uploaded to iTunes Connect (see the next section and you’ll see why I say MUST.) If you use productbuild to create the package manually, you’ll already have a .pkg file to test.

For those of you who submit archives directly from Xcode, you can generate the .pkg file using the command line:

$ xcodebuild -exportArchive -exportFormat PKG -archivePath /path/to/your.xcarchive -exportPath /tmp/CHOCKS -exportSigningIdentity "3rd Party Mac Developer Application: CHOCK LOCK INK” -exportInstallerIdentity "3rd Party Mac Developer Installer:  CHOCK LOCK INK"

You can find the path to your .xcarchive by selecting it in the Organizer and then using the Editor > Show in Finder menu item. The command above will create a /tmp/CHOCKS.pkg. Yes, you now have CHOCKS PACKAGE IF YOU KNOW WHAT I MEAN

(A quick side note, if you use xcodebuild, it got a lot of love in Mavericks. Make sure to check out the man page.)

To check out CHOCKS.pkg, run the installer with the -store option:

$ sudo installer -store -pkg /tmp/CHOCKS.pkg -target /
installer: Note: running installer as an admin user (instead of root) gives better Mac App Store fidelity
installer: CHOCKS.pkg has valid signature for submission: 3rd Party Mac Developer Installer: The Iconfactory
installer: Installation Check: Passed
installer: Volume Check: Passed
installer: Bundle com.artissoftware.mac.xScope will be installed to /Applications/xScope.app
installer: Starting install
installer: Install 0.0% complete
installer: Install 13.8% complete
installer: Install 22.2% complete
installer: Install 47.6% complete
installer: Install 88.3% complete
installer: Install 100.0% complete
installer: Finished install

Now, sign out of the App Store and launch the app that was just installed in your Applications folder. If everything is OK, you’ll see the prompt for your Apple ID and a receipt will be written in the app’s _MASReceipt folder.

But not always.

(For more information on testing installer packages, check out the Testing section in my Mac App Store Guide.)

The Suckage

After being installed for the first time, some apps never get a receipt when they are launched on Mavericks. The app starts up, sees that there’s no receipt in /Contents/_MASReceipt and signals that it’s missing by exiting with a 173 code. Normally, storeagent will recognize this and prompt for an Apple ID. After valid credentials are provided, the receipt is written and the app is launched again.

Several developers, myself included, have noticed that after exiting with a 173, only the following is logged in the console:

Oct 17 11:59:03 Myrtle.local storeagent[72031]: Unsigned app (/Applications/Twitterrific.app).

If this happens to you, it seems your only course of action is to not validate the receipt. Your code will launch fine if you never return a 173. Which, of course, sucks because it’s then trivial to pirate your the app.

For any Apple folks that might be reading this, check out the Radar: rdar://problem/15254213

Updated October 18th, 2013: Developers that are doing their builds on 10.8 also need to watch out for this problem. As a workaround, I tried building the product on 10.8.4 using Xcode 5.0. The resulting .pkg exhibited the same behavior at launch time as the one created with the Xcode GM on Mavericks.

The Workarounds

Xcode sometimes has problems generating a valid designated requirement. When you check the designated requirement, you might see this:

$ codesign --verify --verbose=1 build/Release/Twitterrific.app
build/Release/Twitterrific.app: valid on disk
build/Release/Twitterrific.app: does not satisfy its designated Requirement

$ codesign --display --requirements - build/Release/Twitterrific.app
Executable=/Users/craig/Desktop/BugReport/Ostrich/build/Release/Twitterrific.app/Contents/MacOS/Twitterrific
designated => anchor apple generic and identifier Twitterrific and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = RYQWBTQRPT)

If you look closely, you’ll see that the identifier used for the requirement is incorrect: it should be com.iconfactory.Twitterrific, not just Twitterrific. The workaround for this bug is simply to set the identifier explicitly in your Build Settings. In our case, we added --identifier com.iconfactory.Twitterrific to Other Code Signing Flags.

Updated October 18th, 2013: It looks like this bug happens when you precompile your Info.plist. Thanks to Chris Liscio for verifying that problem. Make sure to dupe it, if you’re affected!

As to why you’d want to precompile your Info.plist, there are two good reasons.

The End

There you have it: a short summary of my last three days of confusion caused by new Gatekeeper requirements, issues with Xcode and bugs in Mavericks. Hopefully, this essay will save you some of that same agony.

Sonderklasse

Let’s talk about cars for a second.

If you’re driving a car manufactured in the past five years, it’s likely it has anti-lock brakes. A standard feature at this point in time, but who came up with it first?

Mercedes-Benz first introduced it on the S-Class line back in 1978. It was a revolutionary technology and the first hint of how digital electronics would change the course of the automotive industry.

The S-Class pioneered many other safety innovations: crash crumple zones, air bags and traction control are a few of the most notable. This line has also become synonymous with comfort and luxury: it was the first Mercedes to be available with an automatic transmission. There’s even an armored version with a customized crocodile, gold and birch interior!

It’s clear this car is in a class by itself: “Sonderklasse”

“S-Class” is an anglicisation of “”S-Klasse,” a German abbreviation of “Sonderklasse,” which means “special class” (in the sense of “a class of its own”). In automotive terms thus refers to “a specially outfitted car”.

The current S600 model sports a 5.5L twin turbo V12 motor with a 7-speed automatic transmission. Enough power to propel a 4,950 lb vehicle from 0 to 60 mph in just 4.5 seconds. And that’s before AMG gets their hands on it. Impressive automotive technology, to be sure.

More importantly, these special cars have been recognized as a driving force behind the company’s success.

And now…

Another premium technology brand has an S-Class product: iPhone 5s.

“Craftsmanship”, “Power”, “Safety & Security”, “Ahead of its time”. Are we talking about a car or a phone?

Look at the words that dominate the iPhone 5s features page: Forward thinking. That’s a strategy that’s worked superbly at Mercedes-Benz for almost 60 years. I suspect Apple will get a pretty good run out of it, too.

Fingerprints

It looks like my hunch about the iPhone invite was right: new phones are likely to have “silver rings” that are fingerprint sensors embedded into the home button.

So what does this mean? Most people assume that it’s just going to be easier to access your home screen (without entering a passcode.) But I think it goes much deeper than that.

iCloud services are a huge part of Apple’s next decade. Everything the company is doing these days has some kind of connection to data that is stored remotely. They’re investing heavily in new data centers.

And anytime you want to access this data, you’re logging into iCloud. Wouldn’t it be great if you could skip the part where you have to type in your Apple ID?

It’s clear to me that your unique fingerprint will be tied to your unique Apple ID. Once this connection between your physical and online presences is established, some very interesting things become possible. Let’s take a look at a few things I think might happen:

Protecting access to apps

From the beginning, I’ve wanted a way to protect my personal information when sharing a device with friends and family. But any secure solution to that problem would be a pain in the butt. Typing a password before launching an app? No thanks!

But imagine if opening your favorite Twitter app only required a fingerprint scan before proceeding. Everyone’s favorite Twitter prank would thankfully die. And more importantly, we’d all feel a lot better about using things like online banking apps.

Corporate security

Most corporate networks are protected by VPN. The profiles that enable this network configuration often specify that a user must use a passcode lock. And it’s rarely a simple passcode. And it kicks in immediately.

Imagine needing to type in a eight character password with letters and numerals just to check the current weather. That’s a reality for millions of people who use their device for both personal and business tasks.

A fingerprint scanner that avoids this complex password will sell a lot of devices.

Multiple accounts

There are many scenarios where you want to let someone do whatever they want with your personal device: a partner providing directions while you drive, a kid playing games in a waiting room, your parents looking at vacation photos. All these people have something different than you: a fingerprint.

Entering a login and password has always seemed out of place in the simplified world of iOS. But detecting which account to use when tapping on the home button actually makes it easier for members of your family to use your personal device: they don’t even have to slide to unlock.

And once everyone has their own personal space on the device, no one can mess with it. This is important in many contexts: even something simple like a game has sensitive information as soon as a sibling comes along and screws up high scores or play position.

Borrowing devices

Most of us backup our data to iCloud. That data is restored to a device when it’s first put into service or if something goes wrong.

Now imagine if you had the ability to restore your data onto any device with the touch of your finger. Borrow an iPad and make it yours instantly. Businesses that strive to make a customer feel at home, like hotels and airlines, would love this capability.

Personal identification

If you think Apple is going to give developers access to this biometric information, think again. Google would love this data, so you know it’s not going to happen.

Slowly but surely

Don’t expect all these things to appear on September 10th. Apple will start out simply and continue to improve the software that uses this new sensor. That’s how they roll.

Acknowledgments: The genesis of these ideas came from a conversation with my colleague Sean Heber. He’s the one that first made the connection between iCloud and your finger. Thanks also go to Ryan Jones for the links about the sensor.

It’s the Production Line, Stupid

“Apple Absolutely Has To Make An iPhone With A Bigger Screen”

(Warning: Business Insider link)

While that may be true, take a look at what happened at the end of last year: 47.8 Million iPhones Sold.

That’s a shitload of iPhones. But how many is a shitload?

47.8M iPhones
/ 90 days = 530K per day
/ 24 hours = 22K per hour
/ 60 minutes = 369 per hour
/ 60 seconds = 6 per second

That means that every second of every day you need six cases, six headphone jacks, six LCD screens, six batteries, six CPUs, six 10µf capacitors, six 10kΩ surface mount resistors, and thousands of other components.

Look at where all the leaks about new products come from: it’s always the supply chain that produces all these components. This should give you an idea of how many partners are involved.

Basically, Apple creates a pipeline that produces devices at an amazing rate. And it’s a finely tuned machine with a lot of inertia. You don’t just walk in and say, “Hey, let’s change the screen!” Doing so would throw that machine out of balance: a new screen means that some of the components (like the headphone jack) don’t change, while others would (the case, for example.)

A finely tuned production machine takes a lot of time and money to set up. Take a look at Apple’s capital expenditures. A mere $10B in 2012.

These capital expenditures show that Apple is planning ahead. At least 2-3 years, maybe more. You don’t just walk into Foxconn and ask for 50M iPhones. You need to predict the future.

Sure, it would be great to have a larger screen iPhone from what is known about current market conditions. But was a larger screen a sure thing 2-3 years ago? While you were falling in love with the new Retina display on your iPhone 4, I bet you weren’t thinking “Man, this display has got to be bigger!”

The cost to setup that production line is also a part of the final cost of the device. More frequent changes to the production line means that each device costs more or earns less profit for Apple.

As Apple continues to sell ever more devices, I see two things that could happen:

  1. A broader range of products (meaning more, smaller production lines to spread the demand)
  2. Increase the size of the production lines along with amount of time they stay online (meaning new devices are introduced every three years instead of two)

Given the highly competitive nature of the mobile space, I suspect we’ll see the first option come into play in the coming years. In the meantime, screens tick, while speed tocks:

Cheap as in Computing

There’s a good case for an iPhone that costs less. But with this lower cost, developers fear that device specifications will suffer:

As someone who’s actively working on an iOS 7 update, I’m noticing a definite pattern emerging: we’re removing a lot of shadows, gradients, and transparency. A lot of views that were previously required to make an app look at home on iOS 6 are no longer needed.

The visual simplification of iOS has led directly to a simplified implementation. As every developer knows, the less work your app does on a mobile device, the better it performs. It’s a lot easier now to make an app that feels fluid and uses less CPU and GPU resources.

While everyone focuses on what Jony Ive has put on the screen, he’s also made the hardware under that screen able to do more with less. And yet again, Apple’s tight integration of hardware and software is going to kick everyone’s ass.

Updated August 14th, 2013: A lot of Twitter followers are saying, “But what about the live blurs? Aren’t those CPU/GPU intensive?”

Yes, they are. And you should also note that access to those features is strictly through private API. An iPhone 4 turns off blur, an iPhone 5C could do the same if necessary.

(If you look closely at the blur behind a toolbar, you notice that there’s some kind of sub-sampling of the screen image. Because this implementation is private, the algorithm could also be adapted for other devices.)

There’s also the question of all the new dynamics in the UI (like bouncy messages.) The highest costs in a GPU, both with computation and hardware components, is with dealing a lot of textures. The math for a physics engine is relatively easy to handle.

AMBER Alert Usability

If you live in the State of California, you got an AMBER Alert last night just before 11 PM. If you have an iOS device, you saw something like this on your lock screen:

Or like this in Notification Center:

And if you’re like most people, you had no idea what it meant. Considering it’s a broadcast to locate missing children, that’s a bad thing. Let’s examine the usability of this alert and think about how this system can be improved.

Updated August 6th, 2013: Lex Friedman has written a great summary of AMBER Alerts at Macworld. Among the revelations: the text of the messages are limited to just 90 characters!

First Impressions

In our household, there are many iOS devices. At the time of the alert, we were in the living room with two iPads and an iPhone. The alert’s sound is designed to get your attention, and that it did!

Both my wife and I gave each other that “what the hell is wrong” look as I grabbed my iPhone from my pocket. Turns out we weren’t the only ones who were frightened by the sound:

My wife’s first question as I looked at my phone was “Are we having a tsunami?” (we’ve had these kind of emergency broadcasts before.) I replied with, “No, It’s an AMBER Alert”. To which she replied, “What’s that?”

And therein lies the first problem: I had no idea.

Unlike all other notifications on my iPhone, I couldn’t interact with the alert. There was no way to slide the icon for more information or tap on it in the Notification Center to get additional information. Through a combination of Google and my Twitter timeline, I eventually figured it out:

But I was also seeing a lot of people on Twitter whose response to the confusion was to ask how to turn the damn thing off. And since AMBER Alerts aren’t affected by the “Do Not Disturb” settings, a lot of people went to Settings > Notification Center so they wouldn’t get woken again in the future.

That’s exactly what you don’t want to happen when a child is abducted.

Alert Text

In looking at the message itself, it’s hard to tell what it’s about. Starting an alert with an acronym may make sense to the government, but there’s wording that could resonate much effectively with normal folks:

It’s also hard to tell if this is a problem with “Boulevard, CA” or a “Nissan Versa”. And where is Boulevard? And what does a Nissan Versa look like? Who do I call if I see license 6WCU986? In summary, this notification provides more questions than answers.

This one image has answers to all of these questions and more. Why can’t I see that image after tapping on the notification?

The Alert Sound

As I mentioned above, the sound definitely let us know that something was wrong. But we were sitting comfortably in our living room. A friend of mine was driving at the time and probably listening to music from their iPhone on a car stereo. Being startled at high speed is dangerous:

Unlike the devices that existed when the AMBER Alert system was first introduced in 1996, our iPhones and iPads do a lot more than calls and texts. Music and video are immersive activities and hearing a loud horn can be a cure that’s worse than the disease.

Also, we’re all conditioned to immediately look at our phone when the normal alert sounds are used: a simple ding would have gotten just as much attention.

Do Not Disturb

And what the heck is up with this crazy sound happening if Do Not Disturb is turned on? Dammit, it’s my phone and I get to tell it what to do. Stupid Apple!

Well, take a look at your government first:

And if you want the details, it’s only going to cost you $205 to download:

Bottom line: these bugs aren’t going to be easy fixes.

(And if you think getting woken up because of an AMBER Alert is such a terrible thing, why don’t you explain your pitiful situation to this boy’s parents.)

File A Radar

Even though these bugs probably aren’t Apple’s direct problem, I’m still going to file a bug report. If you have a developer account, please feel free to duplicate that Radar.

Apple is in a very unique position to address these issues:

  • It has direct access to millions of customers and their mobile devices.
  • It employs many people with a deep understanding of how mobile devices are affecting our lives.

This is clearly a problem where cooperation between Apple, the Department of Justice, and the public can improve a system where everyone benefits. Better usability with AMBER Alerts is case where “think of the children” isn’t a trite platitude.

App Updates for iOS 7

Like many of my fellow developers, I am in the middle of an update of an app for iOS 7. As you’d expect, it’s a lot more work than previous versions of iOS. But results are stunning: both David Lanham and I have commented that our shipping version was “feeling old and clunky.”

While cranking along on the update, a couple of thoughts occurred to me: how many other developers were doing the same thing and were they going to commit fully to iOS 7? The depth and breadth of the changes in iOS 7 makes it difficult to support older versions of the OS.

So I just asked. I also included a simple question that any developer who was actively working on an update would be able to answer as a sort of CAPTCHA.

After a little over 24 hours, I had my answers:

An overwhelming number of developers are updating apps for iOS 7. Of 575 valid responses, 545 developers indicated that they were working on an update for iOS 7. That’s an adoption rate of 95%!

Of those developers who were working on an update, I then calculated how many were going to require iOS 7 (and drop support for iOS 6):

Just over half of developers (284 of 545) were leaving the past behind. Initially I was surprised that this number was so high, but then I remembered how much time and effort I was putting into my own work :-)

If you’re a consumer of apps, this is great news: it’s likely that your favorite apps will be ready for action come this fall. If you’re someone who has a device that’s a couple of years old, now’s the time to start thinking about upgrading. Many apps will require a device capable of running iOS 7.

After I posted the survey, I heard from several game developers who complained that they didn’t know the answer to the trick question: UIView -tintColor is only used in traditional interfaces. Most of the difficulty in adapting apps is changing navigational and content elements to match the new style. Games don’t have this problem: they’re basically all content. Considering these facts, my guess is that games will have much broader support for older versions of iOS.

If you’d like the raw data and my analysis using Numbers, here you go: iOS_7_Updates.numbers