using System.Globalization; using InABox.Core; using Newtonsoft.Json; namespace InABox.Avalonia.Platform.iOS { public class iOS_AppVersion : IAppVersion { string _bundleName => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleName").ToString(); string _bundleIdentifier => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleIdentifier").ToString(); string _bundleVersion => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleShortVersionString").ToString(); private Dictionary _appstoreversion = new(); public Logger Logger { get; set; } public string InstalledVersionNumber() => _bundleVersion; public async Task IsUsingLatestVersion() { try { var info = await GetLatestVersion(false); return String.IsNullOrWhiteSpace(info.Version) || (Version.Parse(info.Version).CompareTo(Version.Parse(_bundleVersion)) <= 0); } catch (Exception e) { Logger?.Error($"Error in IsUsingLatestVersion(): {e.Message}\n{e.StackTrace}"); } return true; } private async Task CheckAppStoreInfo() { // http://itunes.apple.com/lookup?bundleId=com.prsdigital.prssiteapp var url = $"http://itunes.apple.com/lookup?bundleId={_bundleIdentifier}"; using (var request = new HttpRequestMessage(HttpMethod.Get, url)) { using (var handler = new HttpClientHandler()) { handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { //bypass return true; }; using (var client = new HttpClient(handler)) { using (var responseMsg = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead)) { if (!responseMsg.IsSuccessStatusCode) { throw new LatestVersionException($"Error connecting to the App Store. Url={url}."); } try { var content = responseMsg.Content == null ? null : await responseMsg.Content.ReadAsStringAsync(); var _appstoreinfo = JsonConvert.DeserializeObject>( content); if (_appstoreinfo.TryGetValue("results", out var results) && results is Dictionary dict && dict.FirstOrDefault().Value is Dictionary verinfo) _appstoreversion = verinfo; } catch (Exception e) { Logger?.Error( $"Error parsing content from the App Store. Url={url}\n{e.Message}\n{e.StackTrace}"); } } } } } } private AppInfo _info = null; public async Task GetLatestVersion(bool force) { if (force) _info = null; if (_info != null) return _info; _info = new AppInfo(); try { await CheckAppStoreInfo(); { if (_appstoreversion.TryGetValue("releaseDate", out var releaseDateObj) && releaseDateObj is string releaseDateStr && DateTime.TryParse(releaseDateStr, out DateTime releaseDate)) _info.Date = releaseDate; if (_appstoreversion.TryGetValue("version", out var versionObj) && versionObj is string versionStr) _info.Version = versionStr; if (_appstoreversion.TryGetValue("releaseNotes", out var releaseNotesObj) && releaseNotesObj is string releaseNotesStr) _info.Notes = releaseNotesStr; } } catch (Exception e) { Logger?.Error($"Error in GetLatestVersion(): {e.Message}\n{e.StackTrace}"); } return _info; } /// public Task OpenAppInStore() { try { var location = RegionInfo.CurrentRegion.Name.ToLower(); if (_appstoreversion.TryGetValue("releaseNotes", out var trackIdObj) && trackIdObj is string trackIdStr) { var url = String.Format("https://itunes.apple.com/{0}/app/{1}/id{2}?mt=8", location, _bundleName, trackIdStr); #if __IOS__ UIKit.UIApplication.SharedApplication.OpenUrl(new NSUrl(url)); #elif __MACOS__ AppKit.NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl($"http://appstore.com/mac/{appName}")); #endif } } catch (Exception e) { Logger?.Error($"Error in OpenAppInStore(): {e.Message}\n{e.StackTrace}"); } return Task.FromResult(true); } } }