Jan 23

The New York Times had a great article yesterday about the outsourcing to China of all consumer electronics manufacturing in general and the specifically manufacturing of iPhones.

Woven into the article is the fascinating story of how the plastic screen of the first iPhone was replaced with the Gorilla Glass that we know and love, in just six weeks before the iPhone went on sale. No other company besides Apple would even consider pulling off such a feat. And there’s no other place in the world besides Shenzhen China where it would be possible.

written by Nick

Jan 20

Yesterday Apple introduced iBooks Author at an education event in New York City. Almost immediately people were up in arms: How dare Apple introduce an application for free that does not meet all of their own personal needs? And the audacity of insisting on a EULA that favors Apple’s own devices and markets. Not to mention the fact that iBooks Author only runs on Macs. Of course I would also prefer a tool that solves more of my issues related to publishing, along with unicorns and free beer. But, since I’m not footing the bill for the development of iBooks Author, my opinions on this don’t carry much weight. So let’s move on and look at what iBooks Author really is.

iBooks Author is intended to solve a very narrowly defined problem: How to easily create and publish great looking interactive eBooks for the iBookstore to be read on iPads. From what I’ve seen, it solves this problem very well.

iBooks Author is not intended to be a general purpose ePub authoring tool. This is of course disappointing. Most people don’t know that Apple already has one of the very few commercial, easy to use tools for creating ePub files in the iWork Pages application for the Mac. It’s not all that great, but Pages solves the problem of writing a book containing mostly text, adding some images and saving it as an ePub. A disappointing consequence of the introduction of iBooks Author is probably that Pages will not see many future improvements to it’s ePub capabilities.

.ibooks vs. ePub

The output from iBooks Author is like ePub but not quite. If you open up the .ibooks file (it’s a zip archive just like ePub files are) you will see the same structure as an ePub. Each page has it’s own xhtml file, and there are a couple of XML files that describe the structure of the book.

Creating an ePub reader for iOS is not terribly difficult since the individual pages or chapters are pretty standard HTML files which can be displayed in a UIWebView. I believe that iBooks v1.x in essence was built around a UIWebView. But that has changed significantly with iBooks 2.

Examining xhtml files generated by iBooks Author in more detail and you’ll find a lot of non-standard CSS: -ibooks-layout-hint:, -ibooks-list-text-indent:, -ibooks-strikethru-type:, etc. I know there are several WebKit specific CSS extensions with the prefix -webkit, but I don’t know what WebKit, and much less a UIWebView would do with these new -ibooks extensions.

But it gets worse.

When you use one of the built-in widgets you will get code like this:
<object type=”application/x-ibooks+anchored” data-anchor-ref=”danchor-gallery-0″> This code must trigger something in the iBooks 2 binary that renders the widget. It would have been nicer if iBooks Author generated standard JavaScript+CSS here instead. The native approach was probably done for performance reasons, as anyone who has tried to develop complex, interactive animations with JavaScript and CSS can attest to.

A consequence of these design decisions is that it’s no longer possible to load the xhtml files into a UIWebView and see a fully rendered page. This begs the question of how did they implement these new features in iBooks 2? I don’t see any way to just use the public APIs of a UIWebView to accomplish this. But given the debacle when iBooks was caught using a private API for adjusting the screen brightness, it seems unwise to go down that path again. Maybe they started from scratch using the WebKit open source code? They would certainly have the talent at Apple to pull that off.

So why did Apple choose proprietary extensions to ePub instead of fully conforming to the standard? We can only speculate.

  • They want to lock in publishers to the iBookstore to boost the lagging number of titles.
  • They want to ensure only iPads sales benefit from this free tool.
  • They want full control over the format themselves.
  • Time and budget constraints forced them to take the easier path.
  • The current ePub standard does not provide all the functions and features they wanted to include.

I think there is some truth in all of the above, but I would put my money on the last one. See also John Gruber’s insightful analysis.

Given that the output format is closed, it would be possible for Apple to switch to a fully ePub compliant format as soon as the standards catch up. I don’t think this is very likely. But keep in mind that this is just the first version of iBooks Author.

Lack of iPhone compatibility

Curiously iBooks Author only generates ebooks for the iPad. I don’t think there are any technical reasons for excluding the iPhone and iPod touch. It’s more likely to be a content production issue. Creating the page layouts for these enhanced ebooks for the iPad is expensive enough. Forcing publishers to do the work twice to also target the iPhone, would probably be too much to ask.

For the educational market, the iPad is probably the right target. But if you are contemplating using iBooks Author to create ebooks for a wider audience, then the lack of support for iPhone and iPod touch is definitely a factor to consider.

Newsstand

One seemingly obvious application for iBooks Author is to create magazines to be distributed via Newsstand. Jason Snell of MacWorld wishes for this. The current EULA forbids content created with iBooks Author to be distributed via Newsstand (unless you give it away for free), but that is something it shouldn’t be too difficult to get an exception from Apple for, or conceivably see Apple change the EULA to include Newsstand in addition to iBookstore.

But given the architecture of iBooks 2 and the files generated by iBooks Author, it will be a challenge for third party developers to create magazine reader apps to display content generated by iBooks Author.

So should Apple create a generic magazine reader app, e.g. iNewsstand, that has similar features as iBooks, but also handles subscriptions and delivering content using the Newsstand infrastructure? That would be a bit odd to introduce now, as it would become a newsstand within the Newsstand folder. (Apple has actively discouraged third party magazine aggregators from making their apps Newsstand enabled.)

How about a sample project that magazine publishers can download and expand for their own use? This also seems unlikely as that would diminish some of the benefits Apple is achieving (deliberately or as a side effect) from the new proprietary file format.

IBooksPageViewController

An elegant solution to the problem of giving third party developers the ability to display content generated by iBooks Author would be to provide a new view controller that can read and display .ibooks files. It would be like a UIWebView on steroids. We can debate wether it should be a view or a view controller. Given the fixed page layout nature of ebooks created in iBooks Author, I think a view controller would be more appropriate.

Imagine the cool apps that can be created by developers if the creativity unleashed by the free iBooks Author tool could be harnessed in iOS apps. If Apple’s true intention is to keep the file formats proprietary and the technologies exclusive to the iOS platform, that is still achieved and further promoted with this solution.

I like this idea. I think I’ll go right now and submit a Radar for it.

written by Nick \\ tags: , ,

Dec 16

This post is on a very narrow issue, but one that I spent several hours tracking down and finding a fix for. Hopefully this will save some grey hairs for a few of my loyal readers and Google searchers.

An app that we’re working on connects to an IIS server and authenticates using NTLM. For security reasons (for this particular app) NTLM is the only acceptable authentication mechanism.

Therefore, in the didReceiveAuthenticationChallenge callback method we specifically check to ensure that the authentication method is the one we’re accepting.

- (void)connection:(NSURLConnection*)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge {

  if (([[[challenge protectionSpace] authenticationMethod] isEqual:authenticationMethod]) &&
    ([challenge previousFailureCount] <= kAllowedLoginFailures)) {

    [[challenge sender]  useCredential:[NSURLCredential
                    credentialWithUser:user.username
                              password:user.password
                           persistence:NSURLCredentialPersistenceNone]
            forAuthenticationChallenge:challenge];
  } else {
    [[challenge sender] cancelAuthenticationChallenge:challenge];
  }
}

This worked great until the app connected to a server over SSL. Then we experience a very strange behavior. Communication with the server worked fine the first time the app was launched. But after quitting the app and launching it a second time, all server communications failed.

After a bit of debugging and a liberal sprinkling of log statements we discovered that the server sometimes sent the authentication method NSURLAuthenticationMethodServerTrust instead of the expected NSURLAuthenticationMethodNTLM.

We spent some time digging deep into the settings for IIS. The idea of forcing IIS to only use NTLM authentication seemed promising. But in the end we were unable to find the right switch in IIS to get the behavior we desired.

So back to Xcode for a closer look at how authentication is handled. We soon came to the canAuthenticateAgainstProtectionSpace callback method. Which had this naïve implementation:

- (BOOL)connection:(NSURLConnection*)conn
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace*)protectionSpace {
  return YES;
}

After fixing this and rejecting authentication methods we can't or don't want to handle, the method now looks like this:

- (BOOL)connection:(NSURLConnection*)conn
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace*)protectionSpace {
  DLog(@"protectionSpace: %@", [protectionSpace authenticationMethod]);

  // We only know how to handle NTLM authentication.
  if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM])
    return YES;

  // Explicitly reject ServerTrust. This is occasionally sent by IIS.
  if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
    return NO;

  return NO;
}

The IIS server still sends NSURLAuthenticationMethodServerTrust occasionally but when the iOS app rejects it, IIS immediately follows with a request for NSURLAuthenticationMethodNTLM. The didReceiveAuthenticationChallenge method is then called with an authentication method that it can handle. All is well again.

written by Nick \\ tags: , , ,

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: , ,