1
0
mirror of https://github.com/bitwarden/mobile.git synced 2024-11-29 12:45:20 +01:00

PM-3349 PM-3350 MAUI Migration Start iOS extensions

This commit is contained in:
Federico Maccaroni 2023-10-02 12:05:57 -03:00
parent d17789d5ee
commit 990de4ea4e
No known key found for this signature in database
GPG Key ID: 5D233F8F2B034536
12 changed files with 126 additions and 309 deletions

View File

@ -9,94 +9,30 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\Core\Core.cspro
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{E71F3053-056C-4381-9638-048ED73BDFF6}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Core", "src\iOS.Core\iOS.Core.csproj", "{E71F3053-056C-4381-9638-048ED73BDFF6}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
FDroid|Any CPU = FDroid|Any CPU
Debug|iPhone = Debug|iPhone
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|iPhoneSimulator = Release|iPhoneSimulator
AppStore|Any CPU = AppStore|Any CPU
AppStore|iPhone = AppStore|iPhone
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Ad-Hoc|iPhone = Ad-Hoc|iPhone
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.Build.0 = Debug|Any CPU {971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.ActiveCfg = Release|Any CPU {971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.Build.0 = Release|Any CPU {971FDF07-E288-4239-B47A-E9E7E912193B}.Release|Any CPU.Build.0 = Release|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.FDroid|Any CPU.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.FDroid|Any CPU.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhone.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhone.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{971FDF07-E288-4239-B47A-E9E7E912193B}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.Build.0 = Debug|Any CPU {11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.ActiveCfg = Release|Any CPU {11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.Build.0 = Release|Any CPU {11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|Any CPU.Build.0 = Release|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.FDroid|Any CPU.Build.0 = FDroid|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhone.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhone.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{11DBC05E-F8B4-49ED-AAC9-96D92336D21C}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.Build.0 = Debug|Any CPU {E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.ActiveCfg = Release|Any CPU {E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.Build.0 = Release|Any CPU {E71F3053-056C-4381-9638-048ED73BDFF6}.Release|Any CPU.Build.0 = Release|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.ActiveCfg = FDroid|Any CPU {8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.FDroid|Any CPU.Build.0 = FDroid|Any CPU {8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.ActiveCfg = Debug|iPhone {8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhone.Build.0 = Debug|iPhone {8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.ActiveCfg = AppStore|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|Any CPU.Build.0 = AppStore|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhone.Build.0 = AppStore|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|Any CPU.Build.0 = Ad-Hoc|Any CPU
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{E71F3053-056C-4381-9638-048ED73BDFF6}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -208,12 +208,12 @@
</MauiImage> </MauiImage>
<MauiImage Include="Resources\yubikey.png" /> <MauiImage Include="Resources\yubikey.png" />
</ItemGroup> </ItemGroup>
<!--<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'"> <ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
<ProjectReference Include="..\iOS.Autofill\iOS.Autofill.csproj"> <ProjectReference Include="..\iOS.Autofill\iOS.Autofill.csproj">
<IsAppExtension>true</IsAppExtension> <IsAppExtension>true</IsAppExtension>
<IsWatchApp>false</IsWatchApp> <IsWatchApp>false</IsWatchApp>
</ProjectReference> </ProjectReference>
</ItemGroup>--> </ItemGroup>
<ItemGroup> <ItemGroup>
<GoogleServicesJson Include="Platforms\Android\google-services.json" /> <GoogleServicesJson Include="Platforms\Android\google-services.json" />
<GoogleServicesJson Include="Platforms\Android\google-services.json.enc" /> <GoogleServicesJson Include="Platforms\Android\google-services.json.enc" />

View File

@ -155,6 +155,8 @@ namespace Bit.App.Pages
{ {
try try
{ {
// TODO: [MAUI-Migration] added delay or the modal navigation doesn't happen because of modal-loading is shown
await Task.Delay(200);
await _deviceActionService.ShowLoadingAsync(AppResources.Loading); await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
await _stateService.SetPreLoginEmailAsync(Email); await _stateService.SetPreLoginEmailAsync(Email);
await AccountSwitchingOverlayViewModel.RefreshAccountViewsAsync(); await AccountSwitchingOverlayViewModel.RefreshAccountViewsAsync();

View File

@ -338,7 +338,7 @@ namespace Bit.App.Pages
public string PlusAddressedEmail public string PlusAddressedEmail
{ {
get => _usernameOptions.PlusAddressedEmail; get => _usernameOptions?.PlusAddressedEmail;
set set
{ {
if (_usernameOptions != null && _usernameOptions.PlusAddressedEmail != value) if (_usernameOptions != null && _usernameOptions.PlusAddressedEmail != value)

View File

@ -1,8 +1,23 @@
using Foundation; using System;
using Foundation;
using Microsoft.Maui;
using Microsoft.Maui.Embedding;
using Microsoft.Maui.Hosting;
using UIKit; using UIKit;
namespace Bit.iOS.Autofill namespace Bit.iOS.Autofill
{ {
public class MauiContextSingleton
{
private static Lazy<MauiContextSingleton> _instance = new Lazy<MauiContextSingleton>(() => new MauiContextSingleton());
private MauiContextSingleton() { }
public static MauiContextSingleton Instance = _instance.Value;
public MauiContext MauiContext { get; set; }
}
[Register("AppDelegate")] [Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate public partial class AppDelegate : UIApplicationDelegate
{ {
@ -26,5 +41,17 @@ namespace Bit.iOS.Autofill
public override void WillTerminate(UIApplication application) public override void WillTerminate(UIApplication application)
{ {
} }
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
var builder = MauiApp.CreateBuilder();
builder.UseMauiEmbedding<Microsoft.Maui.Controls.Application>();
// Register the Window
builder.Services.Add(new Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(UIWindow), Window));
var mauiApp = builder.Build();
MauiContextSingleton.Instance.MauiContext = new MauiContext(mauiApp.Services);
return base.FinishedLaunching(application, launchOptions);
}
} }
} }

View File

@ -16,9 +16,10 @@ using Bit.iOS.Core.Views;
using CoreFoundation; using CoreFoundation;
using CoreNFC; using CoreNFC;
using Foundation; using Foundation;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Compatibility;
using Microsoft.Maui.Platform;
using UIKit; using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
namespace Bit.iOS.Autofill namespace Bit.iOS.Autofill
{ {
@ -42,7 +43,9 @@ namespace Bit.iOS.Autofill
try try
{ {
InitApp(); InitApp();
base.ViewDidLoad(); base.ViewDidLoad();
Logo.Image = new UIImage(ThemeHelpers.LightTheme ? "logo.png" : "logo_white.png"); Logo.Image = new UIImage(ThemeHelpers.LightTheme ? "logo.png" : "logo_white.png");
View.BackgroundColor = ThemeHelpers.SplashBackgroundColor; View.BackgroundColor = ThemeHelpers.SplashBackgroundColor;
_context = new Context _context = new Context
@ -61,6 +64,8 @@ namespace Bit.iOS.Autofill
{ {
try try
{ {
Console.WriteLine("[Bitwarden] PrepareCredentialList");
InitAppIfNeeded(); InitAppIfNeeded();
_context.ServiceIdentifiers = serviceIdentifiers; _context.ServiceIdentifiers = serviceIdentifiers;
if (serviceIdentifiers.Length > 0) if (serviceIdentifiers.Length > 0)
@ -392,9 +397,6 @@ namespace Bit.iOS.Autofill
private void InitApp() private void InitApp()
{ {
// Init Xamarin Forms
Forms.Init();
if (ServiceContainer.RegisteredServices.Count > 0) if (ServiceContainer.RegisteredServices.Count > 0)
{ {
ServiceContainer.Reset(); ServiceContainer.Reset();
@ -444,7 +446,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(homePage); var navigationPage = new NavigationPage(homePage);
var loginController = navigationPage.CreateViewController(); var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(loginController, true, null); PresentViewController(loginController, true, null);
@ -464,7 +466,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(environmentPage); var navigationPage = new NavigationPage(environmentPage);
var loginController = navigationPage.CreateViewController(); var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(loginController, true, null); PresentViewController(loginController, true, null);
} }
@ -482,7 +484,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(registerPage); var navigationPage = new NavigationPage(registerPage);
var loginController = navigationPage.CreateViewController(); var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(loginController, true, null); PresentViewController(loginController, true, null);
} }
@ -505,7 +507,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(loginPage); var navigationPage = new NavigationPage(loginPage);
var loginController = navigationPage.CreateViewController(); var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(loginController, true, null); PresentViewController(loginController, true, null);
@ -528,7 +530,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(loginWithDevicePage); var navigationPage = new NavigationPage(loginWithDevicePage);
var loginController = navigationPage.CreateViewController(); var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(loginController, true, null); PresentViewController(loginController, true, null);
@ -552,7 +554,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(loginPage); var navigationPage = new NavigationPage(loginPage);
var loginController = navigationPage.CreateViewController(); var loginController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(loginController, true, null); PresentViewController(loginController, true, null);
@ -582,7 +584,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(twoFactorPage); var navigationPage = new NavigationPage(twoFactorPage);
var twoFactorController = navigationPage.CreateViewController(); var twoFactorController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
twoFactorController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; twoFactorController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(twoFactorController, true, null); PresentViewController(twoFactorController, true, null);
} }
@ -601,7 +603,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(setPasswordPage); var navigationPage = new NavigationPage(setPasswordPage);
var setPasswordController = navigationPage.CreateViewController(); var setPasswordController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
setPasswordController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; setPasswordController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(setPasswordController, true, null); PresentViewController(setPasswordController, true, null);
} }
@ -619,7 +621,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(updateTempPasswordPage); var navigationPage = new NavigationPage(updateTempPasswordPage);
var updateTempPasswordController = navigationPage.CreateViewController(); var updateTempPasswordController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
updateTempPasswordController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; updateTempPasswordController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(updateTempPasswordController, true, null); PresentViewController(updateTempPasswordController, true, null);
} }
@ -638,7 +640,7 @@ namespace Bit.iOS.Autofill
} }
var navigationPage = new NavigationPage(loginApproveDevicePage); var navigationPage = new NavigationPage(loginApproveDevicePage);
var loginApproveDeviceController = navigationPage.CreateViewController(); var loginApproveDeviceController = navigationPage.ToUIViewController(MauiContextSingleton.Instance.MauiContext);
loginApproveDeviceController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; loginApproveDeviceController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
PresentViewController(loginApproveDeviceController, true, null); PresentViewController(loginApproveDeviceController, true, null);
} }

View File

@ -1,8 +1,8 @@
using System; using System;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Resources.Localization;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.iOS.Autofill.Models; using Bit.iOS.Autofill.Models;
using Bit.iOS.Autofill.Utilities; using Bit.iOS.Autofill.Utilities;

View File

@ -3,7 +3,7 @@ using Bit.iOS.Autofill.Models;
using Foundation; using Foundation;
using UIKit; using UIKit;
using Bit.iOS.Core.Controllers; using Bit.iOS.Core.Controllers;
using Bit.App.Resources; using Bit.Core.Resources.Localization;
using Bit.iOS.Core.Views; using Bit.iOS.Core.Views;
using Bit.iOS.Autofill.Utilities; using Bit.iOS.Autofill.Utilities;
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BitwardeniOSAutofill")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Bitwarden Inc.")]
[assembly: AssemblyProduct("Bitwarden")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8a3ecd75-3ec8-4cb3-b3a2-a73a724c279a")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -1,7 +1,7 @@
using System; using System;
using UIKit; using UIKit;
using Bit.iOS.Core.Controllers; using Bit.iOS.Core.Controllers;
using Bit.App.Resources; using Bit.Core.Resources.Localization;
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;
namespace Bit.iOS.Autofill namespace Bit.iOS.Autofill

View File

@ -1,8 +1,8 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Resources.Localization;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.iOS.Core.Utilities; using Bit.iOS.Core.Utilities;
using Bit.iOS.Core.Views; using Bit.iOS.Core.Views;

View File

@ -1,159 +1,34 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFrameworks>net8.0-ios</TargetFrameworks>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform> <UseMaui>True</UseMaui>
<ProjectGuid>{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}</ProjectGuid> <OutputType>Library</OutputType>
<ProjectTypeGuids>{EE2C853D-36AF-4FDB-B1AD-8E90477E2198};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <ApplicationId>com.8bit.bitwarden.autofill</ApplicationId>
<OutputType>Exe</OutputType> <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<RootNamespace>Bit.iOS.Autofill</RootNamespace> <ApplicationVersion>1</ApplicationVersion>
<AssemblyName>BitwardeniOSAutofill</AssemblyName>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix> <EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<AppDesignerFolder>Properties</AppDesignerFolder>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">12.0</SupportedOSPlatformVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>true</DebugSymbols> <PropertyGroup>
<DebugType>full</DebugType> <IsAppExtension>true</IsAppExtension>
<Optimize>false</Optimize> <IsWatchExtension>false</IsWatchExtension>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>x86_64</MtouchArch>
<MtouchLink>None</MtouchLink>
<MtouchDebug>true</MtouchDebug>
<MtouchExtraArgs>--nodevcodeshare --http-message-handler=NSUrlSessionHandler -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<OptimizePNGs>true</OptimizePNGs>
<MtouchFastDev>false</MtouchFastDev>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchSdkVersion>12.0</MtouchSdkVersion>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType> <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-ios|AnyCPU'">
<Optimize>true</Optimize> <CreatePackage>false</CreatePackage>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath> <RuntimeIdentifier>iossimulator-arm64</RuntimeIdentifier>
<ErrorReport>prompt</ErrorReport> <CodesignProvision>Automatic</CodesignProvision>
<WarningLevel>4</WarningLevel> <CodesignKey>iPhone Developer</CodesignKey>
<MtouchLink>Full</MtouchLink> <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>x86_64</MtouchArch> <MtouchInterpreter>all</MtouchInterpreter>
<ConsolePause>false</ConsolePause> <MtouchLink>None</MtouchLink>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchExtraArgs>--http-message-handler=NSUrlSessionHandler --linkskip=BitwardeniOS --linkskip=BitwardeniOSCore --linkskip=BitwardeniOSAutofill --linkskip=BitwardenApp --linkskip=BitwardenCore --linkskip=LiteDB --linkskip=BitwardeniOSShareExtension -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<OptimizePNGs>true</OptimizePNGs>
<CodesignKey>iPhone Developer</CodesignKey>
<CodesignProvision>Automatic</CodesignProvision>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' "> <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0-ios|AnyCPU'">
<DebugSymbols>true</DebugSymbols> <CreatePackage>false</CreatePackage>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<MtouchArch>ARM64</MtouchArch>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignKey>iPhone Developer</CodesignKey>
<MtouchDebug>true</MtouchDebug>
<MtouchLink>None</MtouchLink>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchExtraArgs>--nodevcodeshare --http-message-handler=NSUrlSessionHandler -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<OptimizePNGs>true</OptimizePNGs>
<MtouchSdkVersion>
</MtouchSdkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>ARM64</MtouchArch>
<ConsolePause>false</ConsolePause>
<CodesignKey>iPhone Distribution</CodesignKey>
<MtouchLink>Full</MtouchLink>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<OptimizePNGs>true</OptimizePNGs>
<MtouchExtraArgs>--http-message-handler=NSUrlSessionHandler --linkskip=BitwardeniOS --linkskip=BitwardeniOSCore --linkskip=BitwardeniOSAutofill --linkskip=BitwardenApp --linkskip=BitwardenCore --linkskip=LiteDB --linkskip=BitwardeniOSShareExtension -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<CodesignProvision>Dist: Autofill</CodesignProvision>
</PropertyGroup>
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Default' ">
<AppExtensionDebugBundleId />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'AppStore|iPhoneSimulator'">
<OutputPath>bin\iPhoneSimulator\AppStore\</OutputPath>
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;</DefineConstants>
<Optimize>true</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<MtouchExtraArgs>--http-message-handler=NSUrlSessionHandler --linkskip=BitwardeniOS --linkskip=BitwardeniOSCore --linkskip=BitwardeniOSAutofill --linkskip=BitwardenApp --linkskip=BitwardenCore --linkskip=LiteDB --linkskip=BitwardeniOSShareExtension -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<OptimizePNGs>true</OptimizePNGs>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchLink>Full</MtouchLink>
<MtouchSdkVersion>9.3</MtouchSdkVersion>
<CodesignKey>iPhone Distribution</CodesignKey>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>Dist: Autofill</CodesignProvision>
<MtouchArch>x86_64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'AppStore|iPhone'">
<OutputPath>bin\iPhone\AppStore\</OutputPath>
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;</DefineConstants>
<Optimize>true</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<MtouchLink>Full</MtouchLink>
<MtouchExtraArgs>--http-message-handler=NSUrlSessionHandler --linkskip=BitwardeniOS --linkskip=BitwardeniOSCore --linkskip=BitwardeniOSAutofill --linkskip=BitwardenApp --linkskip=BitwardenCore --linkskip=LiteDB --linkskip=BitwardeniOSShareExtension -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<OptimizePNGs>true</OptimizePNGs>
<MtouchArch>ARM64</MtouchArch>
<MtouchSdkVersion>10.2</MtouchSdkVersion>
<CodesignKey>iPhone Distribution</CodesignKey>
<CodesignProvision>Automatic:AppStore</CodesignProvision>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhoneSimulator'">
<OutputPath>bin\iPhoneSimulator\Ad-Hoc\</OutputPath>
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;</DefineConstants>
<Optimize>true</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<MtouchExtraArgs>--http-message-handler=NSUrlSessionHandler --linkskip=BitwardeniOS --linkskip=BitwardeniOSCore --linkskip=BitwardeniOSAutofill --linkskip=BitwardenApp --linkskip=BitwardenCore --linkskip=LiteDB --linkskip=BitwardeniOSShareExtension -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<OptimizePNGs>true</OptimizePNGs>
<MtouchLink>Full</MtouchLink>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchSdkVersion>9.3</MtouchSdkVersion>
<CodesignKey>iPhone Distribution</CodesignKey>
<CodesignProvision>Adhoc: Autofill</CodesignProvision>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<MtouchArch>x86_64</MtouchArch>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone'">
<OutputPath>bin\iPhone\Ad-Hoc\</OutputPath>
<DefineConstants>__IOS__;__MOBILE__;__UNIFIED__;</DefineConstants>
<Optimize>true</Optimize>
<PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<MtouchArch>ARM64</MtouchArch>
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
<MtouchLink>Full</MtouchLink>
<MtouchExtraArgs>--http-message-handler=NSUrlSessionHandler --linkskip=BitwardeniOS --linkskip=BitwardeniOSCore --linkskip=BitwardeniOSAutofill --linkskip=BitwardenApp --linkskip=BitwardenCore --linkskip=LiteDB --linkskip=BitwardeniOSShareExtension -gcc_flags "-L${ProjectDir}/../../lib/ios -largon2 -force_load ${ProjectDir}/../../lib/ios/libargon2.a"</MtouchExtraArgs>
<OptimizePNGs>true</OptimizePNGs>
<CodesignKey>iPhone Distribution</CodesignKey>
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
<CodesignProvision>Automatic:AdHoc</CodesignProvision>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CredentialProviderViewController.cs" /> <Compile Include="CredentialProviderViewController.cs" />
@ -190,33 +65,9 @@
<None Include="Info.plist" /> <None Include="Info.plist" />
<None Include="Entitlements.plist" /> <None Include="Entitlements.plist" />
<Compile Include="Models\Context.cs" /> <Compile Include="Models\Context.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<InterfaceDefinition Include="MainInterface.storyboard" />
<BundleResource Include="Resources\MaterialIcons_Regular.ttf" /> <BundleResource Include="Resources\MaterialIcons_Regular.ttf" />
<BundleResource Include="Resources\bwi-font.ttf" /> <BundleResource Include="Resources\bwi-font.ttf" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="Xamarin.iOS" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\App\App.csproj">
<Project>{ee44c6a1-2a85-45fe-8d9b-bf1d5f88809c}</Project>
<Name>App</Name>
</ProjectReference>
<ProjectReference Include="..\Core\Core.csproj">
<Project>{4b8a8c41-9820-4341-974c-41e65b7f4366}</Project>
<Name>Core</Name>
</ProjectReference>
<ProjectReference Include="..\iOS.Core\iOS.Core.csproj">
<Project>{e71f3053-056c-4381-9638-048ed73bdff6}</Project>
<Name>iOS.Core</Name>
<IsAppExtension>false</IsAppExtension>
<IsWatchApp>false</IsWatchApp>
</ProjectReference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<BundleResource Include="Resources\check.png" /> <BundleResource Include="Resources\check.png" />
</ItemGroup> </ItemGroup>
@ -265,9 +116,9 @@
</BundleResource> </BundleResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Crashes"> <PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<Version>5.0.2</Version> <PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
</PackageReference> <!-- <PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.2" /> -->
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<BundleResource Include="Resources\yubikey.png" /> <BundleResource Include="Resources\yubikey.png" />
@ -278,5 +129,40 @@
<ItemGroup> <ItemGroup>
<BundleResource Include="Resources\yubikey%403x.png" /> <BundleResource Include="Resources\yubikey%403x.png" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.AppExtension.CSharp.targets" /> <ItemGroup>
<BundleResource Update="Resources\yubikey%403x.png">
<Link>Resources\yubikey%403x.png</Link>
</BundleResource>
<BundleResource Update="Resources\yubikey%402x.png">
<Link>Resources\yubikey%402x.png</Link>
</BundleResource>
<BundleResource Update="Resources\Icon%402x.png">
<Link>Resources\Icon%402x.png</Link>
</BundleResource>
<BundleResource Update="Resources\logo%403x.png">
<Link>Resources\logo%403x.png</Link>
</BundleResource>
<BundleResource Update="Resources\check%402x.png">
<Link>Resources\check%402x.png</Link>
</BundleResource>
<BundleResource Update="Resources\check%403x.png">
<Link>Resources\check%403x.png</Link>
</BundleResource>
<BundleResource Update="Resources\logo%402x.png">
<Link>Resources\logo%402x.png</Link>
</BundleResource>
<BundleResource Update="Resources\Icon%403x.png">
<Link>Resources\Icon%403x.png</Link>
</BundleResource>
<BundleResource Update="Resources\logo_white%403x.png">
<Link>Resources\logo_white%403x.png</Link>
</BundleResource>
<BundleResource Update="Resources\logo_white%402x.png">
<Link>Resources\logo_white%402x.png</Link>
</BundleResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Core\Core.csproj" />
<ProjectReference Include="..\iOS.Core\iOS.Core.csproj" />
</ItemGroup>
</Project> </Project>