1

I have added Settings.bundle to my app to add version and build numbers in app settings, and it is added properly. The issue I have is, that it is always getting default value only and after that it is not updating it based on the value from actual app version and build number (even after running the app).

Root.plist:

<?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>StringsTable</key>
    <string>Root</string>
    <key>PreferenceSpecifiers</key>
    <array>
        <dict>
            <key>DefaultValue</key>
            <string>1.0</string>
            <key>Key</key>
            <string>current_version_number</string>
            <key>Title</key>
            <string>Version</string>
            <key>Type</key>
            <string>PSTitleValueSpecifier</string>
        </dict>
    </array>
</dict>
</plist>

I have created this custom class to update version and build number:

public static class SettingsBundleHelper
{
    static string AppVersionKey = "current_version_number";

    public static void SetVersionAndBuildNumber()
    {
        string version = NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleShortVersionString").ToString();
        string build = NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion").ToString();
        NSUserDefaults.StandardUserDefaults.SetString(AppVersionKey, $"{version}({build})");
        NSUserDefaults.StandardUserDefaults.Synchronize();
    }
}

App Delegate:

public override void OnActivated(UIApplication application)
{
    SettingsBundleHelper.SetVersionAndBuildNumber();
}

I followed this tutorial to implement this feature.

After this, version number in app settings is always 1.0

Another Question:

How to implement auto increment build number in Xamarin.iOS app? Because I don't want to update info.plist build number each time I create new ipa.

Moamen Naanou
  • 1,683
  • 1
  • 21
  • 45

2 Answers2

1

I think you are in a wrong way. We can just access the value from Settings.bundle but we can't change it at run time, since the settings bundle resides inside your app's bundle.

As you said, you have already known the NSUserDefaults and Settings.bundle always keep in sync. You can get the value from NSUserDefaults through the same Key. But what you should notice is that the NSUserDefaults will get the value after we have changed the value of Settings manually.

It means you will get null at the first launched time. This is why your tutorial calls setVersionAndBuildNumber() to set the NSUserDefaults's value from bundle. Then when Settings changes NSUserDefaults changes too.

In your case, you set a type PSTitleValueSpecifier, so this value can't be changed in Settings. Also we can't and shouldn't modify it dynamically at run time. Here is a sample about how to use Settings Bundle on Xamarin, you can refer to it for more details: https://github.com/xamarin/ios-samples/tree/master/AppPrefs

How to implement auto increment build number in Xamarin.iOS app?

As we said above, the file embed in our project can't be modified dynamically at run time. You should update it manually every time you want to archive a new ipa.

Ax1le
  • 6,563
  • 2
  • 14
  • 61
  • Thanks for your reply, but actually I believe it is possible to change the build number in app settings from code (not by updating plist file manually). Please check this https://stackoverflow.com/a/1144754/5746504 and https://stackoverflow.com/a/1061864/5746504 But I need a way to implement the same in Xamarin – Moamen Naanou Feb 07 '18 at 12:33
  • @MoamenNaanou As what Quinn said PlistBuddy is a command-line tool. it can modify plist file on mac just like what we can do using Xcode. Also that op may ask how to modify Settings.Bundle at build time not run time. – Ax1le Feb 07 '18 at 13:09
1

I have implemented the required by following this answer so I'm still using same Root.plist file which mentioned in my question, and then implemented the following:

  1. create new file in project directory BuildNumberIncremental.sh
  2. From Visual Studio -> Right click on Xamarin.iOS project -> Select Options -> under build node select Custom Commands -> Add new command as Before Build -> in Command field add sh BuildNumberIncremental.sh.
  3. Add the following script:

BuildNumberIncremental.sh

Version_Number=$(/usr/libexec/PlistBuddy ${ProjectDir}/info.plist -c "print :CFBundleShortVersionString")
Build_Number=$(($(/usr/libexec/PlistBuddy ${ProjectDir}/info.plist -c "print :CFBundleVersion") + 1))
Full_Version="$Version_Number(b$((Build_Number + 1)))"
/usr/libexec/PlistBuddy ${ProjectDir}/info.plist -c "set :CFBundleVersion $Build_Number"
/usr/libexec/PlistBuddy ${ProjectDir}/Settings.bundle/Root.plist -c "set PreferenceSpecifiers:0:DefaultValue $Full_Version"
  1. Replace ${ProjectDir} with your Xamarin.iOS directory.

Now each time I build the app, it will save new value in Root.plist i.e 1.5(b6)

Moamen Naanou
  • 1,683
  • 1
  • 21
  • 45