iOS App Store Distribution Process – Random Notes for Titanium 2.x, Xcode 4.3, OS X 10.7

Creating a Distribution .ipa Using a Client’s Certificate & Profile WITHOUT Client’s iTunesConnect login credentials

Application Loader on OS X 10.7

  • In Application Loader, choose Deliver Your App for App Store distribution.
  • On OSX 10.7, Application Loader won’t come up through Spotlight. Go to /Applications/Xcode/Contents/Applications/ to find Application Loader.

General Initial Steps

To send to App Store you need an account w/ Agent level access (so Distribution tab shows up under Certificates in the portal) and these:

1. Distribution Certificate
2. Distribution Provisioning Profile

Apple’s details on how to create the Distribution Certificate using your Keychain Access on a Mac. At the end of this process you’ll have a .certSigningRequest file, which you then need to submit, via the iOS Provisioning Portal. Once it’s approved, you can download the certificate as a .cert file, double click it on your machine to install and then use KeyChain Access to save it in the .p12 file format.

Once the Distribution Certificate is ready, make a Distribution Provisioning Profile.

Titanium for iOS: Quick Profiling Example Using Xcode’s Instruments

One thing that, for now, sucks about Unity3D for iOS is that there seems to be no easy way to use a Profiler on your Unity generated .ipa file (am I wrong?). There’s progress on the Android side with this with official profiling support in Unity 4.0. While you can’t easily do 3D gaming using Titanium, you can use Xcode’s Instruments to profile your code to make sure there’re no memory leaks.

Titanium’s docs have a video on how to profile using Instruments. Here’s a simplified example .js file loaded into app.js, using the Single View application template in Titanium 2.x:

module.exports = function ApplicationWindow() {
	
	//load component dependencies
	var FirstPage = require('/ui/FirstPageView');
	var currentPg;

    //create component instance
	var self = Ti.UI.createWindow({
		layout: 'composite',
		width: Ti.UI.FILL,
		height: Ti.UI.FILL,
		backgroundColor:'#ffffff',
		navBarHidden:true,
		exitOnClose:true
	});

    currentPg = new FirstView(self);
    self.add(currentPg); 
   
    //will result in a memory leak that will show up as forever incrementing TiUIViewProxy instances in Instruments > Leaks under the "# Living" column 
	self.addEventListener('showSecondPage', function(evt){
		var SecondView = require('/ui/SecondPageView');
		self.remove(currentPg);
		currentPg = null;
		currentPg = new SecondView();		
		self.add(currentPg);	
	});

    return self;
}   

The above code would result in numerous leaks related to various subviews that exist whatever view is currently represented by the currentPg variable (FirstPageView or SecondPageView, depending on which event was fired). In my case, I profiled my app via Xcode’s Instruments, as directed here, and saw the TiUIViewProxy object incrementing forever, each time I went back to a particular page. It never moved from the
“# Living” to the “# Transitory” column.

The fix is fairly simple. I had to run a loop to setting all of currentPg’s subviews to null, “currentPg.children[i] = null”:

...
   //leak free version: 
	self.addEventListener('showSecondPageVersion2', function(evt){
		
           //clean up all subviews of currPage view (or app will get slower the longer you use it)		
		for(var i=0, l=currentPg.children.length; i<l; i++) {
			currentPg.children[i] = null;
		}

           var SecondView = require('/ui/SecondPageView');
		self.remove(currPage);
		currentPg = null;
		currentPg = new SecondView();		
		self.add(currentPg);	
	});
	...

You can improve the above code by adding a destroy() method to both FirstPageView.js and SecondPageViewjs and instead of using a loop in ApplicationWindow’s event listener just do currentPg.destroy().

Unity3D for iOS: “The Executable was signed with invalid entitlements” message from Xcode (Xcode install) and “Failed to Install” from device (iTunes install)

When to install via iTunes, Device says this after almost finishing install progress bar when installing with Dev Provisioning Profile:

"Failed to Install" 

When tried via Xcode’s Organizer, get this message:

The entitlements specified in your application’s Code Signing Entitlements file do not match those specified in your provisioning profile. (0xE8008016).

Looks like Code Signing issue when I tried moving .p12 files to another machine and publishing from that other machine.

When I looked in KeyChain Access on my main machine, under “Keys” in the left side Category menu, the MyCompanyPrivateKeyName had “iPhone Developer: SoAndSo ($*@#&&#$)” certificate. BUT on my 2nd machine, the one I tried moving the .p12 files to, MyCompanyPrivateKeyName listed the “iPhone Distribution: Company Name” certificate. I had to delete the Certificates and Private Keys in KeyChain Access and then re-install them, making sure I install the Dev .p12 file first.

This didn’t fix the problem, however.

After some more poking around, I noticed that, since I had more than one developer certificate installed on that machine (my personal one and 2 company ones), Xcode was by default picking up the wrong Dev Provisioning Certificate and trying to incorrectly use it to code sign my .ipa. To fix this, in Xcode I had to

  • select the project name in the Navigator (left side bar in Xcode)
  • select Unity-iPhone under Project or Targets
  • select the Build Settings tab
  • find the Code Signing section & make sure the “iPhone Developer” profile specified there is correct and matches your app’s Bundle Identifier (com.yourCompany.YourAppName, unless you’re using a generic one via the “*” wildcard)

Unity3D for iOS: “Apple LLVM Compiler 3.0 Error”… “iPhone_target_Prefix.pch’ has been modified since the precompiled header was built”

The Error

I upgraded to the latest minor version of Unity 3.5, specifically 3.5.5f. All was fine until I tried to create an Archive so I could publish an .ipa file from Xcode. Once I hit Product > Archive >, I got Build Failed with this error:

Apple LLVM Compiler 3.0 Error:
fatal error: file '/YourPathToProject/YourProjectName/Classes/iPhone_target_Prefix.pch' has been modified since the precompiled header was built

The Solution

After trying to Clean the project & a few other things, nothing worked. Finally, found this stackoverflow solution that fixed it. The Library folder path for the folder that had to be deleted was under
/YourUserName/Library/Developer/Xcode/DerivedData/{project name + gobly-gook}.

Unity3D for iOS: Debug.Log() Calls Show Up in Xcode’s Console

Debug call inside a Unity 3.5 script:

Debug.Log("DON'T MESS WITH TEXAS");

Xcode 4.2’s console log:


DON'T MESS WITH TEXAS
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
StateNameCollisn:OnCollisionEnter(Collision)
 
(Filename: /Applications/buildAgent/work/b0bcff80449a48aa/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)

adjustedForce: 2100
UnityEngine.Debug:Internal_Log(Int32, String, Object)
UnityEngine.Debug:Log(Object)
$:MoveNext()
 
(Filename: /Applications/buildAgent/work/b0bcff80449a48aa/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)