1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-09-23 03:12:55 +02:00

Fixes for iOS push notifications (#1708)

* WIP Fixes for iOS push notifications

* WIP Fixes for iOS push notifications, fix missed implementation on android

* Fix some issues on the push notifications, changed to Debug Console.WriteLine, and added update on entitlements on the build.yml
This commit is contained in:
Federico Maccaroni 2022-01-18 11:52:08 -03:00 committed by GitHub
parent 42403210a0
commit 2791d4b8ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 107 additions and 31 deletions

View File

@ -397,6 +397,15 @@ jobs:
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Autofill/Info.plist
shell: bash
- name: Update Entitlements
run: |
echo "########################################"
echo "##### Updating Entitlements"
echo "########################################"
perl -0777 -pi.bak -e 's/<key>aps-environment<\/key>\s*<string>development<\/string>/<key>aps-environment<\/key>\n\t<string>production<\/string>/' ./src/iOS/Entitlements.plist
shell: bash
- name: Set up Keychain
env:
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }}

View File

@ -1,6 +1,7 @@
#if !FDROID
using System;
using System.Threading.Tasks;
using AndroidX.Core.App;
using Bit.App.Abstractions;
using Bit.Core;
using Bit.Core.Abstractions;
@ -21,6 +22,8 @@ namespace Bit.Droid.Services
_pushNotificationListenerService = pushNotificationListenerService;
}
public bool IsRegisteredForPush => NotificationManagerCompat.From(Android.App.Application.Context)?.AreNotificationsEnabled() ?? false;
public async Task<string> GetTokenAsync()
{
return await _storageService.GetAsync<string>(Constants.PushCurrentTokenKey);

View File

@ -4,6 +4,7 @@ namespace Bit.App.Abstractions
{
public interface IPushNotificationService
{
bool IsRegisteredForPush { get; }
Task<string> GetTokenAsync();
Task RegisterAsync();
Task UnregisterAsync();

View File

@ -1,15 +1,14 @@
using Bit.App.Abstractions;
using Bit.App.Models;
using System;
using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Utilities;
using Bit.Core.Models.Request;
using Bit.Core.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages

View File

@ -5,6 +5,8 @@ namespace Bit.App.Services
{
public class NoopPushNotificationService : IPushNotificationService
{
public bool IsRegisteredForPush => false;
public Task<string> GetTokenAsync()
{
return Task.FromResult(null as string);

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
@ -25,5 +25,7 @@
<array>
<string>webcredentials:bitwarden.com</string>
</array>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>

View File

@ -1,13 +1,15 @@
using Bit.App.Abstractions;
using Foundation;
using Newtonsoft.Json.Linq;
using System;
using System;
using System.Diagnostics;
using Bit.App.Abstractions;
using Foundation;
using Microsoft.AppCenter.Crashes;
using Newtonsoft.Json.Linq;
using UserNotifications;
using Xamarin.Forms;
namespace Bit.iOS.Services
{
public class iOSPushNotificationHandler
public class iOSPushNotificationHandler : NSObject, IUNUserNotificationCenterDelegate
{
private const string TokenSetting = "token";
private const string DomainName = "iOSPushNotificationService";
@ -21,6 +23,8 @@ namespace Bit.iOS.Services
}
public void OnMessageReceived(NSDictionary userInfo)
{
try
{
var json = DictionaryToJson(userInfo);
var values = JObject.Parse(json);
@ -37,6 +41,11 @@ namespace Bit.iOS.Services
}
_pushNotificationListenerService.OnMessageAsync(values, Device.iOS);
}
catch (Exception ex)
{
Crashes.TrackError(ex);
}
}
public void OnErrorReceived(NSError error)
{
@ -47,9 +56,15 @@ namespace Bit.iOS.Services
public void OnRegisteredSuccess(NSData token)
{
Debug.WriteLine("{0} - Successfully Registered.", DomainName);
var hexDeviceToken = BitConverter.ToString(token.ToArray())
.Replace("-", string.Empty).ToLowerInvariant();
Console.WriteLine("{0} - Token: {1}", DomainName, hexDeviceToken);
.Replace("-", string.Empty)
.ToLowerInvariant();
Debug.WriteLine("{0} - Token: {1}", DomainName, hexDeviceToken);
UNUserNotificationCenter.Current.Delegate = this;
_pushNotificationListenerService.OnRegisteredAsync(hexDeviceToken, Device.iOS);
NSUserDefaults.StandardUserDefaults.SetString(hexDeviceToken, TokenSetting);
NSUserDefaults.StandardUserDefaults.Synchronize();
@ -60,5 +75,29 @@ namespace Bit.iOS.Services
var json = NSJsonSerialization.Serialize(dictionary, NSJsonWritingOptions.PrettyPrinted, out NSError error);
return json.ToString(NSStringEncoding.UTF8);
}
// To receive notifications in foreground on iOS 10 devices.
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
Debug.WriteLine($"{DomainName} WillPresentNotification {notification?.Request?.Content?.UserInfo}");
OnMessageReceived(notification?.Request?.Content?.UserInfo);
completionHandler(UNNotificationPresentationOptions.Alert);
}
[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
Debug.WriteLine($"{DomainName} DidReceiveNotificationResponse {response?.Notification?.Request?.Content?.UserInfo}");
if (response.IsDefaultAction)
{
OnMessageReceived(response?.Notification?.Request?.Content?.UserInfo);
}
// Inform caller it has been handled
completionHandler();
}
}
}

View File

@ -1,11 +1,14 @@
using System.Threading.Tasks;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Bit.App.Abstractions;
using Foundation;
using UIKit;
using UserNotifications;
namespace Bit.iOS.Services
{
public class iOSPushNotificationService : IPushNotificationService
public class iOSPushNotificationService : NSObject, IPushNotificationService, IUNUserNotificationCenterDelegate
{
private const string TokenSetting = "token";
@ -14,13 +17,31 @@ namespace Bit.iOS.Services
return Task.FromResult(NSUserDefaults.StandardUserDefaults.StringForKey(TokenSetting));
}
public Task RegisterAsync()
public bool IsRegisteredForPush => UIApplication.SharedApplication.IsRegisteredForRemoteNotifications;
public async Task RegisterAsync()
{
var userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge |
UIUserNotificationType.Sound;
var settings = UIUserNotificationSettings.GetSettingsForTypes(userNotificationTypes, null);
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
return Task.FromResult(0);
var tcs = new TaskCompletionSource<bool>();
var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) =>
{
if (error != null)
{
Debug.WriteLine($"Push Notifications {error}");
}
else
{
Debug.WriteLine($"Push Notifications {granted}");
}
tcs.SetResult(granted);
});
if (await tcs.Task)
{
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
}
public Task UnregisterAsync()