When working on Xamarin.iOS apps, we could use the configuration and platform options to define the bundle signing identities and profiles, but other application wide options like Bundle ID, version, icons, name... can't be configured for each configuration.
In general terms this wouldn't be a problem, but there are some cases where you will want to have different IDs for compilation, for example when development is made with your Apple developer account but publishing is made using customer's dev account.
For these cases we can use MSBuild compilation options inside the Xamarin iOS CSPROJ file to configure what we need for each case.
Creating the files needed
The first step is to create all the copies of info.plist and entitlements.plist we would need. In this example we would have one development info.plist and entitlements.plist and one appstore info.plist and entitlements.plist, as seen in the next picture:
In design time you only have access to the info.plist and entitlements.plist files, and need to manually edit the other configs.
Configuring what entitlements to use for each configuration
You will need to unload and edit the CSPROJ file for your Xamarin iOS app and locate the configuration you want to edit, in this case
AppStore | iPhone, to indicate the correct entitlements file:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
This way, the correct codesigning entitlements would be used. Now we only need to include the correct files for the configuration with a little fix: we need to make it appear as they use the original names, info.plist and entitlements.plist, as iOS need that exact files to exist to extract information.
Using LogicalName on MSBuild
To make the files have the correct name, we would use the LogicalName property in our files in the CSPROJ files where they are included:
<None Include="Info.plist" Condition=" '$(Configuration)|$(Platform)' != 'AppStore|iPhone' ">
<Content Include="Entitlements.plist" Condition=" '$(Configuration)|$(Platform)' != 'AppStore|iPhone' ">
<None Include="Info-AppStore.plist" Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
<Content Include="Entitlements-AppStore.plist" Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
As you can see, when the configuration is different to
AppStore | iPhone, the original Info.plist and Entitlements.plist are used.
But when we compile in
AppStore | iPhone configurations, the Entitlements-AppStore.plist and Info-AppStore.plist are used, but renaming the files to the original ones in the output.
This way, you can create different configurations, using different bundle IDs, versions, icons... easily.
Hope this helps, happy coding!