Having fun with iTMSTransporter

I haven’t found much about this strange iTMSTransporter API enabling developers to script communication with iTunes Connect, so I dug and it was worth it.

Objective

I have 25 In-App Purchase products that are hosted by Apple, and these products need to be updated 2 to 4 times a year. Wow, that represents a lot of time, let’s write a script.

The solution : iTMSTransporter

The iTunes Connect
 Transporter is provided by Apple, an installer and the documentation are available through iTunes Connect under the “Resources & Help” section (you need to have a valid iTunes Connect account to access). Guess what? As an Xcode user, it’s already installed since the IDE itself is using the API to communicate with iTunes Connect when you uploading binaries (for instance).

It also can be used to:

  • upload app binaries
  • upload screenshots
  • update app metadata
  • manage app pricing
  • manage In-App Purchase products
  • etc.

Well yes, that’s basically the same possibilities than Application Loader, but scriptable.

How to use it?

Once it installed, let’s say that you have added it to you path, you can use the iTMSTransporter command and try to understand something to the help message.

There are basically 3 modes that can be easily translated into three steps, plus the one where you actually edit the information you want to send to iTunes Connect.

Step 1 : lookup for metadata

In my case, I had to find metadata related to a given In-App Purchase product identifier, so the first step is to download the .itmsp package from iTunes Connect with the following command:

iTMSTransporter -m lookupMetadata -u "$ITC_USERNAME" -p "$ITC_PASSWORD" -vendor_id "$ITC_PRODUCT_PARENT_ID"

Doing such will download a package (aka a directory that OS X will not open directly) with an XML file representing ALL THE DATA about your application. If you just need to update products one by one, you can easily add filters:

iTMSTransporter -m lookupMetadata -u "$ITC_USERNAME" -p "$ITC_PASSWORD" -vendor_id "$ITC_PRODUCT_PARENT_ID" -subitemids "$ITC_PRODUCT_ID" -subitemtype InAppPurchase

Step 2 : update metadata

This is the most challenging part since you need to update the metadata.xml file by adding or editing some fields.

As I was writing a shell script, I used xmlstarlet to work with my xml file. XPath

Note 1: if you want to upload some files (screenshots, .ipa files or .pkg files), you just need to add them to the .itmsp package and update the related fields in the metadata.xml file (such as the size of the file, or the md5 hash).

Note 2: except some required field, all the non-modified fields are ignored, you can safely remove some of them.

Step 3 : verify

iTMSTransporter -m verify -u "$ITC_USERNAME" -p "$ITC_PASSWORD" -f "$ITMSP_PATH"

If this command pass, you can go to the step 4, otherwise, you should carefully read the hints “provided” by Apple in the error log.

Step 4 : upload

iTMSTransporter -m upload -u "$ITC_USERNAME" -p "$ITC_PASSWORD" -f "$ITMSP_PATH"

Note: when the upload is completed, the sent package may take some processing time to appear on iTunes Connect, especially when sending In-App Purchase packages.

Voila !

The documentation found on iTunes Connect if “helpful”, but here is the best source of information I found: http://bou.io/UploadingScreenshotsWithITMSTransporter.html, this is about uploading screenshots but the process can be easily adapted.

Tracking and character spacing on iOS

Finally got to understand how to use the “tracking” value from the InDesign files I received for an app I’m working on. Thanks to this post from devsign, this is one more step to a pixel perfect label integration.

In tools like Photoshop and InDesign, tracking is the term that describes the relative amount of spacing between characters in a string of text.

A wonderful bit about tracking: pick a value, and your text will have that same visual style, regardless of the font size. It scales[…]

Source: http://www.devsign.co/notes/tracking-and-character-spacing

Open source projects should be more accessible to contributors

There are ton of developers out there, me included, who are looking for open source projects to help and improve their technical skills. It’s a good opportunity to dive into other people code, learn good practices and actually have code reviews from peers. Unfortunately, it’s often really hard to find a good project to actually contribute. And even then, it is difficult to know where to start and what you could actually do.

The project doesn’t work out of the box

The code can sometimes have a lot of dependencies and project developers didn’t take the time to write a “Getting started” note to help potential contributors to have a working copy of your project. Even when its there, it has to be up to date.

Project owner doesn’t explicitly say how contributors can help

What could potential others do to help in your project? That’s often unclear. They could find something to do by solving the issues, add features from a roadmap,  improve the tests coverage, everything is possible but usually hard to guess. Within issues, it’s usually better if they are tagged so it’s easy to see if it’s important or if it can be done without having a global knowledge of the project.

There is this post about the CONTRIBUTING.md file on Github, I like the idea and think it is a good place to gather all this thing that will help others to help!

I’m a really fan of the open source philosophy, I really would like to find more projects I could contribute 🙂

iOS and the status bar

Since iOS 7, there is this UIViewControllerBasedStatusBarAppearance or “View controller-based status bar appearance” option in Info.plist that aims to manage the way status bar appearance is set across the app.

Typical answers on Stack Overflow to questions regarding status bar text color not changing to white when using the UIApplication setStatusBarStyle: method or not disappearing when hiding will say:

Just set the “View controller-based status bar appearance” option to NO in your Info.plist.

That’s a mistake. By doing this, you are turning off the feature introduced in iOS 7. Even if I agree that this is convenient, I could not encourage you more to work with UIViewControllerBasedStatusBarAppearance set to YES.

Here are some things I learned trying to get it to work:

  1. The “Status bar style” and “Status bar is initially hidden” are still used during launch screen.
  2. If a view controller is not contained in a navigation controller and if you want to have a status bar with text colored in white, then you have to override the preferredStatusBarStyle method to say that you want the light content status bar style
  3. If you are using navigation controllers, the previous method is ignored so you should use [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];, status bar style is automatically set light content in this case
  4. To hide status bar, there is also this “prefersStatusBarHidden” method that you can override
  5. The overridden methods are called when  your view controller is first displayed, but you can force iOS to update status bar settings by calling [self setNeedsStatusBarAppearanceUpdate]; at runtime

A good example of something you can’t achieve with UIViewControllerBasedStatusBarAppearance set to NO: is getting the status bar to white text color when opening a MFMailComposeViewController; even with status bar default color globally set, the status bar stays written in black. To bypass that, you must change the option value to YES, and you can, for instance, create a category like this one:

#import "MFMailComposeViewController+StatusBarStyle.h"
@implementation MFMailComposeViewController (StatusBarStyle)
#pragma mark - Status bar management
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}
- (UIViewController *)childViewControllerForStatusBarStyle
{
    return nil;
}
@end

Part of the credit goes to this post: https://coderwall.com/p/hitv1q/mastering-ios-7-uistatusbarstyle