Monday, October 24, 2011

Removing unwanted languages from AIR for iOS apps

IMPORTANT: This article is now obsolete. After the release of AIR 3.2 a new tag in Application descriptor, called <supportedLanguages>, is introduced. To read more about this visit this great article.

As many of the AIR developers have observed on iOS platform that their application when shown on iTunes store lists around 15 different languages. This is how it is and as of now there doesn't seem to be any solution to this. Well, you can work around this problem if you have Mac and Xcode installed.

I recently posted this work around while answering this post on Adobe Forums. So I will just re-organize the solution so that its easy to follow.

Before we actually start doing this we will create one plist file which will be used in the process given below(Only if you want to create a binary that will go on App Store through Application Loader). I will first tell you what are the contents of that file. Then I will take some time to describe its significance.

Create a file called Entitlements.plist with the contents given below.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string>XXXXXXXXX.com.your.id</string>
    <key>keychain-access-groups</key>
    <array>
        <string>XXXXXXXX.com.your.id</string>
    </array>
</dict>
</plist>

In this file
  • XXXXXXX is the AppIdentifierPrefix which you can see by opening mobileprovision file in textEdit look for 'ApplicationIdentifierPrefix'. If you are not sure what mobileprovision file is you should read this first
  • com.your.id is the same id of your app which is used for mobileprovision and is given as id in app descriptor 
What is this file about?

When apple codesigns the binary it can optionally combine the signature with an XML chunk which is specified in a property list file. Now, when I say optionally I mean this is optional operation when you just want to put your re-codesigned binary on your device and test. But absolutely not when you want to upload it for the app store review. There are some rules around this and also purposes of those tags which I wont discuss here for the sake of simplicity. So now I assume you have this file created somewhere on your Mac and will start the process of creating an ipa which enlists only the languages that you support.
  1. Generate the final ipa(preferably the one which is to be put on app store) with your favorite tool. Make sure you use distribution certificate and mobileprovision if you want to upload this binary through application loader. If you just want to test you can use development profiles also.
  2. Rename the generated binary from *.ipa to *.zip and extract it. This will create a folder called 'Payload' in the directory you extracted the archive.The contents of Payload is a folder called binaryname.app. (Mac gives this a special meaning and doesnt show it as a normal folder in finder. But its a actually a normal folder/directory)
  3. Right click on the .app in finder application and select show package contents. This will actually open the .app folder to show all the contents and assets of your application.
  4. Now, Inside .app delete all such x.lproj where x is not the language that you support. This is most probably sufficient for you. but if your application happens to support a language whose lproj did not already exist you can simply create <ISO-639-Code>.lproj folder for that language.
    Cool!! So, now you have a .app that supports only the languages that you actually support. But wait... We just modified the contents of .app which in turn invalidated the signature on .app package hence in the next step we will re codesign the .app so that we have valid signature applied to the packge with modified contents.
  5. Execute the following command. (I have assumed that I have unarchived the ipa in my current working directory)
    codesign -f -s "iPhone Distribution: Your Name" 
    "--resource-rules=./Payload/binary.app/ResourceRules.plist" 
    --entitlements "/path/to/Entitlements.plist" 
    "./Payload/binary.app"
    
    above command is pretty straight-forward. The string "iPhone Distribution: Your Name" comes from your "Keychain" You must have installed the distribution certificate in your keychain. If you are using development certificate(in step 1). Your string will become "iPhone Developer: Your Name (XXXXXXXXX)" process is same, you should have installed your development certificate in your keychain to see this entry.
    You can see the we are providing the --entitlements here whose value is the path to the file we just created at the beginning. Note that this switch is optional for the command to work correctly and hence can be omitted if you are using development certificates. But If you are planning to upload this binary to app store and using the distribution certificates you must provide this switch.
  6. Now, We are done. If you want to upload this binary to app store for review, just right click on .app folder and compress it to .zip and upload this .zip through Application Loader.
    If you want to install it on device and test, compress the parent 'Payload' folder and rename the compressed .zip to .ipa and put it on your device
Hope this article helps you guys to eliminate the unsupported languages from your apps to avoid bad comments and money refunds. cheers!!

3 comments:

  1. how to resign app on windows platform?

    ReplyDelete
    Replies
    1. Hi Georgi:

      This workaround is applicable only for mac systems. But in future versions of AIR you can specify the languages for your APP and same will be populated in Android and iOS Stores.

      Delete
  2. Is this solution stil necessary now that apple allows languages to be changed via iTunes connect?

    ReplyDelete