Dec 10

I read an interesting article at NYTimes Blogs about Apple’s Spot-the-Shopper Technology

The article claims that Apple’s system “has had the ability to show the in-store location of a shopper who has come to pick up a purchase”.

How does this work?

I don’t have any insider knowledge of how this system works, so this post is just my speculations. I know that I have very smart readers, so I’m curious to know what you think.

First let’s tackle the easier problem of knowing when a customer arrives at the store. Here are some ideas of this could work.

The Apple Store app could use a mechanism that is similar to the location reindeers in the Reminders app. As soon as the app realizes that the phone is in the vicinity of the Apple Store it sends a message to Apple. GPS is usually not very accurate indoors, but combined with Apple’s database of WiFi hotspots (I’m sure the Apple Store WiFi locations are in their database) it should be accurate enough to provide an alert.
The Apple Store app sends the MAC address of the WiFi network interface in the customer’s device to Apple. As soon as the device tries to connect to the Apple Store network, the MAC address is detected and the system is alerted that the customer has arrived.

Neither mechanism is foolproof. If the customer’s device is in airplane mode, for example, then I can’t think of any mechanism that would work. Since Apple is not advertising this functionality, it doesn’t have to work every time. But each time it does and a customer is delighted by the experience, it’s a win.

Now to the more difficult problem (I think) of locating a customer in the store.

The article shows an iPod touch with a map of the store and locations of people who have requested help highlighted in red.

For iPads with “help buttons” that are part of the store’s fixed display, it’s of course easy to place them on a map and highlight the location when someone asks for help.

But what about customers who have arrived to pick up a purchase? I can’t imagine that GPS is accurate enough inside a store inside a mall to pinpoint a customer.

I wonder if it’s possible for the WiFi access points inside the store to triangulate the location of a given MAC address with enough precision?

Have you experienced this system first hand? Were the Apple employees able to find you in the crowd?

Comments are open.

written by Nick \\ tags:

Nov 28

A long weekend is a good time to catch up on some reading of articles queued up in Instapaper. Here are several design related items that I found interesting.

Copycats

A well argued essay on why it’s so difficult to innovate and create great design. And why it’s so important to break through those barriers to be successful.

360iDev: Lessons from the design of Postage

Postage is a beautiful app for the iPhone. It is also very functional. I think the latter comes from Chris Parrish’s philosophy of “putting the user on rails”. Figure out what the main goal for a user of your app is, and make sure that goal can be accomplished as quickly and easily as possible. Great advice!

Apple, Kindly Remove Your OS Gestures from My App Canvas

I agree with Josh Clark that Apple blew it with these new “system” gestures in iOS 5. It would have been much better if these gestures started off the edge of the screen to give the user the clear indication that this gesture is something that is going to have an affect outside the context of the app that currently fills the screen. The gesture for showing the Notification Center does this, for example.

I think I know why Apple made this decision: to use the same gestures in Lion. In a windowed environment like OS X for the Mac, the context of the screen does not have the same meaning. So starting a gesture outside the screen does not make as much sense. And also, beginning a gesture with your fingers outside the physical area of a Magic Trackpad is awkward.

In my opinion, Apple made the wrong trade-off in this case, resulting in a worse user experience for iOS.

Exclusive: Matias Duarte on the philosophy of Android, and an in-depth look at Ice Cream Sandwich

This is a rather long article, but I’m not sure what it really says about the design philosophy of Android, if anything. My takeaway is that Matias Duarte is a very good and thoughtful designer who has strong opinions about design. I think this is good for Android. I think good design should convey and evoke opinions; an object should have a design personality.

Touchscreens have no hand

Information design legend Edward Tufte comments that touch screens are dead flat and have no texture. Maybe this is the reason for Apple’s recent fascination with skeuomorphism. (A simpler explanation is that the “more texture” decree came from the top.) In any case, I hope that Apple already has touch screens in their lab with haptic feedback so that we soon can feel real texture in our apps.

A Brief Rant on the Future of Interaction Design

Microsoft’s productivity future vision video made the rounds a while ago and was widely criticized for showing something that was not real, could never be made into a real product, and had many inconsistencies in the user interactions. While that may all be true, I think Bret Victor’s critique that is doesn’t go far enough is more spot on. His essay about our hands and how truly useful they could be in a future user interface is truly inspiring.

Dilbert November 27

Finally, I can’t help but to link to yesterday’s Dilbert strip. I think this is how we all feel about smartphone interface design at times.

written by Nick

Nov 22

With iOS 5 there’s a subtle change in behavior related to custom table view headers. Actually it’s just a more strict enforcement of the existing API. But the end result is the same: Your app may not work as you expected when running on iOS 5.

If you are implementing

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 

in your UITableViewDataSource then you must also implement

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

The heightForHeaderInSection method needs to return a height of 0.0 when the viewForHeaderInSection returns a nil for the case when there are no rows in that section. Otherwise you will see a lot of gray, empty header views in your table in iOS 5.

To Apple’s credit they have clearly stated this in the documentation for tableView:viewForHeaderInSection:

This method only works correctly when tableView:heightForHeaderInSection: is also implemented.

But if you missed this in the documentation and you’re wondering why your tables views suddenly don’t look so good in iOS 5, there’s your explanation. And the quick fix.

written by Nick \\ tags: , , ,

Nov 17

I saw the Steve Jobs interview movie by Robert X. Cringely today. For die-hard Apple fans it doesn’t contain any new information. But most stories about Steve Jobs are related second or third hand. This is a rare opportunity to see and hear the man himself. Very entertaining, and definitely worth watching if you get the chance.

There’s also an interesting and geeky story behind the movie. The full interview was thought to be lost for many years, until a VHS copy surfaced. With sophisticated image processing the VHS tape was used to create a movie that was watchable on the large screen of a movie theater. No small feat. It was very evident that the source material was not high definition, but it was not too distracting. Maybe that was because of the entertaining subject, or the reality distortion field coming through.

written by Nick

Nov 11

Happy 11-cubed day!

Everybody has been reviewing and posting excerpts from the Steve Jobs biography recently. So I’m going to talk about a different book.

If you’re already a fan of Neal Stephenson, you can stop reading now and just go and get the book. You won’t be disappointed.

Stephenson has written several classic Sci-Fi/Cyper-Punk/computer-related novels. Snow Crash and Cryptonomicon are two of my favorites. He made a detour, in my opinion, with the Baroque Cycle which I never managed to get through.

With Reamde he’s back in a contemporary setting and the story revolves around a fictional MMO called T’Rain. If you’re into playing World of Warcraft, then you’ll find the similarities and story plots very interesting.

Throw in a gang of international terrorists, rouge Russian mobsters, and a group of Chinese hackers, and you get a very intense and fast-paced thriller that moves between the virtual and real world.

This was the longest book I’ve read with iBooks (print length 1056 pages). With such an engrossing story, the chrome of the app and the iPad itself disappear. As I suspected the very realistic page turn animation in iBooks doesn’t matter when you’re actually reading a long book. However, one iBooks feature I found myself using frequently, and one that’s sorely missing in the Kindle app, is the number of pages remaining in the chapter. With Stephenson’s prolific writing don’t be surprised to see that you have 384 pages remaining in the current chapter…

written by Nick \\ tags: ,

Nov 04

A long standing “problem” with Cocoa has been Apple’s insistence that HTTP header field names are case-insensitive. This is clearly described in the documentation and also in the relevant RFC.

However not all server systems follow these standards so strictly and often require HTTP header field names to have a specific case. For example if the server expects the name “MyHeaderField” and your app sends “Myheaderfield” then the server may not read the value sent in the header field at all.

Your code may look something like this:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.server.com"]];
[request setValue:@"value" forHTTPHeaderField:@"MyHeaderField"];

The problem was that when the HTTP request is sent to the server, the case of the name of the header field was “helpfully” changed for you, without giving you any control over the exact change or any way to override it. In the example above the name would become “Myheaderfield” instead of “MyHeaderField”, which is what you specified in the code.

If you have control over the server API you could just ask the server team to look for “Myheaderfield” instead and all would be well. But if the server API was a third party serving multiple clients, you would have a problem.

With iOS 5 this behavior has changed. Now the header field names are not changed at all. Whatever you specify in your code is what is sent to the server. Nice!

If your code looks like the snippet above, and you made a deal with the server team to look for the modified case string, then you may have issues when your app is running on iOS 5. Of course in the perfect world where servers followed the RFC to the letter, there would not be an issue (in iOS 5 or earlier) because the server would not care about the capitalization and treat “MyHeaderField” and “Myheaderfield” as the same.

http://0xced.blogspot.com/2010/06/fixing-nsmutableurlrequest.html

http://www.cocoabuilder.com/archive/cocoa/142670-http-extensions-to-nsmutableurlrequest-erroneously-modify-headers.html

http://stackoverflow.com/questions/2543396/how-to-add-lowercase-field-to-nsurlrequest-header-field

written by Nick \\ tags:

Oct 28

Apple has made several subtle changes related to case (as in upper/lower/mixed-case) in the URL and HTTP communication classes for iOS 5. Here’s the first one, and more blog posts to follow.

With a UIWebView I often implement the shouldStartLoadWithRequest method in the UIWebViewDelegate to look at the link the user tapped and take specific action for certain types of links. Here’s a simple example that handles mailto links:

- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
	BOOL shouldStartLoadWithRequest = YES;
	
	NSString *scheme = [[request URL] scheme];
	if ([scheme isEqualToString:@"mailto"]) {
		[[UIApplication sharedApplication] openURL:[request URL]];
		shouldStartLoadWithRequest = NO;
	}
	
	return shouldStartLoadWithRequest;
}

Another common use is to handle application specific links like “MyApp://goto?id=42″. If you just replaced @”mailto” with @”MyApp” in the example code above, it turns out that this breaks in iOS 5. The reason is that iOS 5 returns “myapp” (all lowercase) for the scheme, whereas iOS 4 and earlier returned the actual string from the HTML link unaltered.

The solution is simple. Just make your string comparison case insensitive. For example:

if ([scheme compare:@"MyApp" options:NSCaseInsensitiveSearch] == NSOrderedSame) {

written by Nick \\ tags: , ,

Oct 21

One of the better known apps we at Pervasent have developed is the Zinio magazine reader app. For a while it’s been in the top 5 of the Top Grossing iPad Apps on the App Store. Duking it out with Apple’s Pages app, Angry Birds and Smurfs’ Village for the top spots.

Recently the Zinio app was awarded the “Best Global App” by the Internet Marketing Association at an award ceremony in Las Vegas. The event was opened by the Mayor of Las Vegas and streamed live to 11k people (out of IMA’s 350k members). So sounds like a pretty big deal. I’m not sure what the selection criteria was, or who the competitors were. But it doesn’t get much better than being the best global app. Nice!

written by Nick

Oct 14

Marco wrote a great post explaining the issues with local file storage in iOS 5. Please read it now and then come back.

There are also many threads on the Apple Developer Forums about this (developer login required):

Confusion

There is considerable confusion around this subject because there are many different issues discussed and lumped together:

  • The semantics of cache and tmp directories
  • Changes/gaps in Apple’s documentation
  • App review rejections
  • What is being backed up by iTunes and iCloud
  • Changes in behavior in iOS 5

Let’s discuss each issue separately:

The semantics of cache and tmp directories

If you have an OS X or Unix background, it’s easy to understand Apple’s position that such directories have no guarantee as to how long the data in them will persist.

The fact that the tmp directory in the app’s sandbox is not the same as the root /tmp directory, should not make a difference in how you think about this directory.

If you have never observed files being removed from these directories in the past, that is not a guarantee that it will not change in the future. Especially when the change is in accordance with documentation. This is a general rule.

Changes/gaps in Apple’s documentation

As late as June 29, 2011 Apple’s documentation regarding <Application_Home>/Documents said:

Use this directory to store user documents and application data files.

This is pretty clear. No wonder developers are unhappy that the rules for the Documents directory have changed in iOS 5 without any suitable alternative.

And regarding <Application_Home>/Library/Caches

Use this directory to write any application-specific support files that you want to persist between launches of the application or during application updates. Your application is generally responsible for adding and removing these files. It should also be able to re-create these files as needed because iTunes removes them during a full restoration of the device.

The phrasing in this section is definitely vague. The general impression that I get from reading this is that Apple has made a fundamental change with iOS 5 that contradicts this paragraph. But if you instead focus on the words "generally" and "able to re-create" you could argue that Apple has warned you what might happen to your files.

The iOS Data Storage Guidelines state:

To ensure that backups are as efficient as possible, be sure to store your app’s data according to the following guidelines:

1. Only documents and other data that is user-generated, or that cannot otherwise be recreated by your application, should be stored in the <Application_Home>/Documents directory and will be automatically backed up by iCloud.

2. Data that can be downloaded again or regenerated should be stored in the <Application_Home>/Library/Caches directory. Examples of files you should put in the Caches directory include database cache files and downloadable content, such as that used by magazine, newspaper, and map applications.

3. Data that is used only temporarily should be stored in the <Application_Home>/tmp directory. Although these files are not backed up to iCloud, remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device.

If we for the moment disregard the fact that sole purpose of many magazine, newspaper and map apps is to display content offline, these guidelines are clear and make sense.

App review rejections

Developers are reporting that apps that store any/some/much data in the Documents directory are being rejected by App Review.

It’s unlikely that the App Review team has detailed knowledge of which files are being stored in which directory and which of those are user generated vs. data that can be downloaded again or regenerated. Some developers have reported success in responding to the App Review team with an explanation of how their app is storing data and how that is in accordance with the rules.

What is being backed up by iTunes and iCloud

Everything in the app’s home directory is backed up, with the exception of:

  • The app bundle itself (.app)
  • <Application_Home>/tmp directory
  • <Application_Home>/Library/Caches directory

This is clear from the iOS Data Storage Guidelines and Michael Jurewitz comment.

Other documentation clearly states that the Application Support directory is also backed up by iTunes (and presumably iCloud). In the discussions some developers have suggested that Application Support directory would be safer (= more permanent) alternative to Caches. To me it seems that App Review would crack down on large amounts of data stored in Application Support with the same fervor as for the Documents directory, since it’s all about iCloud storage.

Changes in behavior in iOS 5

As of iOS 5, <Application_Home>/Library/Caches may be purged while your app is not running if the device experiences a low disk space warning.

What’s missing?

There is no longer a directory where your app can store files that are:

  • Not backed up to iTunes/iCloud
  • Not at risk of being purged

It’s obviously too late to implement this for iOS 5.0. But if enough developers make a case that this is really needed for their apps, then it might happen in a future version. Hint: file a bug report.

What’s a developer to do?

If you are currently storing files in the Documents directory

Your app will continue to work in iOS 5 without any issues. Your customers might complain about too much data being backed up to iCloud. (See below.)

However, when you update your app, it’s likely that it will be rejected for storing too much data in the Documents directory.

If you are currently, or are considering, storing files in the Caches directory

Make sure that your app can gracefully handle the situation when any of the files you stored in the Caches directory disappears. One way to handle this is to keep a list of all the files you store in Caches along with their source URLs. (And obviously store this file in a different, more permanent location.) Then at app start go through the list and verify that the files are still there.

If any files are missing you can show a dialog to the customer apologizing, explaining the situation, and asking if the files should be downloaded again. If the device is offline, you apologize and explain that the customer is screwed.

There are many more complicated situations than these two, e.g. where partial data is available. You need to decide what and how much data you can display.

I love the use case pointed out by one of the developers in the Apple forums: His app is used by pilots to display maps. If he was to store the downloaded maps in Caches and they were suddenly deleted by iOS 5 and this was discovered while the plane is in the air, that could have some dire consequences. A dialog asking the pilot to download the maps data again would add insult to injury. Literally.

Migrating existing data

If you update your app to be compliant with the new iOS 5/iCloud rules and now store files in the Caches directory, then you should probably move any existing files from Documents to Caches. I’m sure that the app review team will not test this because they will not have an old version of your app with data saved. But it seems like the right thing to do.

Remember to not start a big job of moving files on the main thread during app startup. This will get your app killed by the startup timer watchdog.

Early warning

When the app is running, you can warn the customer if the device is running low on disk space. This will not prevent files from being removed, but at least it will raise some awareness about the issues.

I don’t know how low the available disk space needs to go before the iOS 5 cleaning process kicks in, and I doubt that Apple will ever specify this. Please add a comment to this post if you have any results from your own experiments.

Let Apple know that this is a big problem

File a bug report.

What’s a customer to do?

Until now, apps that store a lot of data in directories that are backed up have been a problem because the iTunes backup process took a very long time. This was especially true if a large number of files needed to be backed up.

With iCloud backup, customers may not want to use their precious 5 GB data allotment (or pay for additional storage) to backup what they consider to be non-essential data. It is possible to turn off iCloud backup for individual apps. Just go to this easy to find location in the Settings app: iCloud > Storage & Backup > Manage Storage > Backups. In the Backup Options list on this screen, backup can be turned on/off for each app. Since it’s unlikely that your customers will stumble across this setting, you may want to prepare a support email with these instructions.

It is my understanding, although I have not tested this yet, that turning off iCloud backup will not affect iTunes backups. But for customers who have cut the cord and are no longer syncing with their computer, they will be without any backup of their app data if it’s turned off as described above.

written by Nick \\ tags:

Oct 12

If you installed a beta version of iTunes along with the beta releases of the iOS 5 SDK, you may encounter a problem when trying to update to the public release version.

When I tried to update my non-development iOS device to iOS 5 with a beta version of iTunes 10.5 I was informed that I needed iTunes 10.5 to do this. Fine. Since I knew that 10.5 had been released to the public, I selected Check for Updates to download it. But the Software Update application said that there was no update available for me.

Solution: Download the iTunes disk image file here and install it.

written by Nick \\ tags: ,