/// <summary> /// Processes the local notification. /// </summary> /// <param name="application">Application.</param> /// <param name="localNotification">Local notification.</param> private void ProcessLocalNotification(UIApplicationState applicationState, UILocalNotification localNotification) { if (localNotification != null) { #if DEBUG log("******* Local NOTIFICATION received"); #endif if (applicationState == UIApplicationState.Active) { // we need to manually process the notification while application is running. #if DEBUG log("******* Application is running, manually showing notification"); #endif this.UpdateApplicationIconBadgeNumber((int)localNotification.ApplicationIconBadgeNumber); this.PlayNotificationSound(localNotification.SoundName); this.ShowNotificationAlert("Notification", localNotification.AlertBody); } NotificationData notificationData = new NotificationData(); notificationData.AlertMessage = localNotification.AlertBody; notificationData.Badge = (int)localNotification.ApplicationIconBadgeNumber; notificationData.Sound = localNotification.SoundName; if (localNotification.UserInfo != null) { Dictionary <String, Object> customDic = IPhoneUtils.GetInstance().ConvertToDictionary(new NSMutableDictionary(localNotification.UserInfo)); notificationData.CustomDataJsonString = IPhoneUtils.GetInstance().JSONSerialize(customDic); } IPhoneUtils.GetInstance().FireUnityJavascriptEvent("Appverse.OnLocalNotificationReceived", notificationData); } }
/// Available in iOS 6.0 and later. public override bool ShouldAutorotate() { bool shouldAutorotate = IPhoneUtils.GetInstance().ShouldAutorotate(); if (!shouldAutorotate) { log(" ** Autorotation blocked by application at runtime. "); } log("ShouldAutorotate? " + shouldAutorotate); if (shouldAutorotate) { if (this.splashscreenShownOnStartupTime) { UIInterfaceOrientation currentOrientation = UIApplication.SharedApplication.StatusBarOrientation; if (this.splashView != null) { log("Adjusting splashscreen to current orientation: " + currentOrientation); this.splashView.SetSplashViewForOrientation(currentOrientation); } } } return(shouldAutorotate); }
/// <summary> /// Processes the launch data received when launched externally (using custom scheme url). /// </summary> public void processLaunchData() { #if DEBUG log("************** Checking launch data... should handle open url? : " + handledOpenUrl + ", launchedData?: " + launchData); #endif if (handledOpenUrl && launchData != null && launchData.Count > 0) { IPhoneUtils.GetInstance().FireUnityJavascriptEvent("Appverse.OnExternallyLaunched", launchData); handledOpenUrl = false; launchData = null; } }
/// <summary> /// Failure when trying to register for remote notifications. /// </summary> /// <param name="application">Application.</param> /// <param name="error">Error.</param> public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { //Registering for remote notifications failed for some reason //This is usually due to your provisioning profiles not being properly setup in your project options // or not having the right mobileprovision included on your device // or you may not have setup your app's product id to match the mobileprovision you made #if DEBUG log("Failed to Register for Remote Notifications: " + error.LocalizedDescription); #endif RegistrationError registrationError = new RegistrationError(); registrationError.Code = "" + error.Code; registrationError.LocalizedDescription = error.LocalizedDescription; IPhoneUtils.GetInstance().FireUnityJavascriptEvent("Unity.OnRegisterForRemoteNotificationsFailure", registrationError); }
/// DEPRECATED for iOS 6 and later, but needed for iOS 5 and earlier to support additional orientations public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation) { bool shouldAutorotate = IPhoneUtils.GetInstance().ShouldAutorotate(); if (shouldAutorotate) { // Check supported orientations if (supportedOrientations != null) { bool orientationSupported = false; for (uint index = 0; index < supportedOrientations.Count; index++) { NSString mySupportedOrientation = new NSString(supportedOrientations.GetItem <NSString> (index)); if (("UIInterfaceOrientation" + toInterfaceOrientation.ToString()) == mySupportedOrientation.ToString()) { orientationSupported = true; break; } } shouldAutorotate = orientationSupported; } else { log("Supported orientations not configured. All orientations are supported by default"); } } else { log(" ** Autorotation blocked by application at runtime. "); } log("Should Autorotate to " + toInterfaceOrientation.ToString() + "? " + shouldAutorotate); if (shouldAutorotate) { this.ShowSplashScreenOnStartupTime(toInterfaceOrientation); } return(shouldAutorotate); }
public override void loadWebView(string urlPath) { log("UnityUI_iOSViewController_WKWebView loading web view contents"); NSUrl url = new NSUrl(urlPath); //NSUrlRequest request = new NSUrlRequest(url, NSUrlRequestCachePolicy.ReturnCacheDataElseLoad, 3600.0); // FIX (16-09-2013) - testing iOS 7 apps; resources are not refreshed when installing a new app version on the top of a previous one // We need to remove the cache data loaded NSUrlRequest request = new NSUrlRequest(url, NSUrlRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData, 3600.0); if (this.webView != null) { if (urlPath.StartsWith("file://")) { log("UnityUI_iOSViewController_WKWebView loading local error pages as HTML string"); string basePath = IPhoneUtils.GetInstance().GetDefaultBasePath(); urlPath = urlPath.Substring(("file://" + basePath + "/").Length); //log ("UnityUI_iOSViewController_WKWebView local url path: " + urlPath); string htmlErrorPageFile = IPhoneUtils.GetInstance().GetFileFullPath(urlPath); byte[] htmlErrorPageBytes = IPhoneUtils.GetInstance().GetResourceAsBinary(htmlErrorPageFile, true); NSData htmlErrorPageData = NSData.FromArray(htmlErrorPageBytes); NSString htmlErrorPageString = new NSString(htmlErrorPageData, NSStringEncoding.UTF8); this.webView.LoadHtmlString(htmlErrorPageString, new NSUrl("/")); } else { this.webView.LoadRequest(request); } } else { log("WebView is null."); } }
/// <summary> /// Succcessful registration for remote notifications. /// </summary> /// <param name="application">Application.</param> /// <param name="deviceToken">Device token.</param> public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { // The deviceToken is what the push notification server needs to send out a notification // to the device. Most times application needs to send the device Token to its servers when it has changed #if DEBUG log("Success registering for Remote Notifications"); #endif // ****** REMOVED "lastDeviceToken storage" feature. Marga 06/08/2013 . Platform will always call the JS listener; same behavior in all platforms ****** // First, get the last device token we know of // string lastDeviceToken = NSUserDefaults.StandardUserDefaults.StringForKey("deviceToken"); //There's probably a better way to do this NSString strFormat = new NSString("%@"); NSString newToken = new NSString(MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend_IntPtr_IntPtr(new MonoTouch.ObjCRuntime.Class("NSString").Handle, new MonoTouch.ObjCRuntime.Selector("stringWithFormat:").Handle, strFormat.Handle, deviceToken.Handle)); var newDeviceToken = newToken.ToString().Replace("<", "").Replace(">", "").Replace(" ", ""); #if DEBUG log("Device token: " + newDeviceToken); #endif // We only want to send the device token to the server if it hasn't changed since last time // no need to incur extra bandwidth by sending the device token every time // if (!newDeviceToken.Equals(lastDeviceToken)) //{ // Send the new device token to your application server // ****** REMOVED "lastDeviceToken storage" feature. Marga 06/08/2013 . Platform will always call the JS listener; same behavior in all platforms ****** RegitrationToken registrationToken = new RegitrationToken(); registrationToken.StringRepresentation = newDeviceToken; byte[] buffer = new byte[deviceToken.Length]; Marshal.Copy(deviceToken.Bytes, buffer, 0, buffer.Length); registrationToken.Binary = buffer; IPhoneUtils.GetInstance().FireUnityJavascriptEvent("Unity.OnRegisterForRemoteNotificationsSuccess", registrationToken); //Save the new device token for next application launch // NSUserDefaults.StandardUserDefaults.SetString(newDeviceToken, "deviceToken"); //} }
private bool performSecurityChecks() { if (securityChecksPerfomed) { #if DEBUG log("security checks already performed"); #endif return(securityChecksPassed); // if security checks already performed, return } #if DEBUG log("performing security checks..."); #endif // initialize variable securityChecksPassed = false; if (blockRooted) { #if DEBUG log("Checking device jailbroken (this app is not allowed to run in those devices)... "); #endif ISecurity securityService = (ISecurity)IPhoneServiceLocator.GetInstance().GetService("security"); bool IsDeviceModified = securityService.IsDeviceModified(); if (IsDeviceModified) { #if DEBUG log("Device is jailbroken. Application is blocked as per build configuration demand"); #endif UIApplication.SharedApplication.InvokeOnMainThread(delegate { #if DEBUG log("Loading error page..."); #endif try { // loading error page from file system string basePath = IPhoneUtils.GetInstance().GetDefaultBasePath(); string htmlErrorPageFile = "file://" + basePath + DEFAULT_LOCKED_HTML; MainViewController().loadWebView(htmlErrorPageFile); } catch (Exception ex) { #if DEBUG log("Unable to load error page on Appverse WebView. Exception message: " + ex.Message); #endif } }); this.DismissSplashScreen(); } else { securityChecksPassed = true; #if DEBUG log("Device is NOT jailbroken."); #endif } } else { securityChecksPassed = true; #if DEBUG log("This app could be used in jailbroken devices"); #endif } securityChecksPerfomed = true; return(securityChecksPassed); }
/// <summary> /// Initializes the appverse context exposing data to the WebView Javascript DOM. /// </summary> private void InitializeAppverseContext() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); try { #if DEBUG log("Before loading the main HTML, platform will expose some information directly to javascript..."); #endif IPhoneSystem systemService = (IPhoneSystem)IPhoneServiceLocator.GetInstance().GetService("system"); AbstractI18N i18nService = (AbstractI18N)IPhoneServiceLocator.GetInstance().GetService("i18n"); IIo ioService = (IIo)IPhoneServiceLocator.GetInstance().GetService("io"); // 1. Appverse Context (Appverse.is) UnityContext unityContext = systemService.GetUnityContext(); String unityContextJsonString = IPhoneUtils.GetInstance().JSONSerializeObjectData(unityContext); unityContextJsonString = "_AppverseContext = " + unityContextJsonString; this.EvaluateJavascript(unityContextJsonString); // 2. OS Info (Appverse.OSInfo) OSInfo osInfo = systemService.GetOSInfo(); String osInfoJsonString = IPhoneUtils.GetInstance().JSONSerializeObjectData(osInfo); osInfoJsonString = "_OSInfo = " + osInfoJsonString; this.EvaluateJavascript(osInfoJsonString); // 3. Hardware Info (Appverse.HardwareInfo) HardwareInfo hwInfo = systemService.GetOSHardwareInfo(); String hwInfoJsonString = IPhoneUtils.GetInstance().JSONSerializeObjectData(hwInfo); hwInfoJsonString = "_HwInfo = " + hwInfoJsonString; this.EvaluateJavascript(hwInfoJsonString); // 4. Get all configured localized keys (Appverse.i18n) Unity.Core.I18N.Locale[] supportedLocales = i18nService.GetLocaleSupported(); String localizedStrings = "_i18n = {}; _i18n['default'] = '" + i18nService.DefaultLocale + "'; "; String localeLiterals = ""; foreach (Unity.Core.I18N.Locale supportedLocale in supportedLocales) { ResourceLiteralDictionary literals = i18nService.GetResourceLiterals(supportedLocale); String literalsJsonString = IPhoneUtils.GetInstance().JSONSerializeObjectData(literals); localeLiterals = localeLiterals + " _i18n['" + supportedLocale.ToString() + "'] = " + literalsJsonString + "; "; } localizedStrings = localizedStrings + localeLiterals; this.EvaluateJavascript(localizedStrings); // 5. Current device locale Unity.Core.System.Locale currentLocale = systemService.GetLocaleCurrent(); String currentLocaleJsonString = IPhoneUtils.GetInstance().JSONSerializeObjectData(currentLocale); currentLocaleJsonString = "_CurrentDeviceLocale = " + currentLocaleJsonString; this.EvaluateJavascript(currentLocaleJsonString); // 6. Configured IO services endpoints IOService[] services = ioService.GetServices(); String servicesJsonString = "_IOServices = {}; "; foreach (IOService service in services) { String serviceJson = IPhoneUtils.GetInstance().JSONSerializeObjectData(service); servicesJsonString = servicesJsonString + " _IOServices['" + service.Name + "-" + IPhoneUtils.GetInstance().JSONSerializeObjectData(service.Type) + "'] = " + serviceJson + "; "; } this.EvaluateJavascript(servicesJsonString); IPhoneNet NetService = (IPhoneNet)IPhoneServiceLocator.GetInstance().GetService("net"); NetService.CheckConnectivity(); String netJsonString = "_NetworkStatus = " + NetService.getNetStatus(); this.EvaluateJavascript(netJsonString); } catch (Exception ex) { #if DEBUG log("Unable to load Appverse Context. Exception message: " + ex.Message); #endif } stopwatch.Stop(); #if DEBUG log("# Time elapsed initializing Appverse Context: " + stopwatch.Elapsed); #endif }
private bool performSecurityChecks() { if (securityChecksPerfomed) { #if DEBUG log("security checks already performed"); #endif return(securityChecksPassed); // if security checks already performed, return } #if DEBUG log("performing security checks..."); #endif // initialize variable securityChecksPassed = false; if (blockRooted) { #if DEBUG log("Checking device jailbroken (this app is not allowed to run in those devices)... "); #endif ISecurity securityService = (ISecurity)IPhoneServiceLocator.GetInstance().GetService("security"); bool IsDeviceModified = securityService.IsDeviceModified(); if (IsDeviceModified) { #if DEBUG log("Device is jailbroken. Application is blocked as per build configuration demand"); #endif UIApplication.SharedApplication.InvokeOnMainThread(delegate { #if DEBUG log("Loading error page..."); #endif try { string htmlErrorPageFile = IPhoneUtils.GetInstance().GetFileFullPath(DEFAULT_LOCKED_HTML); byte[] htmlErrorPageBytes = IPhoneUtils.GetInstance().GetResourceAsBinary(htmlErrorPageFile, true); NSData htmlErrorPageData = NSData.FromArray(htmlErrorPageBytes); string mimeType = "text/html"; string textEncodingName = "UTF-8"; MainViewController().loadWebViewData(htmlErrorPageData, mimeType, textEncodingName, new NSUrl("/")); } catch (Exception ex) { #if DEBUG log("Unable to load error page on Appverse WebView. Exception message: " + ex.Message); #endif } }); this.DismissSplashScreen(); } else { securityChecksPassed = true; #if DEBUG log("Device is NOT jailbroken."); #endif } } else { securityChecksPassed = true; #if DEBUG log("This app could be used in jailbroken devices"); #endif } securityChecksPerfomed = true; return(securityChecksPassed); }
private void ProcessRemoteNotification(NSDictionary options, bool fromFinishedLaunching, UIApplicationState applicationState) { //Check to see if the dictionary has the aps key. This is the notification payload you would have sent if (options != null && options.ContainsKey(new NSString("aps"))) { #if DEBUG log(" ******* PROCESSING REMOTE NOTIFICATION Notification Payload received"); #endif NotificationData notificationData = new NotificationData(); string alert = string.Empty; string sound = string.Empty; int badge = -1; try { //Get the aps dictionary NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary; //Extract the alert text //NOTE: Just for the simple alert specified by " aps:{alert:"alert msg here"} " // For complex alert with Localization keys, etc., the "alert" object from the aps dictionary // will be another NSDictionary... Basically the json gets dumped right into a NSDictionary, so keep that in mind if (aps.ContainsKey(new NSString("alert"))) { string alertType = "undefined"; if (aps[new NSString("alert")].GetType() == typeof(NSString)) { alert = (aps [new NSString("alert")] as NSString).ToString(); alertType = "NSString"; } else if (aps [new NSString("alert")].GetType() == typeof(NSDictionary)) { NSDictionary alertNSDictionary = aps.ObjectForKey(new NSString("alert")) as NSDictionary; alertType = "NSDictionary"; // We only get "body" key from that dictionary if (alertNSDictionary.ContainsKey(new NSString("body")) && (alertNSDictionary[new NSString("body")].GetType() == typeof(NSString))) { alert = (alertNSDictionary [new NSString("body")] as NSString).ToString(); } } #if DEBUG log("******* PROCESSING NOTIFICATION Notification Payload contains an alert message. Type [" + alertType + "]"); #endif } //Extract the sound string if (aps.ContainsKey(new NSString("sound")) && (aps [new NSString("sound")].GetType() == typeof(NSString))) { sound = (aps [new NSString("sound")] as NSString).ToString(); #if DEBUG log("******* PROCESSING NOTIFICATION Notification Payload contains sound"); #endif } //Extract the badge if (aps.ContainsKey(new NSString("badge")) && (aps [new NSString("badge")].GetType() == typeof(NSObject))) { string badgeStr = (aps [new NSString("badge")] as NSObject).ToString(); int.TryParse(badgeStr, out badge); #if DEBUG log("******* PROCESSING NOTIFICATION Notification Payload contains a badge number: " + badge); #endif } //If this came from the ReceivedRemoteNotification while the app was running, // we of course need to manually process things like the sound, badge, and alert. if (!fromFinishedLaunching && applicationState == UIApplicationState.Active) { #if DEBUG log("******* PROCESSING NOTIFICATION app was running, so manually showing notification"); #endif UIRemoteNotificationType enabledRemoteNotificationTypes = UIApplication.SharedApplication.EnabledRemoteNotificationTypes; bool alertEnabled = ((enabledRemoteNotificationTypes & UIRemoteNotificationType.Alert) == UIRemoteNotificationType.Alert); bool soundEnabled = ((enabledRemoteNotificationTypes & UIRemoteNotificationType.Sound) == UIRemoteNotificationType.Sound); bool badgeEnabled = ((enabledRemoteNotificationTypes & UIRemoteNotificationType.Badge) == UIRemoteNotificationType.Badge); #if DEBUG log("******* PROCESSING NOTIFICATION types enabled: alert[" + alertEnabled + "], sound[" + soundEnabled + "], badge[" + badgeEnabled + "]"); #endif //Manually set the badge in case this came from a remote notification sent while the app was open if (badgeEnabled) { this.UpdateApplicationIconBadgeNumber(badge); } //Manually play the sound if (soundEnabled) { this.PlayNotificationSound(sound); } //Manually show an alert if (alertEnabled) { this.ShowNotificationAlert("Notification", alert); } } Dictionary <String, Object> customDic = IPhoneUtils.GetInstance().ConvertToDictionary(new NSMutableDictionary(options)); customDic.Remove("aps"); // it is not needed to pass the "aps" (notification iOS data) inside the "custom data json string" notificationData.CustomDataJsonString = IPhoneUtils.GetInstance().JSONSerialize(customDic); } catch (System.Exception ex) { #if DEBUG log(" ******* Unhanlded exception processing notification payload received. Exception message: " + ex.Message); #endif } finally { notificationData.AlertMessage = alert; notificationData.Badge = badge; notificationData.Sound = sound; IPhoneUtils.GetInstance().FireUnityJavascriptEvent("Unity.OnRemoteNotificationReceived", notificationData); } } else { #if DEBUG log(" ******* NO Notification Payload received"); #endif } }