[Proposal] Add an API to Track App Versions (#124)
* Add an API to track app versions * Using the new Preferences model * Made a few changes and updated the sample * Added docs
This commit is contained in:
Родитель
267edd1c88
Коммит
64f6130493
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Caboodle
|
||||
{
|
||||
public static class VersionTracking
|
||||
{
|
||||
const string versionTrailKey = "VersionTracking.Trail";
|
||||
const string versionsKey = "VersionTracking.Versions";
|
||||
const string buildsKey = "VersionTracking.Builds";
|
||||
|
||||
static readonly string sharedName = $"{AppInfo.PackageName}.caboodle";
|
||||
|
||||
static Dictionary<string, List<string>> versionTrail;
|
||||
|
||||
static VersionTracking()
|
||||
{
|
||||
IsFirstLaunchEver = !Preferences.ContainsKey(versionsKey, sharedName) || !Preferences.ContainsKey(buildsKey, sharedName);
|
||||
if (IsFirstLaunchEver)
|
||||
{
|
||||
versionTrail = new Dictionary<string, List<string>>
|
||||
{
|
||||
{ versionsKey, new List<string>() },
|
||||
{ buildsKey, new List<string>() }
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
versionTrail = new Dictionary<string, List<string>>
|
||||
{
|
||||
{ versionsKey, ReadHistory(versionsKey).ToList() },
|
||||
{ buildsKey, ReadHistory(buildsKey).ToList() }
|
||||
};
|
||||
}
|
||||
|
||||
IsFirstLaunchForCurrentVersion = !versionTrail[versionsKey].Contains(CurrentVersion);
|
||||
if (IsFirstLaunchForCurrentVersion)
|
||||
{
|
||||
versionTrail[versionsKey].Add(CurrentVersion);
|
||||
}
|
||||
|
||||
IsFirstLaunchForCurrentBuild = !versionTrail[buildsKey].Contains(CurrentBuild);
|
||||
if (IsFirstLaunchForCurrentBuild)
|
||||
{
|
||||
versionTrail[buildsKey].Add(CurrentBuild);
|
||||
}
|
||||
|
||||
if (IsFirstLaunchForCurrentVersion || IsFirstLaunchForCurrentBuild)
|
||||
{
|
||||
WriteHistory(versionsKey, versionTrail[versionsKey]);
|
||||
WriteHistory(buildsKey, versionTrail[buildsKey]);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsFirstLaunchEver { get; private set; }
|
||||
|
||||
public static bool IsFirstLaunchForCurrentVersion { get; private set; }
|
||||
|
||||
public static bool IsFirstLaunchForCurrentBuild { get; private set; }
|
||||
|
||||
public static string CurrentVersion => AppInfo.VersionString;
|
||||
|
||||
public static string CurrentBuild => AppInfo.BuildString;
|
||||
|
||||
public static string PreviousVersion => GetPrevious(versionsKey);
|
||||
|
||||
public static string PreviousBuild => GetPrevious(buildsKey);
|
||||
|
||||
public static string FirstInstalledVersion => versionTrail[versionsKey].FirstOrDefault();
|
||||
|
||||
public static string FirstInstalledBuild => versionTrail[buildsKey].FirstOrDefault();
|
||||
|
||||
public static IEnumerable<string> VersionHistory => versionTrail[versionsKey].ToArray();
|
||||
|
||||
public static IEnumerable<string> BuildHistory => versionTrail[buildsKey].ToArray();
|
||||
|
||||
public static bool IsFirstLaunchForVersion(string version)
|
||||
=> CurrentVersion == version && IsFirstLaunchForCurrentVersion;
|
||||
|
||||
public static bool IsFirstLaunchForBuild(string build)
|
||||
=> CurrentBuild == build && IsFirstLaunchForCurrentBuild;
|
||||
|
||||
internal static string GetStatus()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("VersionTracking");
|
||||
sb.AppendLine($" IsFirstLaunchEver: {IsFirstLaunchEver}");
|
||||
sb.AppendLine($" IsFirstLaunchForCurrentVersion: {IsFirstLaunchForCurrentVersion}");
|
||||
sb.AppendLine($" IsFirstLaunchForCurrentBuild: {IsFirstLaunchForCurrentBuild}");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($" CurrentVersion: {CurrentVersion}");
|
||||
sb.AppendLine($" PreviousVersion: {PreviousVersion}");
|
||||
sb.AppendLine($" FirstInstalledVersion: {FirstInstalledVersion}");
|
||||
sb.AppendLine($" VersionHistory: [{string.Join(", ", VersionHistory)}]");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine($" CurrentBuild: {CurrentBuild}");
|
||||
sb.AppendLine($" PreviousBuild: {PreviousBuild}");
|
||||
sb.AppendLine($" FirstInstalledBuild: {FirstInstalledBuild}");
|
||||
sb.AppendLine($" BuildHistory: [{string.Join(", ", BuildHistory)}]");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
static string[] ReadHistory(string key)
|
||||
=> Preferences.Get(key, null, sharedName)?.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
|
||||
|
||||
static void WriteHistory(string key, IEnumerable<string> history)
|
||||
=> Preferences.Set(key, string.Join("|", history), sharedName);
|
||||
|
||||
static string GetPrevious(string key)
|
||||
{
|
||||
var trail = versionTrail[key];
|
||||
return (trail.Count >= 2) ? trail[trail.Count - 2] : null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@ The following cross-platform APIs are planned for our first release:
|
|||
- [x] Secure Storage
|
||||
- [x] SMS
|
||||
- [ ] Text-to-Speech
|
||||
- [x] Version Tracking
|
||||
- [x] Vibrate
|
||||
|
||||
## Contributing
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Caboodle.Samples.Model;
|
||||
using Caboodle.Samples.View;
|
||||
using Microsoft.Caboodle;
|
||||
|
||||
namespace Caboodle.Samples.ViewModel
|
||||
{
|
||||
public class HomeViewModel : BaseViewModel
|
||||
{
|
||||
private bool alreadyAppeared;
|
||||
|
||||
public HomeViewModel()
|
||||
{
|
||||
Items = new ObservableCollection<SampleItem>
|
||||
|
@ -35,5 +39,25 @@ namespace Caboodle.Samples.ViewModel
|
|||
}
|
||||
|
||||
public ObservableCollection<SampleItem> Items { get; }
|
||||
|
||||
public override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
|
||||
if (!alreadyAppeared)
|
||||
{
|
||||
alreadyAppeared = true;
|
||||
|
||||
if (VersionTracking.IsFirstLaunchEver)
|
||||
{
|
||||
DisplayAlert("Welcome to the Caboodle samples!");
|
||||
}
|
||||
else if (VersionTracking.IsFirstLaunchForCurrentVersion)
|
||||
{
|
||||
var count = VersionTracking.VersionHistory.Count();
|
||||
DisplayAlert($"Welcome to the NEW Caboodle samples! You have tried {count} versions.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
<Type Name="VersionTracking" FullName="Microsoft.Caboodle.VersionTracking">
|
||||
<TypeSignature Language="C#" Value="public static class VersionTracking" />
|
||||
<TypeSignature Language="ILAsm" Value=".class public auto ansi abstract sealed VersionTracking extends System.Object" />
|
||||
<AssemblyInfo>
|
||||
<AssemblyName>Microsoft.Caboodle</AssemblyName>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<Base>
|
||||
<BaseTypeName>System.Object</BaseTypeName>
|
||||
</Base>
|
||||
<Interfaces />
|
||||
<Docs>
|
||||
<summary>Provides an easy way to track an app's version on a device.</summary>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
<Members>
|
||||
<Member MemberName="BuildHistory">
|
||||
<MemberSignature Language="C#" Value="public static System.Collections.Generic.IEnumerable<string> BuildHistory { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property class System.Collections.Generic.IEnumerable`1<string> BuildHistory" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Collections.Generic.IEnumerable<System.String></ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the collection of build numbers of the app that ran on this device.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="CurrentBuild">
|
||||
<MemberSignature Language="C#" Value="public static string CurrentBuild { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property string CurrentBuild" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the current build of the app.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="CurrentVersion">
|
||||
<MemberSignature Language="C#" Value="public static string CurrentVersion { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property string CurrentVersion" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the current version number of the app.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="FirstInstalledBuild">
|
||||
<MemberSignature Language="C#" Value="public static string FirstInstalledBuild { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property string FirstInstalledBuild" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the build number of first version of the app that was installed on this device.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="FirstInstalledVersion">
|
||||
<MemberSignature Language="C#" Value="public static string FirstInstalledVersion { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property string FirstInstalledVersion" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the version number of the first version of the app that was installed on this device.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsFirstLaunchEver">
|
||||
<MemberSignature Language="C#" Value="public static bool IsFirstLaunchEver { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property bool IsFirstLaunchEver" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets a value indicating whether this is the first time this app has ever been launched on this device.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsFirstLaunchForBuild">
|
||||
<MemberSignature Language="C#" Value="public static bool IsFirstLaunchForBuild (string build);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsFirstLaunchForBuild(string build) cil managed" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="build" Type="System.String" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="build">The build number.</param>
|
||||
<summary>Determines if this is the first launch of the app for a specified build number.</summary>
|
||||
<returns>Returns true if this is the first launch of the app for the specified build number; otherwise false.</returns>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsFirstLaunchForCurrentBuild">
|
||||
<MemberSignature Language="C#" Value="public static bool IsFirstLaunchForCurrentBuild { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property bool IsFirstLaunchForCurrentBuild" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets a value indicating if this is the first launch of the app for the current build number.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsFirstLaunchForCurrentVersion">
|
||||
<MemberSignature Language="C#" Value="public static bool IsFirstLaunchForCurrentVersion { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property bool IsFirstLaunchForCurrentVersion" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets a value indicating if this is the first launch of the app for the current version number.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="IsFirstLaunchForVersion">
|
||||
<MemberSignature Language="C#" Value="public static bool IsFirstLaunchForVersion (string version);" />
|
||||
<MemberSignature Language="ILAsm" Value=".method public static hidebysig bool IsFirstLaunchForVersion(string version) cil managed" />
|
||||
<MemberType>Method</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Boolean</ReturnType>
|
||||
</ReturnValue>
|
||||
<Parameters>
|
||||
<Parameter Name="version" Type="System.String" />
|
||||
</Parameters>
|
||||
<Docs>
|
||||
<param name="version">The version number.</param>
|
||||
<summary>Determines if this is the first launch of the app for a specified version number.</summary>
|
||||
<returns>Returns true if this is the first launch of the app for the specified version number; otherwise false.</returns>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="PreviousBuild">
|
||||
<MemberSignature Language="C#" Value="public static string PreviousBuild { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property string PreviousBuild" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the build number for the previously run version.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="PreviousVersion">
|
||||
<MemberSignature Language="C#" Value="public static string PreviousVersion { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property string PreviousVersion" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.String</ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the version number for the previously run version.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
<Member MemberName="VersionHistory">
|
||||
<MemberSignature Language="C#" Value="public static System.Collections.Generic.IEnumerable<string> VersionHistory { get; }" />
|
||||
<MemberSignature Language="ILAsm" Value=".property class System.Collections.Generic.IEnumerable`1<string> VersionHistory" />
|
||||
<MemberType>Property</MemberType>
|
||||
<AssemblyInfo>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
</AssemblyInfo>
|
||||
<ReturnValue>
|
||||
<ReturnType>System.Collections.Generic.IEnumerable<System.String></ReturnType>
|
||||
</ReturnValue>
|
||||
<Docs>
|
||||
<summary>Gets the collection of version numbers of the app that ran on this device.</summary>
|
||||
<value></value>
|
||||
<remarks></remarks>
|
||||
</Docs>
|
||||
</Member>
|
||||
</Members>
|
||||
</Type>
|
|
@ -122,6 +122,7 @@
|
|||
<Type Name="ShareTextRequest" Kind="Class" />
|
||||
<Type Name="Sms" Kind="Class" />
|
||||
<Type Name="SmsMessage" Kind="Class" />
|
||||
<Type Name="VersionTracking" Kind="Class" />
|
||||
<Type Name="Vibration" Kind="Class" />
|
||||
</Namespace>
|
||||
</Types>
|
||||
|
|
Загрузка…
Ссылка в новой задаче