mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 18:08:26 +03:00
cleanup and simplify ios push reg/handling
This commit is contained in:
parent
fb76ecf198
commit
bcf49ab396
5 changed files with 96 additions and 228 deletions
|
@ -1,78 +0,0 @@
|
||||||
namespace Bit.App.Utilities
|
|
||||||
{
|
|
||||||
public static class PushNotificationContants
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Type
|
|
||||||
/// </summary>
|
|
||||||
public const string Type = "type";
|
|
||||||
/// <summary>
|
|
||||||
/// Error
|
|
||||||
/// </summary>
|
|
||||||
public const string Error = "error";
|
|
||||||
/// <summary>
|
|
||||||
/// Domain Name
|
|
||||||
/// </summary>
|
|
||||||
public const string DomainName = "CrossPushNotification";
|
|
||||||
/// <summary>
|
|
||||||
/// Title
|
|
||||||
/// </summary>
|
|
||||||
public const string Title = "title";
|
|
||||||
/// <summary>
|
|
||||||
/// Text
|
|
||||||
/// </summary>
|
|
||||||
public const string Text = "text";
|
|
||||||
/// <summary>
|
|
||||||
/// Subtitle
|
|
||||||
/// </summary>
|
|
||||||
public const string Subtitle = "subtitle";
|
|
||||||
/// <summary>
|
|
||||||
/// Message
|
|
||||||
/// </summary>
|
|
||||||
public const string Message = "message";
|
|
||||||
/// <summary>
|
|
||||||
/// Silent
|
|
||||||
/// </summary>
|
|
||||||
public const string Silent = "silent";
|
|
||||||
/// <summary>
|
|
||||||
/// Alert
|
|
||||||
/// </summary>
|
|
||||||
public const string Alert = "alert";
|
|
||||||
/// <summary>
|
|
||||||
/// Data
|
|
||||||
/// </summary>
|
|
||||||
public const string Data = "data";
|
|
||||||
/// <summary>
|
|
||||||
/// Token
|
|
||||||
/// </summary>
|
|
||||||
public const string Token = "token";
|
|
||||||
/// <summary>
|
|
||||||
/// App Version
|
|
||||||
/// </summary>
|
|
||||||
public const string AppVersion = "appVersion";
|
|
||||||
/// <summary>
|
|
||||||
/// IntentFromGcmMessage
|
|
||||||
/// </summary>
|
|
||||||
public const string IntentFromGcmMessage = "com.google.android.c2dm.intent.RECEIVE";
|
|
||||||
/// <summary>
|
|
||||||
/// BackOffMilliseconds
|
|
||||||
/// </summary>
|
|
||||||
public const string BackOffMilliseconds = "backoff_ms";
|
|
||||||
/// <summary>
|
|
||||||
/// ErrorServiceNotAvailable
|
|
||||||
/// </summary>
|
|
||||||
public const string ErrorServiceNotAvailable = "SERVICE_NOT_AVAILABLE";
|
|
||||||
/// <summary>
|
|
||||||
/// Tag
|
|
||||||
/// </summary>
|
|
||||||
public const string Tag = "tag";
|
|
||||||
/// <summary>
|
|
||||||
/// Id
|
|
||||||
/// </summary>
|
|
||||||
public const string Id = "id";
|
|
||||||
/// <summary>
|
|
||||||
/// RegistrationComplete
|
|
||||||
/// </summary>
|
|
||||||
public const string RegistrationComplete = "registrationComplete";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,6 +29,7 @@ namespace Bit.iOS
|
||||||
{
|
{
|
||||||
private GaiCompletionHandler _dispatchHandler = null;
|
private GaiCompletionHandler _dispatchHandler = null;
|
||||||
private ILockService _lockService;
|
private ILockService _lockService;
|
||||||
|
private iOSPushNotificationHandler _pushHandler = null;
|
||||||
|
|
||||||
public ISettings Settings { get; set; }
|
public ISettings Settings { get; set; }
|
||||||
|
|
||||||
|
@ -42,7 +43,9 @@ namespace Bit.iOS
|
||||||
}
|
}
|
||||||
|
|
||||||
_lockService = Resolver.Resolve<ILockService>();
|
_lockService = Resolver.Resolve<ILockService>();
|
||||||
|
_pushHandler = new iOSPushNotificationHandler(Resolver.Resolve<IPushNotificationListener>());
|
||||||
var appIdService = Resolver.Resolve<IAppIdService>();
|
var appIdService = Resolver.Resolve<IAppIdService>();
|
||||||
|
|
||||||
var crashManagerDelegate = new HockeyAppCrashManagerDelegate(
|
var crashManagerDelegate = new HockeyAppCrashManagerDelegate(
|
||||||
appIdService, Resolver.Resolve<IAuthService>());
|
appIdService, Resolver.Resolve<IAuthService>());
|
||||||
var manager = BITHockeyManager.SharedHockeyManager;
|
var manager = BITHockeyManager.SharedHockeyManager;
|
||||||
|
@ -201,18 +204,12 @@ namespace Bit.iOS
|
||||||
|
|
||||||
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
|
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
|
||||||
{
|
{
|
||||||
if(CrossPushNotification.Current is IPushNotificationHandler handler)
|
_pushHandler?.OnErrorReceived(error);
|
||||||
{
|
|
||||||
handler.OnErrorReceived(error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
|
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
|
||||||
{
|
{
|
||||||
if(CrossPushNotification.Current is IPushNotificationHandler handler)
|
_pushHandler?.OnRegisteredSuccess(deviceToken);
|
||||||
{
|
|
||||||
handler.OnRegisteredSuccess(deviceToken);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DidRegisterUserNotificationSettings(UIApplication application,
|
public override void DidRegisterUserNotificationSettings(UIApplication application,
|
||||||
|
@ -224,18 +221,12 @@ namespace Bit.iOS
|
||||||
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo,
|
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo,
|
||||||
Action<UIBackgroundFetchResult> completionHandler)
|
Action<UIBackgroundFetchResult> completionHandler)
|
||||||
{
|
{
|
||||||
if(CrossPushNotification.Current is IPushNotificationHandler handler)
|
_pushHandler?.OnMessageReceived(userInfo);
|
||||||
{
|
|
||||||
handler.OnMessageReceived(userInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
|
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
|
||||||
{
|
{
|
||||||
if(CrossPushNotification.Current is IPushNotificationHandler handler)
|
_pushHandler?.OnMessageReceived(userInfo);
|
||||||
{
|
|
||||||
handler.OnMessageReceived(userInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendResumedMessage()
|
private void SendResumedMessage()
|
||||||
|
@ -298,12 +289,10 @@ namespace Bit.iOS
|
||||||
container.RegisterSingleton(Settings);
|
container.RegisterSingleton(Settings);
|
||||||
|
|
||||||
// Push
|
// Push
|
||||||
var pushListener = new PushNotificationListener();
|
container.RegisterSingleton<IPushNotificationListener, PushNotificationListener>();
|
||||||
container.RegisterSingleton<IPushNotificationListener>(pushListener);
|
container.RegisterSingleton<IPushNotificationService, iOSPushNotificationService>();
|
||||||
CrossPushNotification.Initialize(pushListener);
|
|
||||||
container.RegisterSingleton(CrossPushNotification.Current);
|
|
||||||
CachedImageRenderer.Init();
|
|
||||||
|
|
||||||
|
CachedImageRenderer.Init();
|
||||||
Resolver.SetResolver(new SimpleInjectorResolver(container));
|
Resolver.SetResolver(new SimpleInjectorResolver(container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
71
src/iOS/Services/iOSPushNotificationHandler.cs
Normal file
71
src/iOS/Services/iOSPushNotificationHandler.cs
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,20 +1,23 @@
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using Bit.App.Utilities;
|
|
||||||
using Foundation;
|
using Foundation;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading;
|
|
||||||
using UIKit;
|
using UIKit;
|
||||||
using UserNotifications;
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Bit.iOS.Services
|
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()
|
public void Register()
|
||||||
{
|
{
|
||||||
|
@ -27,127 +30,9 @@ namespace Bit.iOS.Services
|
||||||
public void Unregister()
|
public void Unregister()
|
||||||
{
|
{
|
||||||
UIApplication.SharedApplication.UnregisterForRemoteNotifications();
|
UIApplication.SharedApplication.UnregisterForRemoteNotifications();
|
||||||
OnUnregisteredSuccess();
|
_pushNotificationListener.OnUnregistered(Device.iOS);
|
||||||
}
|
NSUserDefaults.StandardUserDefaults.SetString(string.Empty, TokenSetting);
|
||||||
|
|
||||||
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<string, object>();
|
|
||||||
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);
|
|
||||||
NSUserDefaults.StandardUserDefaults.Synchronize();
|
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<IPushNotificationService> Implementation = new Lazy<IPushNotificationService>(
|
|
||||||
() => new iOSPushNotificationService(),
|
|
||||||
LazyThreadSafetyMode.PublicationOnly);
|
|
||||||
public static bool IsInitialized => PushNotificationListener != null;
|
|
||||||
public static IPushNotificationListener PushNotificationListener { get; private set; }
|
|
||||||
|
|
||||||
public static void Initialize<T>(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<T>() 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,7 @@
|
||||||
<Compile Include="Services\DeviceActionService.cs" />
|
<Compile Include="Services\DeviceActionService.cs" />
|
||||||
<Compile Include="Main.cs" />
|
<Compile Include="Main.cs" />
|
||||||
<Compile Include="AppDelegate.cs" />
|
<Compile Include="AppDelegate.cs" />
|
||||||
|
<Compile Include="Services\iOSPushNotificationHandler.cs" />
|
||||||
<Compile Include="Services\iOSPushNotificationService.cs" />
|
<Compile Include="Services\iOSPushNotificationService.cs" />
|
||||||
<Compile Include="Services\ReflectionService.cs" />
|
<Compile Include="Services\ReflectionService.cs" />
|
||||||
<None Include="Entitlements.plist" />
|
<None Include="Entitlements.plist" />
|
||||||
|
|
Loading…
Reference in a new issue