summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.iOS/FormsApplicationDelegate.cs
blob: 78dc6dca871d02f90a5fbca7e7db536a0ceb25ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
#if __UNIFIED__
using Foundation;
using UIKit;
using CoreSpotlight;

#else
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using MonoTouch.CoreSpotlight;
#endif

namespace Xamarin.Forms.Platform.iOS
{
	public class FormsApplicationDelegate : UIApplicationDelegate
	{
		Application _application;
		bool _isSuspended;
		UIWindow _window;

		protected FormsApplicationDelegate()
		{
		}

		public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
		{
			CheckForAppLink(userActivity);
			return true;
		}

		// now in background
		public override void DidEnterBackground(UIApplication uiApplication)
		{
			// applicationDidEnterBackground
		}

		// finish initialization before display to user
		public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
		{
			// check contents of launch options and evaluate why the app was launched and respond
			// initialize the important data structures
			// prepare you apps window and views for display
			// keep lightweight, anything long winded should be executed asynchronously on a secondary thread.
			// application:didFinishLaunchingWithOptions
			_window = new UIWindow(UIScreen.MainScreen.Bounds);

			if (_application == null)
				throw new InvalidOperationException("You MUST invoke LoadApplication () before calling base.FinishedLaunching ()");

			SetMainPage();
			_application.SendStart();
			return true;
		}

		// about to become foreground, last minute preparatuin
		public override void OnActivated(UIApplication uiApplication)
		{
			// applicationDidBecomeActive
			// execute any OpenGL ES drawing calls
			if (_application != null && _isSuspended)
			{
				_isSuspended = false;
				_application.SendResume();
			}
		}

		// transitioning to background
		public override async void OnResignActivation(UIApplication uiApplication)
		{
			// applicationWillResignActive
			if (_application != null)
			{
				_isSuspended = true;
				await _application.SendSleepAsync();
			}
		}

		public override void UserActivityUpdated(UIApplication application, NSUserActivity userActivity)
		{
			CheckForAppLink(userActivity);
		}

		// from background to foreground, not yet active
		public override void WillEnterForeground(UIApplication uiApplication)
		{
			// applicationWillEnterForeground
		}

		// TODO where to execute heavy code, storing state, sending to server, etc 

		// first chance to execute code at launch time
		public override bool WillFinishLaunching(UIApplication uiApplication, NSDictionary launchOptions)
		{
			// check contents of launch options and evaluate why the app was launched and respond
			// initialize the important data structures
			// prepare you apps window and views for display
			// keep lightweight, anything long winded should be executed asynchronously on a secondary thread.
			// application:willFinishLaunchingWithOptions
			// Restore ui state here
			return true;
		}

		// app is being terminated, not called if you app is suspended
		public override void WillTerminate(UIApplication uiApplication)
		{
			// applicationWillTerminate
			//application.SendTerminate ();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && _application != null)
				_application.PropertyChanged -= ApplicationOnPropertyChanged;

			base.Dispose(disposing);
		}

		protected void LoadApplication(Application application)
		{
			if (application == null)
				throw new ArgumentNullException("application");

			Application.Current = application;
			_application = application;
			(application as IApplicationController)?.SetAppIndexingProvider(new IOSAppIndexingProvider());

			application.PropertyChanged += ApplicationOnPropertyChanged;
		}

		void ApplicationOnPropertyChanged(object sender, PropertyChangedEventArgs args)
		{
			if (args.PropertyName == "MainPage")
				UpdateMainPage();
		}

		void CheckForAppLink(NSUserActivity userActivity)
		{
			var strLink = string.Empty;

			switch (userActivity.ActivityType)
			{
				case "NSUserActivityTypeBrowsingWeb":
					strLink = userActivity.WebPageUrl.AbsoluteString;
					break;
				case "com.apple.corespotlightitem":
					if (userActivity.UserInfo.ContainsKey(CSSearchableItem.ActivityIdentifier))
						strLink = userActivity.UserInfo.ObjectForKey(CSSearchableItem.ActivityIdentifier).ToString();
					break;
				default:
					if (userActivity.UserInfo.ContainsKey(new NSString("link")))
						strLink = userActivity.UserInfo[new NSString("link")].ToString();
					break;
			}

			if (!string.IsNullOrEmpty(strLink))
				_application.SendOnAppLinkRequestReceived(new Uri(strLink));
		}

		void SetMainPage()
		{
			UpdateMainPage();
			_window.MakeKeyAndVisible();
		}

		void UpdateMainPage()
		{
			if (_application.MainPage == null)
				return;

			var platformRenderer = (PlatformRenderer)_window.RootViewController;
			_window.RootViewController = _application.MainPage.CreateViewController();
			if (platformRenderer != null)
				((IDisposable)platformRenderer.Platform).Dispose();
		}
	}
}