Monday, October 8, 2012

Smart App Banners

The new version of Mobile Safari that ships with iOS 6 has a great new feature for app publishers: Smart App Banners.
When a user visits your site in Mobile Safari on iOS, you can now add a pop-up banner to promote your iOS app, which includes a direct link to the app in the App Store and optionally your iTunes affiliate information. David Smith has a great overview on his blog, and you can find all the details of Smart App Banners in Apple's Safari Web Content Guide on the Apple developer site.

Though I doubt that this will do away with all those annoying full-page "get our iPad app" pop-ups, I hope that at least some sites will start to use this instead. Thanks Apple for providing something to help sites promote their apps in a less annoying way.

Monday, July 30, 2012

Adding a Retina-ready icon to your Mac app in three easy steps

I've been doing more OS X development recently, and coming from the iOS world, there's a lot that's familiar but I still stumble over many things. Creating an app icon is one of them. After some poking around, I've discovered what you need to do to create a custom icon for your modern Mac app.

Step 1: Create the icon images
Modern Mac icons pack five different resolutions in one .icns file, from 16x16 to 512x512:
  • icon_16x16.png
  • icon_32x32.png
  • icon_128x128.png
  • icon_256x256.png
  • icon_512x512.png
The dimensions are actually "points" rather than "pixels". On standard resolution displays, 1 point == 1 pixel; iOS developers are already familiar with handling "retina" resolution displays where 1 point == 2 pixels. These double resolution "retina" resources get "@2x" added to the base filename, so in addition to the five standard resolution icon images, you now need five double resolution ones:
  • icon_16x16@2x.png
  • icon_32x32@2x.png
  • icon_128x128@2x.png
  • icon_256x256@2x.png
  • icon_512x512@2x.png
The names describe the icon size in points, so icon_16x16@2x.png is 32 by 32 pixels and icon_512x512@2x.png is 1024 by 1024 pixels. Some of these images have equivalent pixel sizes: icon_32x32.png and icon_16x16@2x.png are both 32 by 32 pixels. You may be able to get away with using the same bitmap in many cases, but you (or your icon designer) may want to tweak each version to look best on their respective display types.

Step 2: Add an .iconset to the Xcode project
In the olden days, you would use the Icon Composer app to build your .icns file, but it's no longer being updated by Apple and doesn't support double resolution images. Today, Xcode will build your .icns file automatically for you. (Alternately you can use the iconutil command line utility to build .icns with high res images or to extract images from .icns files; see Apple's High Resolution Guidelines for OS X for details.)

The trick to making Xcode build your .icns automatically is to put your set of icon images in a folder named <ICON_NAME>.iconset, where <ICON_NAME> becomes the base name for your .icns file. Add this folder to your Xcode project and Xcode will then create <ICON_NAME>.icns when you build, and automatically copy it to your app bundle.

Note that the images in the .iconset directory need to have the names given above: "icon_16x16.png" through "icon_512x512@2x.png" or you will see a warning in Xcode when building your project and the mis-named images won't be included.

Step 3: Add the icon to the Info.plist
To set your app's main icon, add the "Icon File" key to your app's Info.plist file and set the value to <ICON_NAME> (without the .icns extension). If you used the standard Xcode template to create your app, your Info.plist will be named "<APP_NAME>-Info.plist", where <APP_NAME> is your app or project name. For those of you who like to edit your .plist files as XML, the key name is CFBundleIconFile.

You can also drag the .iconset directory from the finder or the Xcode project navigator to the "App Icon" pane of the Summary tab for your app's target (pictured above). If you use this approach, Xcode will insist on copying the .iconset into the root folder of your project, even if you've already added the .iconset somewhere else in your project's directory tree (<sarcasm>another great example of Apple's attention to detail</sarcasm>.) If you're not fussy about your project organization, you can simply let Xcode have its way; otherwise you can remove the copy Xcode makes and add the .iconset in a more appropriate place, like the Resources folder; just make sure to leave the "Icon File" key in your Info.plist and Xcode will show the icon in the "App Icon" pane.

Easy as 1-2-3
Not hard once you figure it out, and a nicer workflow than having to wrestle with a half-baked special purpose app like Icon Composer.

Monday, July 9, 2012

Download iTunes Connect sales reports with Autoindigestion

When you start selling your first app in the app store, it's very exciting to check you sales every day in iTunes Connect. After the initial excitement wears off and your app sales settle into a steady state, it's easy to get involved in your next project and forget to log into iTunes Connect periodically to download your daily or weekly sales reports. Apple only makes the last 14 days of daily reports and the last 13 weeks of weekly reports available; if you're not diligent, time can fly by and you will lose important sales records.

Apple does provide a tool to automate the retrieval of iTunes Connect sales reports: the Auto-Ingest tool, a small Java command line app. While it's good that Apple provides an officially supported tool, it's a very minimal one. The Auto-Ingest tool only downloads one report at a time and doesn't have any intelligence for determining which reports have already been downloaded, nor can it handle downloading multiple report types or multiple iTunes Connect vendor accounts without some scripting help. Enter Autoindigestion.

Autoindigestion is a command line utility for Mac OS X Lion that uses the Auto-Ingest tool to automatically download daily and weekly sales reports. The first time it runs, Autoindigestion will grab all available reports; on subsequent runs it will download new reports based on the current date and the dates of previously downloaded reports. If you miss a day because your system is off or iTunes Connect reports are delayed, Autoindigestion will catch up the next time it runs. Autoindigestion can also be configured to handle multiple iTunes Connect vendors, which is great if you handle sales reporting for clients.

Autoindigestion is open source and available under a BSD style license. It's currently available as source from the Autoindigestion GitHub page. It is a native OS X command line program written in Objective-C and requires Xcode to build. Complete instructions for installing and configuring Autoindigestion are included on the GitHub page. I enjoyed creating Autoindigestion and hope you find it useful.

Wednesday, June 20, 2012

WWDC 2012 Videos

Apple has posted the videos and slides from the technical sessions of this year's Worldwide Developers Conference yesterday. The videos are available for free, but you need to be a registered Apple developer to watch them. (You can register at https://developer.apple.com/.)

As in previous years, there's a lot of good stuff here for iOS and OS X developers, as well as some sessions on other parts of the Apple ecosystem like Safari and iAds. Also featured this year are several sessions related to authoring content for the iBookstore using both EPUB 3 and Apple's proprietary iBooks Author formats. There are also a good number of sessions focused on getting the most out of Xcode and the Apple toolchain.

I've watched many of the videos from previous years and they are quite useful. If you are an experienced iOS developer, these sessions are a great way to help you get up to speed on the latest stuff. If you are new to iOS, the WWDC sessions, especially from previous years, contain some great overviews that will help you get up to speed fast. I highly recommend them.

Monday, March 5, 2012

Instance Variables in the Implementation File

Xcode
Recent versions of iOS and the Apple LLVM 2.1 compiler use an improved version of libobjc, the core library that powers Objective-C features like classes and method calls. This "modern runtime" library enables a lot of new, cool flexibility in creating Objective-C classes. One of my favorite new features is Instance Variables in the Implementation File, which allows you to move your private instance variables out of your .h files. iOS developer Tips shows you how.

Friday, February 24, 2012

Something wonderful: new Objective-C literal syntax

mountain lion cub going rawrrrrrWith the announcement of OS X 10.8 Mountain Lion, Apple made the beta version of Xcode 4.4 and the Mountain Lion SDK available to developers enrolled in the Mac Developer Program (the US$99 annual membership required to submit apps to the Mac App Store). The new OS X version has created a lot of developer buzz around Gatekeeper, the upcoming requirement that all apps in the Mac App Store run in a restrictive sandbox similar to iOS apps. This is a big problem for makers of development tools and other specialized apps that need low level access to the system; Apple has effectively banned many of them from the App Store. On the other hand, strong argument can be made that Gatekeeper and app sandboxing will be a big win for most non-technical Mac users.

The news about Mountain Lion isn't all bad for developers. Apple keeps their beta SDKs under a non-disclosure agreement, but with developer interest high for both iOS and OS X, details tend to leak out. CocoaHeads recently revealed that the Apple LLVM 4.0 compiler in the Xcode 4.4 beta includes support for an Objective-C literal syntax for NSDictionary, NSArray and NSNumber objects.

If you've done any Objective-C programming, you've seen the NSString literal syntax:
// NSString literal
NSString *name1 = @"Lana Kane";

// creating NSString from a C string literal
NSString *name2 = [NSString stringWithCString:"Sterling Archer"
encoding:NSUTF8StringEncoding];

An NSString literal is like a plain old C string literal, but prefixed with the '@' character. This has made using NSString objects easy, such as adding them to a NSArray. Using numbers, however, meant lots of tedious calls to [NSNumber numberWithXxx:...]. Like NSString literals, the new NSNumber literals are simply the plain old C number literals prefixed with '@'. This included character literals (since characters are simply small integers of type char) as well as the BOOL values YES and NO (though technically YES and NO are #define'd constants, not literals).
// new NSNumber literals
// and old style NSNumber creation
NSNumber *intNumber1 = @42;
NSNumber *intNumber2 = [NSNumber numberWithInt:42];

NSNumber *doubleNumber1 = @3.1415926;
NSNumber *doubleNumber2 = [NSNumber numberWithDouble:3.1415926];

NSNumber *charNumber1 = @'A';
NSNumber *charNumber2 = [NSNumber numberWithChar:'A'];

NSNumber *boolNumber1 = @YES;
NSNumber *boolNumber2 = [NSNumber numberWithBool:YES];

The new syntax supports the usual number suffixes like 'f' for float and 'u' for unsigned number types.
NSNumber *unsignedIntNumber1 = @256u;
NSNumber *unsignedIntNumber2 = [NSNumber numberWithUnsignedInt:256u];

NSNumber *floatNumber1 = @2.718f;
NSNumber *floatNumber2 = [NSNumber numberWithFloat:2.718f];

Having a compact NSNumber literal makes using numbers in collections much nicer. Here's a NSArray with some strings and numbers:
// an array with string and number literals
NSArray *array1 = [NSArray arrayWithObjects:@"foo", @42, @"bar", @3.14, nil];

// and the old way
NSArray *array2 = [NSArray arrayWithObjects:@"foo",
[NSNumber numberWithInt:42],
@"bar",
[NSNumber numberWithDouble:3.14],
nil];

This would be nice all by itself, but really shines when combined with the new NSArray and NSDictionary literals. Here is the array from above using the new NSArray literal syntax:
// an array literal
NSArray *array1 = @[@"foo", @42, @"bar", @3.14];

Like many popular languages today, NSArray literals use the square bracket characters '[' and ']' to delimit the array literal; the only twist here is you prefix it with '@' symbol. And thankfully, you no longer need to remember to put nil at the end!

And there's a similar notation for NSDictionary literals:
// a dictionary literal
NSDictionary *dictionary1 = @{ @1: @"red", @2: @"green", @3: @"blue" };

// old style
NSDictionary *dictionary2 = [NSDictionary dictionaryWithObjectsAndKeys:@"red", @1,
@"green", @2,
@"blue", @3,
nil];

The curly brace characters '{' and '}' delimit the dictionary literal and the colon ':' character to separate keys and values, similar to widely used languages like Python and JavaScript, but of course prefixed with '@'. I was never a fan of the backwards "ObjectsAndKeys" way of creating a NSDictionary, and I'm glad to have a much more compact alternative.

This new syntax is basically what Ole Begemann proposed in his blog in 2010 (EDIT: and Stig Brautaset proposed in his blog in 2008, and by others even earlier) and it's great to see that Apple is actively eventually listening to their developer community and finding real ways to make Objective-C a nicer language. Along with the @property syntax and ARC, this goes a long way toward reducing boilerplate code. Objective-C's dynamic object model, inspired by Smalltalk, has always made it more akin to dynamic languages like Python and Ruby than static ones like C++ and Java. ARC and compact container literals are big steps that take Objective-C further into dynamic language territory, yet the low level power of C is always available when you need it. I can't wait until this is released.

Update: Apple has committed a patch with the new syntax to the LLVM project.

Thursday, February 16, 2012

Add "Social Networking" with the Twitter & Accounts Frameworks in iOS 5

Recently, on the iOS Developer Network (iOS DevNet) on LinkedIn, I posted a discussion on integrating "social media hubs" into your iOS 5 app and provided some references.  Here is the discussion:

There are several ways to integrate your app with Social Media hubs like Facebook and Twitter. Now with the new Accounts and Twitter frameworks in iOS 5 Apple makes it even easier.

Peter Friese has a good post on his blog covering Accounts and Twitter integration.

Lasse Bunk shows another example using JSON and Storyboards in Xcode 4.2.

More information on Working with JSON and iOS 5 can be found in Marin Todorov's post on Ray Wenderlich's blog.

You can, and should, review Apple's document on on the Twitter Framework and the Accounts Framework to become familiar with the new APIs.

In addition, and if you like the feel of paper, or use the Kindle app, Amazon is now caring Apress's Beginning iOS Apps with Facebook and Twitter APIs: for iPhone, iPad and iPod touch book.

Cheers and good luck on your app's social integration.