1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-21 02:33:36 +00:00

[EC-770] Implement MessagePack on Watch sync (#2264)

* EC-770 Started implementing MessagePack for the iPhone -> Watch communication

* EC-770 Removed Pods and installed MessagePack through SPM

* EC-770 Implemented MessagePack + Lzfse compression when syncing iPhone -> Watch

* EC-770 Added MessagePack as submodule and updated the build to checkout the submodule as well. Also added MessagePack files as reference in the watch project

* EC-770 Updated build

Updated build.yml to checkout submodules on iOS
This commit is contained in:
Federico Maccaroni
2023-03-09 15:45:51 -03:00
committed by GitHub
parent a18f74a72a
commit 9f8307a4ff
21 changed files with 228 additions and 45 deletions

View File

@@ -3,9 +3,8 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Services;
using Bit.Core.Abstractions;
using Bit.Core.Models;
using Bit.Core.Utilities;
using Newtonsoft.Json;
using Foundation;
using WatchConnectivity;
namespace Bit.iOS.Core.Services
@@ -15,12 +14,17 @@ namespace Bit.iOS.Core.Services
const string ACTION_MESSAGE_KEY = "actionMessage";
const string TRIGGER_SYNC_ACTION_KEY = "triggerSync";
private readonly ILogger _logger;
public WatchDeviceService(ICipherService cipherService,
IEnvironmentService environmentService,
IStateService stateService,
IVaultTimeoutService vaultTimeoutService)
IVaultTimeoutService vaultTimeoutService,
ILogger logger)
: base(cipherService, environmentService, stateService, vaultTimeoutService)
{
_logger = logger;
WCSessionManager.SharedManager.OnMessagedReceived += OnMessagedReceived;
}
@@ -30,17 +34,24 @@ namespace Bit.iOS.Core.Services
protected override bool IsSupported => WCSession.IsSupported;
protected override Task SendDataToWatchAsync(WatchDTO watchDto)
protected override Task SendDataToWatchAsync(byte[] rawData)
{
var serializedData = JsonConvert.SerializeObject(watchDto);
NSError error = null;
// Lzfse is available on iOS 13+ but we're already constraining that by the constraint of watchOS version
// so there's no way this will be executed on lower than iOS 13. So no condition is needed here.
var data = NSData.FromArray(rawData).Compress(NSDataCompressionAlgorithm.Lzfse, out error);
if (error != null)
{
_logger.Error("Can't compress Lzfse. Error: " + error.LocalizedDescription);
return Task.CompletedTask;
}
// Add time to the key to make it change on every message sent so it's delivered faster.
// If we use the same key then the OS may defer the delivery of the message because of
// resources, reachability and other stuff
WCSessionManager.SharedManager.SendBackgroundHighPriorityMessage(new Dictionary<string, object>
{
[$"watchDto-{DateTime.UtcNow.ToLongTimeString()}"] = serializedData
});
var dict = new NSDictionary<NSString, NSObject>(new NSString($"watchDto-{DateTime.UtcNow.ToLongTimeString()}"), data);
WCSessionManager.SharedManager.SendBackgroundHighPriorityMessage(dict);
return Task.CompletedTask;
}

View File

@@ -74,7 +74,7 @@ namespace WatchConnectivity
Debug.WriteLine($"Watch connectivity Reachable:{(session.Reachable ? '✓' : '✗')}");
}
public void SendBackgroundHighPriorityMessage(Dictionary<string, object> applicationContext)
public void SendBackgroundHighPriorityMessage(NSDictionary<NSString, NSObject> applicationContext)
{
// Application context doesnt need the watch to be reachable, it will be received when opened
if (validSession is null || validSession.ActivationState != WCSessionActivationState.Activated)
@@ -84,10 +84,10 @@ namespace WatchConnectivity
try
{
var sendSuccessfully = validSession.UpdateApplicationContext(applicationContext.ToNSDictionary(), out var error);
var sendSuccessfully = validSession.UpdateApplicationContext(applicationContext, out var error);
if (sendSuccessfully)
{
Debug.WriteLine($"Sent App Context \nPayLoad: {applicationContext.ToNSDictionary().ToString()} \n");
Debug.WriteLine($"Sent App Context \nPayLoad: {applicationContext.ToString()} \n");
}
else
{

View File

@@ -144,7 +144,8 @@ namespace Bit.iOS.Core.Utilities
ServiceContainer.Register<IWatchDeviceService>(new WatchDeviceService(ServiceContainer.Resolve<ICipherService>(),
ServiceContainer.Resolve<IEnvironmentService>(),
ServiceContainer.Resolve<IStateService>(),
ServiceContainer.Resolve<IVaultTimeoutService>()));
ServiceContainer.Resolve<IVaultTimeoutService>(),
ServiceContainer.Resolve<ILogger>()));
}
public static void Bootstrap(Func<Task> postBootstrapFunc = null)