using System;
using System.Json;
using System.Net.Http;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.IO;
using Foundation;
using UIKit;
using Xamarin.Forms;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Globalization;
[assembly: Xamarin.Forms.Dependency(typeof(InABox.Mobile.iOS.Version_iOS))]
namespace InABox.Mobile.iOS
{
internal static class iOS_VersionExtensions
{
public static string MakeSafeForAppStoreShortLinkUrl(this string value)
{
// Reference: https://developer.apple.com/library/content/qa/qa1633/_index.html
var regex = new Regex(@"[©™®!¡""#$%'()*+,\\\-.\/:;<=>¿?@[\]^_`{|}~]*");
var safeValue = regex.Replace(value, "")
.Replace(" ", "")
.Replace("&", "and")
.ToLower();
return safeValue;
}
}
///
/// implementation for iOS.
///
public class Version_iOS : IAppVersion
{
string _bundleName => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleName").ToString();
string _bundleIdentifier => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleIdentifier").ToString();
string _bundleVersion => NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleShortVersionString").ToString();
JsonValue _appstoreInfo = null;
///
public string InstalledVersionNumber
{
get => _bundleVersion;
}
private async Task CheckAppStoreInfo(string appName)
{
if (_appstoreInfo != null)
return;
var url = $"http://itunes.apple.com/lookup?bundleId={appName}";
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();
_appstoreInfo = JsonValue.Parse(content);
}
catch (Exception e)
{
throw new LatestVersionException($"Error parsing content from the App Store. Url={url}.", e);
}
}
}
}
}
}
///
public async Task IsUsingLatestVersion()
{
string latestversion = string.Empty;
try
{
latestversion = await GetLatestVersionNumber();
return Version.Parse(latestversion).CompareTo(Version.Parse(_bundleVersion)) <= 0;
}
catch (Exception e)
{
throw new LatestVersionException($"Error comparing current app version number with latest. Bundle version={_bundleVersion} and lastest version={latestversion} .", e);
}
}
///
public async Task GetLatestVersionNumber()
{
return await GetLatestVersionNumber(_bundleIdentifier);
}
///
public async Task GetLatestVersionNumber(string appName)
{
if (string.IsNullOrWhiteSpace(appName))
{
throw new ArgumentNullException(nameof(appName));
}
await CheckAppStoreInfo(appName);
var version = _appstoreInfo["results"][0]["version"];
return version;
}
///
public Task OpenAppInStore()
{
return OpenAppInStore(_bundleName);
}
///
public Task OpenAppInStore(string appName)
{
if (string.IsNullOrWhiteSpace(appName))
{
throw new ArgumentNullException(nameof(appName));
}
try
{
var location = RegionInfo.CurrentRegion.Name.ToLower();
var trackid = _appstoreInfo["results"][0]["trackId"];
var url = String.Format("https://itunes.apple.com/{0}/app/{1}/id{2}?mt=8",location,appName,trackid);
//appName = appName.MakeSafeForAppStoreShortLinkUrl();
#if __IOS__
UIKit.UIApplication.SharedApplication.OpenUrl(new NSUrl(url)); // $"http://appstore.com/{appName}"));
#elif __MACOS__
AppKit.NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl($"http://appstore.com/mac/{appName}"));
#endif
return Task.FromResult(true);
}
catch (Exception e)
{
throw new LatestVersionException($"Unable to open {appName} in App Store.", e);
}
}
}
}