diff --git a/src/App/Utilities/PushNotificationContants.cs b/src/App/Utilities/PushNotificationContants.cs deleted file mode 100644 index e1466d59d..000000000 --- a/src/App/Utilities/PushNotificationContants.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace Bit.App.Utilities -{ - public static class PushNotificationContants - { - /// - /// Type - /// - public const string Type = "type"; - /// - /// Error - /// - public const string Error = "error"; - /// - /// Domain Name - /// - public const string DomainName = "CrossPushNotification"; - /// - /// Title - /// - public const string Title = "title"; - /// - /// Text - /// - public const string Text = "text"; - /// - /// Subtitle - /// - public const string Subtitle = "subtitle"; - /// - /// Message - /// - public const string Message = "message"; - /// - /// Silent - /// - public const string Silent = "silent"; - /// - /// Alert - /// - public const string Alert = "alert"; - /// - /// Data - /// - public const string Data = "data"; - /// - /// Token - /// - public const string Token = "token"; - /// - /// App Version - /// - public const string AppVersion = "appVersion"; - /// - /// IntentFromGcmMessage - /// - public const string IntentFromGcmMessage = "com.google.android.c2dm.intent.RECEIVE"; - /// - /// BackOffMilliseconds - /// - public const string BackOffMilliseconds = "backoff_ms"; - /// - /// ErrorServiceNotAvailable - /// - public const string ErrorServiceNotAvailable = "SERVICE_NOT_AVAILABLE"; - /// - /// Tag - /// - public const string Tag = "tag"; - /// - /// Id - /// - public const string Id = "id"; - /// - /// RegistrationComplete - /// - public const string RegistrationComplete = "registrationComplete"; - } -} diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs index a89deb512..3a78bbb48 100644 --- a/src/iOS/AppDelegate.cs +++ b/src/iOS/AppDelegate.cs @@ -29,6 +29,7 @@ namespace Bit.iOS { private GaiCompletionHandler _dispatchHandler = null; private ILockService _lockService; + private iOSPushNotificationHandler _pushHandler = null; public ISettings Settings { get; set; } @@ -42,7 +43,9 @@ namespace Bit.iOS } _lockService = Resolver.Resolve(); + _pushHandler = new iOSPushNotificationHandler(Resolver.Resolve()); var appIdService = Resolver.Resolve(); + var crashManagerDelegate = new HockeyAppCrashManagerDelegate( appIdService, Resolver.Resolve()); var manager = BITHockeyManager.SharedHockeyManager; @@ -201,18 +204,12 @@ namespace Bit.iOS public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error) { - if(CrossPushNotification.Current is IPushNotificationHandler handler) - { - handler.OnErrorReceived(error); - } + _pushHandler?.OnErrorReceived(error); } public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { - if(CrossPushNotification.Current is IPushNotificationHandler handler) - { - handler.OnRegisteredSuccess(deviceToken); - } + _pushHandler?.OnRegisteredSuccess(deviceToken); } public override void DidRegisterUserNotificationSettings(UIApplication application, @@ -224,18 +221,12 @@ namespace Bit.iOS public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action completionHandler) { - if(CrossPushNotification.Current is IPushNotificationHandler handler) - { - handler.OnMessageReceived(userInfo); - } + _pushHandler?.OnMessageReceived(userInfo); } public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo) { - if(CrossPushNotification.Current is IPushNotificationHandler handler) - { - handler.OnMessageReceived(userInfo); - } + _pushHandler?.OnMessageReceived(userInfo); } private void SendResumedMessage() @@ -298,12 +289,10 @@ namespace Bit.iOS container.RegisterSingleton(Settings); // Push - var pushListener = new PushNotificationListener(); - container.RegisterSingleton(pushListener); - CrossPushNotification.Initialize(pushListener); - container.RegisterSingleton(CrossPushNotification.Current); - CachedImageRenderer.Init(); + container.RegisterSingleton(); + container.RegisterSingleton(); + CachedImageRenderer.Init(); Resolver.SetResolver(new SimpleInjectorResolver(container)); } diff --git a/src/iOS/Services/iOSPushNotificationHandler.cs b/src/iOS/Services/iOSPushNotificationHandler.cs new file mode 100644 index 000000000..b0a6abf66 --- /dev/null +++ b/src/iOS/Services/iOSPushNotificationHandler.cs @@ -0,0 +1,71 @@ +using Bit.App.Abstractions; +using Foundation; +using Newtonsoft.Json.Linq; +using System; +using System.Diagnostics; +using Xamarin.Forms; + +namespace Bit.iOS.Services +{ + public class iOSPushNotificationHandler + { + private const string TokenSetting = "token"; + private const string DomainName = "iOSPushNotificationService"; + + private readonly IPushNotificationListener _pushNotificationListener; + + public iOSPushNotificationHandler( + IPushNotificationListener pushNotificationListener) + { + _pushNotificationListener = pushNotificationListener; + } + + public void OnMessageReceived(NSDictionary userInfo) + { + var json = DictionaryToJson(userInfo); + var values = JObject.Parse(json); + + var keyAps = new NSString("aps"); + if(userInfo.ContainsKey(keyAps) && userInfo.ValueForKey(keyAps) is NSDictionary aps) + { + foreach(var apsKey in aps) + { + if(!values.TryGetValue(apsKey.Key.ToString(), out JToken temp)) + { + values.Add(apsKey.Key.ToString(), apsKey.Value.ToString()); + } + } + } + + _pushNotificationListener.OnMessage(values, Device.iOS); + } + + public void OnErrorReceived(NSError error) + { + Debug.WriteLine("{0} - Registration Failed.", DomainName); + _pushNotificationListener.OnError(error.LocalizedDescription, Device.iOS); + } + + public void OnRegisteredSuccess(NSData token) + { + Debug.WriteLine("{0} - Successfully Registered.", DomainName); + + var trimmedDeviceToken = token.Description; + if(!string.IsNullOrWhiteSpace(trimmedDeviceToken)) + { + trimmedDeviceToken = trimmedDeviceToken.Trim('<').Trim('>').Trim().Replace(" ", string.Empty); + } + + Console.WriteLine("{0} - Token: {1}", DomainName, trimmedDeviceToken); + _pushNotificationListener.OnRegistered(trimmedDeviceToken, Device.iOS); + NSUserDefaults.StandardUserDefaults.SetString(trimmedDeviceToken, TokenSetting); + NSUserDefaults.StandardUserDefaults.Synchronize(); + } + + private static string DictionaryToJson(NSDictionary dictionary) + { + var json = NSJsonSerialization.Serialize(dictionary, NSJsonWritingOptions.PrettyPrinted, out NSError error); + return json.ToString(NSStringEncoding.UTF8); + } + } +} diff --git a/src/iOS/Services/iOSPushNotificationService.cs b/src/iOS/Services/iOSPushNotificationService.cs index 6afaeff0c..2d2fb0d1e 100644 --- a/src/iOS/Services/iOSPushNotificationService.cs +++ b/src/iOS/Services/iOSPushNotificationService.cs @@ -1,20 +1,23 @@ using Bit.App.Abstractions; -using Bit.App.Utilities; using Foundation; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; using UIKit; -using UserNotifications; using Xamarin.Forms; namespace Bit.iOS.Services { - public class iOSPushNotificationService : IPushNotificationService, IPushNotificationHandler + public class iOSPushNotificationService : IPushNotificationService { - public string Token => NSUserDefaults.StandardUserDefaults.StringForKey(PushNotificationContants.Token); + private const string TokenSetting = "token"; + + private readonly IPushNotificationListener _pushNotificationListener; + + public iOSPushNotificationService( + IPushNotificationListener pushNotificationListener) + { + _pushNotificationListener = pushNotificationListener; + } + + public string Token => NSUserDefaults.StandardUserDefaults.StringForKey(TokenSetting); public void Register() { @@ -27,127 +30,9 @@ namespace Bit.iOS.Services public void Unregister() { UIApplication.SharedApplication.UnregisterForRemoteNotifications(); - OnUnregisteredSuccess(); - } - - private static string DictionaryToJson(NSDictionary dictionary) - { - NSError error; - var json = NSJsonSerialization.Serialize(dictionary, NSJsonWritingOptions.PrettyPrinted, out error); - return json.ToString(NSStringEncoding.UTF8); - } - - public void OnMessageReceived(NSDictionary userInfo) - { - var parameters = new Dictionary(); - var json = DictionaryToJson(userInfo); - var values = JObject.Parse(json); - - var keyAps = new NSString("aps"); - if(userInfo.ContainsKey(keyAps)) - { - var aps = userInfo.ValueForKey(keyAps) as NSDictionary; - if(aps != null) - { - foreach(var apsKey in aps) - { - parameters.Add(apsKey.Key.ToString(), apsKey.Value); - JToken temp; - if(!values.TryGetValue(apsKey.Key.ToString(), out temp)) - { - values.Add(apsKey.Key.ToString(), apsKey.Value.ToString()); - } - } - } - } - - CrossPushNotification.PushNotificationListener.OnMessage(values, Device.iOS); - } - - public void OnErrorReceived(NSError error) - { - Debug.WriteLine("{0} - Registration Failed.", PushNotificationContants.DomainName); - CrossPushNotification.PushNotificationListener.OnError(error.LocalizedDescription, Device.iOS); - } - - public void OnRegisteredSuccess(NSData token) - { - Debug.WriteLine("{0} - Succesfully Registered.", PushNotificationContants.DomainName); - - var trimmedDeviceToken = token.Description; - if(!string.IsNullOrWhiteSpace(trimmedDeviceToken)) - { - trimmedDeviceToken = trimmedDeviceToken.Trim('<'); - trimmedDeviceToken = trimmedDeviceToken.Trim('>'); - trimmedDeviceToken = trimmedDeviceToken.Trim(); - trimmedDeviceToken = trimmedDeviceToken.Replace(" ", ""); - } - - Console.WriteLine("{0} - Token: {1}", PushNotificationContants.DomainName, trimmedDeviceToken); - CrossPushNotification.PushNotificationListener.OnRegistered(trimmedDeviceToken, Device.iOS); - NSUserDefaults.StandardUserDefaults.SetString(trimmedDeviceToken, PushNotificationContants.Token); + _pushNotificationListener.OnUnregistered(Device.iOS); + NSUserDefaults.StandardUserDefaults.SetString(string.Empty, TokenSetting); NSUserDefaults.StandardUserDefaults.Synchronize(); } - - public void OnUnregisteredSuccess() - { - CrossPushNotification.PushNotificationListener.OnUnregistered(Device.iOS); - NSUserDefaults.StandardUserDefaults.SetString(string.Empty, PushNotificationContants.Token); - NSUserDefaults.StandardUserDefaults.Synchronize(); - } - } - - public interface IPushNotificationHandler - { - void OnMessageReceived(NSDictionary parameters); - void OnErrorReceived(NSError error); - void OnRegisteredSuccess(NSData token); - void OnUnregisteredSuccess(); - } - - internal class CrossPushNotification - { - private static Lazy Implementation = new Lazy( - () => new iOSPushNotificationService(), - LazyThreadSafetyMode.PublicationOnly); - public static bool IsInitialized => PushNotificationListener != null; - public static IPushNotificationListener PushNotificationListener { get; private set; } - - public static void Initialize(T listener) where T : IPushNotificationListener - { - if(PushNotificationListener == null) - { - PushNotificationListener = listener; - Debug.WriteLine("PushNotification plugin initialized."); - } - else - { - Debug.WriteLine("PushNotification plugin already initialized."); - } - } - - public static void Initialize() where T : IPushNotificationListener, new() - { - Initialize(new T()); - } - - public static IPushNotificationService Current - { - get - { - if(!IsInitialized) - { - throw new Exception("Not initialized."); - } - - var ret = Implementation.Value; - if(ret == null) - { - throw new Exception("Not in PCL"); - } - - return ret; - } - } } } diff --git a/src/iOS/iOS.csproj b/src/iOS/iOS.csproj index f3e61ad9f..2d3e70ea8 100644 --- a/src/iOS/iOS.csproj +++ b/src/iOS/iOS.csproj @@ -236,6 +236,7 @@ +