summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.iOS/Forms.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.iOS/Forms.cs')
-rw-r--r--Xamarin.Forms.Platform.iOS/Forms.cs373
1 files changed, 373 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.iOS/Forms.cs b/Xamarin.Forms.Platform.iOS/Forms.cs
new file mode 100644
index 00000000..b7a41826
--- /dev/null
+++ b/Xamarin.Forms.Platform.iOS/Forms.cs
@@ -0,0 +1,373 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Net.Http;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+#if __UNIFIED__
+using UIKit;
+using CoreFoundation;
+using Foundation;
+#else
+using MonoTouch.UIKit;
+using MonoTouch.CoreFoundation;
+using MonoTouch.Foundation;
+#endif
+using Xamarin.Forms.Platform.iOS;
+
+namespace Xamarin.Forms
+{
+ public static class Forms
+ {
+ //Preserve GetCallingAssembly
+ static readonly bool nevertrue = false;
+
+ static bool? s_isiOS7OrNewer;
+
+ static bool? s_isiOS8OrNewer;
+
+ static bool? s_isiOS9OrNewer;
+
+ static Forms()
+ {
+ if (nevertrue)
+ Assembly.GetCallingAssembly();
+ }
+
+ public static bool IsInitialized { get; private set; }
+
+ internal static bool IsiOS7OrNewer
+ {
+ get
+ {
+ if (!s_isiOS7OrNewer.HasValue)
+ s_isiOS7OrNewer = UIDevice.CurrentDevice.CheckSystemVersion(7, 0);
+ return s_isiOS7OrNewer.Value;
+ }
+ }
+
+ internal static bool IsiOS8OrNewer
+ {
+ get
+ {
+ if (!s_isiOS8OrNewer.HasValue)
+ s_isiOS8OrNewer = UIDevice.CurrentDevice.CheckSystemVersion(8, 0);
+ return s_isiOS8OrNewer.Value;
+ }
+ }
+
+ internal static bool IsiOS9OrNewer
+ {
+ get
+ {
+ if (!s_isiOS9OrNewer.HasValue)
+ s_isiOS9OrNewer = UIDevice.CurrentDevice.CheckSystemVersion(9, 0);
+ return s_isiOS9OrNewer.Value;
+ }
+ }
+
+ public static void Init()
+ {
+ if (IsInitialized)
+ return;
+ IsInitialized = true;
+ Color.Accent = Color.FromRgba(50, 79, 133, 255);
+
+ Log.Listeners.Add(new DelegateLogListener((c, m) => Trace.WriteLine(m, c)));
+
+ Device.OS = TargetPlatform.iOS;
+ Device.PlatformServices = new IOSPlatformServices();
+ Device.Info = new IOSDeviceInfo();
+
+ Ticker.Default = new CADisplayLinkTicker();
+ Registrar.RegisterAll(new[] { typeof(ExportRendererAttribute), typeof(ExportCellAttribute), typeof(ExportImageSourceHandlerAttribute) });
+
+ Device.Idiom = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad ? TargetIdiom.Tablet : TargetIdiom.Phone;
+
+ ExpressionSearch.Default = new iOSExpressionSearch();
+ }
+
+ public static event EventHandler<ViewInitializedEventArgs> ViewInitialized;
+
+ internal static void SendViewInitialized(this VisualElement self, UIView nativeView)
+ {
+ var viewInitialized = ViewInitialized;
+ if (viewInitialized != null)
+ viewInitialized(self, new ViewInitializedEventArgs { View = self, NativeView = nativeView });
+ }
+
+ class iOSExpressionSearch : ExpressionVisitor, IExpressionSearch
+ {
+ List<object> _results;
+ Type _targetType;
+
+ public List<T> FindObjects<T>(Expression expression) where T : class
+ {
+ _results = new List<object>();
+ _targetType = typeof(T);
+ Visit(expression);
+ return _results.Select(o => o as T).ToList();
+ }
+
+ protected override Expression VisitMember(MemberExpression node)
+ {
+ if (node.Expression is ConstantExpression && node.Member is FieldInfo)
+ {
+ var container = ((ConstantExpression)node.Expression).Value;
+ var value = ((FieldInfo)node.Member).GetValue(container);
+
+ if (_targetType.IsInstanceOfType(value))
+ _results.Add(value);
+ }
+ return base.VisitMember(node);
+ }
+ }
+
+ internal class IOSDeviceInfo : DeviceInfo
+ {
+ readonly NSObject _notification;
+ readonly Size _scaledScreenSize;
+ readonly double _scalingFactor;
+
+ public IOSDeviceInfo()
+ {
+ _notification = UIDevice.Notifications.ObserveOrientationDidChange((sender, args) => CurrentOrientation = UIDevice.CurrentDevice.Orientation.ToDeviceOrientation());
+
+ _scalingFactor = UIScreen.MainScreen.Scale;
+ _scaledScreenSize = new Size(UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height);
+ PixelScreenSize = new Size(_scaledScreenSize.Width * _scalingFactor, _scaledScreenSize.Height * _scalingFactor);
+ }
+
+ public override Size PixelScreenSize { get; }
+
+ public override Size ScaledScreenSize
+ {
+ get { return _scaledScreenSize; }
+ }
+
+ public override double ScalingFactor
+ {
+ get { return _scalingFactor; }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ _notification.Dispose();
+ base.Dispose(disposing);
+ }
+ }
+
+ class IOSPlatformServices : IPlatformServices
+ {
+ static readonly MD5CryptoServiceProvider Checksum = new MD5CryptoServiceProvider();
+
+ public void BeginInvokeOnMainThread(Action action)
+ {
+ NSRunLoop.Main.BeginInvokeOnMainThread(action.Invoke);
+ }
+
+ public ITimer CreateTimer(Action<object> callback)
+ {
+ return new _Timer(new Timer(o => callback(o)));
+ }
+
+ public ITimer CreateTimer(Action<object> callback, object state, int dueTime, int period)
+ {
+ return new _Timer(new Timer(o => callback(o), state, dueTime, period));
+ }
+
+ public ITimer CreateTimer(Action<object> callback, object state, long dueTime, long period)
+ {
+ return new _Timer(new Timer(o => callback(o), state, dueTime, period));
+ }
+
+ public ITimer CreateTimer(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period)
+ {
+ return new _Timer(new Timer(o => callback(o), state, dueTime, period));
+ }
+
+ public ITimer CreateTimer(Action<object> callback, object state, uint dueTime, uint period)
+ {
+ return new _Timer(new Timer(o => callback(o), state, dueTime, period));
+ }
+
+ public Assembly[] GetAssemblies()
+ {
+ return AppDomain.CurrentDomain.GetAssemblies();
+ }
+
+ public string GetMD5Hash(string input)
+ {
+ var bytes = Checksum.ComputeHash(Encoding.UTF8.GetBytes(input));
+ var ret = new char[32];
+ for (var i = 0; i < 16; i++)
+ {
+ ret[i * 2] = (char)Hex(bytes[i] >> 4);
+ ret[i * 2 + 1] = (char)Hex(bytes[i] & 0xf);
+ }
+ return new string(ret);
+ }
+
+ public double GetNamedSize(NamedSize size, Type targetElementType, bool useOldSizes)
+ {
+ // We make these up anyway, so new sizes didn't really change
+ // iOS docs say default button font size is 15, default label font size is 17 so we use those as the defaults.
+ switch (size)
+ {
+ case NamedSize.Default:
+ return typeof(Button).IsAssignableFrom(targetElementType) ? 15 : 17;
+ case NamedSize.Micro:
+ return 12;
+ case NamedSize.Small:
+ return 14;
+ case NamedSize.Medium:
+ return 17;
+ case NamedSize.Large:
+ return 22;
+ default:
+ throw new ArgumentOutOfRangeException("size");
+ }
+ }
+
+ public async Task<Stream> GetStreamAsync(Uri uri, CancellationToken cancellationToken)
+ {
+ using(var client = GetHttpClient())
+ using(var response = await client.GetAsync(uri, cancellationToken))
+ return await response.Content.ReadAsStreamAsync();
+ }
+
+ public IIsolatedStorageFile GetUserStoreForApplication()
+ {
+ return new _IsolatedStorageFile(IsolatedStorageFile.GetUserStoreForApplication());
+ }
+
+ public bool IsInvokeRequired
+ {
+ get { return !NSThread.IsMain; }
+ }
+
+ public void OpenUriAction(Uri uri)
+ {
+ UIApplication.SharedApplication.OpenUrl(new NSUrl(uri.AbsoluteUri));
+ }
+
+ public void StartTimer(TimeSpan interval, Func<bool> callback)
+ {
+ NSTimer timer = null;
+#if __UNIFIED__
+ timer = NSTimer.CreateRepeatingScheduledTimer(interval, t =>
+ {
+#else
+ timer = NSTimer.CreateRepeatingScheduledTimer (interval, () => {
+ #endif
+ if (!callback())
+#if __UNIFIED__
+ t.Invalidate();
+#else
+ timer.Invalidate ();
+ #endif
+ });
+ NSRunLoop.Main.AddTimer(timer, NSRunLoopMode.Common);
+ }
+
+ HttpClient GetHttpClient()
+ {
+ var proxy = CFNetwork.GetSystemProxySettings();
+ var handler = new HttpClientHandler();
+ if (!string.IsNullOrEmpty(proxy.HTTPProxy))
+ {
+ handler.Proxy = CFNetwork.GetDefaultProxy();
+ handler.UseProxy = true;
+ }
+ return new HttpClient(handler);
+ }
+
+ static int Hex(int v)
+ {
+ if (v < 10)
+ return '0' + v;
+ return 'a' + v - 10;
+ }
+
+ public class _Timer : ITimer
+ {
+ readonly Timer _timer;
+
+ public _Timer(Timer timer)
+ {
+ _timer = timer;
+ }
+
+ public void Change(int dueTime, int period)
+ {
+ _timer.Change(dueTime, period);
+ }
+
+ public void Change(long dueTime, long period)
+ {
+ _timer.Change(dueTime, period);
+ }
+
+ public void Change(TimeSpan dueTime, TimeSpan period)
+ {
+ _timer.Change(dueTime, period);
+ }
+
+ public void Change(uint dueTime, uint period)
+ {
+ _timer.Change(dueTime, period);
+ }
+ }
+
+ public class _IsolatedStorageFile : IIsolatedStorageFile
+ {
+ readonly IsolatedStorageFile _isolatedStorageFile;
+
+ public _IsolatedStorageFile(IsolatedStorageFile isolatedStorageFile)
+ {
+ _isolatedStorageFile = isolatedStorageFile;
+ }
+
+ public Task CreateDirectoryAsync(string path)
+ {
+ _isolatedStorageFile.CreateDirectory(path);
+ return Task.FromResult(true);
+ }
+
+ public Task<bool> GetDirectoryExistsAsync(string path)
+ {
+ return Task.FromResult(_isolatedStorageFile.DirectoryExists(path));
+ }
+
+ public Task<bool> GetFileExistsAsync(string path)
+ {
+ return Task.FromResult(_isolatedStorageFile.FileExists(path));
+ }
+
+ public Task<DateTimeOffset> GetLastWriteTimeAsync(string path)
+ {
+ return Task.FromResult(_isolatedStorageFile.GetLastWriteTime(path));
+ }
+
+ public Task<Stream> OpenFileAsync(string path, FileMode mode, FileAccess access)
+ {
+ Stream stream = _isolatedStorageFile.OpenFile(path, (System.IO.FileMode)mode, (System.IO.FileAccess)access);
+ return Task.FromResult(stream);
+ }
+
+ public Task<Stream> OpenFileAsync(string path, FileMode mode, FileAccess access, FileShare share)
+ {
+ Stream stream = _isolatedStorageFile.OpenFile(path, (System.IO.FileMode)mode, (System.IO.FileAccess)access, (System.IO.FileShare)share);
+ return Task.FromResult(stream);
+ }
+ }
+ }
+ }
+} \ No newline at end of file