Version_iOS.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. using System;
  2. using System.Json;
  3. using System.Net.Http;
  4. using Foundation;
  5. using System.Threading.Tasks;
  6. using System.Text.RegularExpressions;
  7. using System.Globalization;
  8. [assembly: Xamarin.Forms.Dependency(typeof(InABox.Mobile.iOS.Version_iOS))]
  9. namespace InABox.Mobile.iOS
  10. {
  11. // internal static class iOS_VersionExtensions
  12. // {
  13. // public static string MakeSafeForAppStoreShortLinkUrl(this string value)
  14. // {
  15. // // Reference: https://developer.apple.com/library/content/qa/qa1633/_index.html
  16. //
  17. // var regex = new Regex(@"[©™®!¡""#$%'()*+,\\\-.\/:;<=>¿?@[\]^_`{|}~]*");
  18. //
  19. // var safeValue = regex.Replace(value, "")
  20. // .Replace(" ", "")
  21. // .Replace("&", "and")
  22. // .ToLower();
  23. //
  24. // return safeValue;
  25. // }
  26. // }
  27. /// <summary>
  28. /// <see cref="ILatestVersion"/> implementation for iOS.
  29. /// </summary>
  30. public class Version_iOS : IAppVersion
  31. {
  32. string _bundleName => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleName").ToString();
  33. string _bundleIdentifier => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleIdentifier").ToString();
  34. string _bundleVersion => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleShortVersionString").ToString();
  35. JsonValue _appstoreInfo = null;
  36. /// <inheritdoc />
  37. public string InstalledVersionNumber
  38. {
  39. get => _bundleVersion;
  40. }
  41. private async Task CheckAppStoreInfo(string appName)
  42. {
  43. if (_appstoreInfo != null)
  44. return;
  45. var url = $"http://itunes.apple.com/lookup?bundleId={appName}";
  46. using (var request = new HttpRequestMessage(HttpMethod.Get, url))
  47. {
  48. using (var handler = new HttpClientHandler())
  49. {
  50. handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
  51. {
  52. //bypass
  53. return true;
  54. };
  55. using (var client = new HttpClient(handler))
  56. {
  57. using (var responseMsg = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead))
  58. {
  59. if (!responseMsg.IsSuccessStatusCode)
  60. {
  61. throw new LatestVersionException($"Error connecting to the App Store. Url={url}.");
  62. }
  63. try
  64. {
  65. var content = responseMsg.Content == null ? null : await responseMsg.Content.ReadAsStringAsync();
  66. _appstoreInfo = JsonValue.Parse(content);
  67. }
  68. catch (Exception e)
  69. {
  70. throw new LatestVersionException($"Error parsing content from the App Store. Url={url}.", e);
  71. }
  72. }
  73. }
  74. }
  75. }
  76. }
  77. /// <inheritdoc />
  78. public async Task<bool> IsUsingLatestVersion()
  79. {
  80. string latestversion = string.Empty;
  81. try
  82. {
  83. latestversion = await GetLatestVersionNumber();
  84. return String.IsNullOrWhiteSpace(latestversion) || (Version.Parse(latestversion).CompareTo(Version.Parse(_bundleVersion)) <= 0);
  85. }
  86. catch (Exception e)
  87. {
  88. throw new LatestVersionException($"Error comparing current app version number with latest. Bundle version={_bundleVersion} and lastest version={latestversion} .", e);
  89. }
  90. }
  91. /// <inheritdoc />
  92. public async Task<string> GetLatestVersionNumber()
  93. {
  94. return await GetLatestVersionNumber(_bundleIdentifier);
  95. }
  96. /// <inheritdoc />
  97. public async Task<string> GetLatestVersionNumber(string appName)
  98. {
  99. String version = "";
  100. if (string.IsNullOrWhiteSpace(appName))
  101. {
  102. throw new ArgumentNullException(nameof(appName));
  103. }
  104. await CheckAppStoreInfo(appName);
  105. try
  106. {
  107. if (_appstoreInfo.ContainsKey("results"))
  108. {
  109. var results = _appstoreInfo["results"];
  110. if (results.Count > 0)
  111. {
  112. var result = results[0];
  113. if (result.ContainsKey("version"))
  114. version = result["version"];
  115. }
  116. }
  117. //version = _appstoreInfo["results"]?[0]?["version"] ?? "";
  118. }
  119. catch (Exception e)
  120. {
  121. }
  122. return version;
  123. }
  124. /// <inheritdoc />
  125. public Task OpenAppInStore()
  126. {
  127. return OpenAppInStore(_bundleName);
  128. }
  129. /// <inheritdoc />
  130. public Task OpenAppInStore(string appName)
  131. {
  132. if (string.IsNullOrWhiteSpace(appName))
  133. {
  134. throw new ArgumentNullException(nameof(appName));
  135. }
  136. try
  137. {
  138. var location = RegionInfo.CurrentRegion.Name.ToLower();
  139. var trackid = _appstoreInfo["results"][0]["trackId"];
  140. var url = String.Format("https://itunes.apple.com/{0}/app/{1}/id{2}?mt=8",location,appName,trackid);
  141. //appName = appName.MakeSafeForAppStoreShortLinkUrl();
  142. #if __IOS__
  143. UIKit.UIApplication.SharedApplication.OpenUrl(new NSUrl(url)); // $"http://appstore.com/{appName}"));
  144. #elif __MACOS__
  145. AppKit.NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl($"http://appstore.com/mac/{appName}"));
  146. #endif
  147. return Task.FromResult(true);
  148. }
  149. catch (Exception e)
  150. {
  151. throw new LatestVersionException($"Unable to open {appName} in App Store.", e);
  152. }
  153. }
  154. }
  155. }