Browse Source

PM-2732 Added script to build swift fat framework and also several attempts to fix and avoid loading iOS 17 stuff on other OS versions. So far this only works on iOS 17 and on previous versions the Autofill extensions doesn't load

feature/PM-2732-ios17-credentialprovider
Federico Maccaroni 2 years ago
parent
commit
95ccf1da08
No known key found for this signature in database
GPG Key ID: 5D233F8F2B034536
  1. 14
      lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/ApiDefinitions.cs
  2. 4
      lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/XamariniOS17CredentialProviderBinding.csproj
  3. 14
      lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/buildfat.sh
  4. 26
      lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/iOS17CredentialProvider/BaseASCredentialProviderViewController.swift
  5. 44
      src/iOS.Autofill/CredentialProviderViewController.cs

14
lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/ApiDefinitions.cs

@ -12,22 +12,26 @@ namespace XamariniOS17CredentialProviderBinding @@ -12,22 +12,26 @@ namespace XamariniOS17CredentialProviderBinding
interface ASCredentialProviderCompatDelegate
{
// @required -(void)prepareInterfaceToProvideCredentialCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest;
[iOS(17, 0)]
[Abstract]
[Export("prepareInterfaceToProvideCredentialCompatFor:")]
void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest);
// @required -(void)provideCredentialWithoutUserInteractionCompatFor:(ASCredentialRequestCompat * _Nonnull)credentialRequest;
[iOS(17, 0)]
[Abstract]
[Export("provideCredentialWithoutUserInteractionCompatFor:")]
void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest);
// @required -(void)prepareInterfaceCompatForPasskeyRegistration:(ASCredentialRequestCompat * _Nonnull)registrationRequest;
[iOS(17, 0)]
[Abstract]
[Export("prepareInterfaceCompatForPasskeyRegistration:")]
void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest);
}
// @interface ASCredentialRequestCompat : NSObject
[iOS(17, 0)]
[BaseType (typeof(NSObject))]
[DisableDefaultCtor]
interface ASCredentialRequestCompat
@ -42,10 +46,12 @@ namespace XamariniOS17CredentialProviderBinding @@ -42,10 +46,12 @@ namespace XamariniOS17CredentialProviderBinding
// @property (readonly, nonatomic, strong) ASPasswordCredentialIdentity * _Nullable passwordCredentialIdentity;
[iOS(17, 0)]
[NullAllowed, Export("passwordCredentialIdentity", ArgumentSemantic.Strong)]
ASPasswordCredentialIdentity PasswordCredentialIdentity { get; }
// @property (readonly, nonatomic, strong) ASPasskeyCredentialIdentityCompat * _Nullable passkeyCredentialIdentity;
[iOS(17, 0)]
[NullAllowed, Export("passkeyCredentialIdentity", ArgumentSemantic.Strong)]
ASPasskeyCredentialIdentityCompat PasskeyCredentialIdentity { get; }
}
@ -111,6 +117,7 @@ namespace XamariniOS17CredentialProviderBinding @@ -111,6 +117,7 @@ namespace XamariniOS17CredentialProviderBinding
// [Abstract]
// void PrepareInterfaceCompatForPasskeyRegistration (ASCredentialRequestCompat registrationRequest);
[iOS(17, 0)]
[Export("SetCompatDelegate:")]
void SetCompatDelegate(IASCredentialProviderCompatDelegate @delegate);
@ -124,4 +131,11 @@ namespace XamariniOS17CredentialProviderBinding @@ -124,4 +131,11 @@ namespace XamariniOS17CredentialProviderBinding
//[DesignatedInitializer]
// IntPtr Constructor (NSCoder coder);
}
// @interface MyTest : NSObject
[BaseType(typeof(NSObject))]
//[DisableDefaultCtor]
interface MyTest
{
}
}

4
lib/ios/iOS17CredentialProvider/XamariniOS17CredentialProvider/XamariniOS17CredentialProviderBinding/XamariniOS17CredentialProviderBinding.csproj

@ -50,8 +50,8 @@ @@ -50,8 +50,8 @@
<NativeReference Include="..\..\iOS17CredentialProvider\build\Release-fat\iOS17CredentialProvider.framework">
<Kind>Framework</Kind>
<SmartLink>True</SmartLink>
<ForceLoad>True</ForceLoad>
<Frameworks>Foundation AuthenticationServices</Frameworks>
<ForceLoad>False</ForceLoad>
<WeakFrameworks>Foundation AuthenticationServices</WeakFrameworks>
</NativeReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.ObjCBinding.CSharp.targets" />

14
lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/buildfat.sh

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
echo "Building framework"
xcodebuild -sdk iphonesimulator17.0 -project "iOS17CredentialProvider.xcodeproj" -configuration Release -arch x86_64
xcodebuild -sdk iphoneos17.0 -project "iOS17CredentialProvider.xcodeproj" -configuration Release
cd build
cp -R "Release-iphoneos" "Release-fat"
cp -R "Release-iphonesimulator/iOS17CredentialProvider.framework/Modules/iOS17CredentialProvider.swiftmodule/" "Release-fat/iOS17CredentialProvider.framework/Modules/iOS17CredentialProvider.swiftmodule/"
lipo -create -output "Release-fat/iOS17CredentialProvider.framework/iOS17CredentialProvider" "Release-iphoneos/iOS17CredentialProvider.framework/iOS17CredentialProvider" "Release-iphonesimulator/iOS17CredentialProvider.framework/iOS17CredentialProvider"
echo "Sharpie creating binding definitions"
sharpie bind --sdk=iphoneos17.0 --output="XamarinApiDef" --namespace="Binding" --scope="Release-iphoneos/iOS17CredentialProvider.framework/Headers/" "Release-iphoneos/iOS17CredentialProvider.framework/Headers/iOS17CredentialProvider-Swift.h"
echo "Done!"

26
lib/ios/iOS17CredentialProvider/iOS17CredentialProvider/iOS17CredentialProvider/BaseASCredentialProviderViewController.swift

@ -73,6 +73,7 @@ public class ASPasskeyCredentialIdentityCompat : NSObject { @@ -73,6 +73,7 @@ public class ASPasskeyCredentialIdentityCompat : NSObject {
public var rank: Int
}
@available(iOS 17.0, *)
@objc(ASCredentialRequestCompat)
public class ASCredentialRequestCompat : NSObject {
@ -84,9 +85,10 @@ public class ASCredentialRequestCompat : NSObject { @@ -84,9 +85,10 @@ public class ASCredentialRequestCompat : NSObject {
/** The credential identity selected by the user to authenticate.
*/
@objc
public var credentialIdentity: ASCredentialIdentity
@available(iOS 17.0, *)
var credentialIdentity: ASCredentialIdentity
@available(iOS 17.0, *)
@objc
public var passwordCredentialIdentity: ASPasswordCredentialIdentity? {
guard type == .password, let password = credentialIdentity as? ASPasswordCredentialIdentity else {
@ -95,6 +97,7 @@ public class ASCredentialRequestCompat : NSObject { @@ -95,6 +97,7 @@ public class ASCredentialRequestCompat : NSObject {
return password
}
@available(iOS 17.0, *)
@objc
public var passkeyCredentialIdentity: ASPasskeyCredentialIdentityCompat? {
guard type == .passkeyAssertion, let passkey = credentialIdentity as? ASPasskeyCredentialIdentity else {
@ -103,6 +106,7 @@ public class ASCredentialRequestCompat : NSObject { @@ -103,6 +106,7 @@ public class ASCredentialRequestCompat : NSObject {
return ASPasskeyCredentialIdentityCompat(relyingPartyIdentifier: passkey.relyingPartyIdentifier, userName: passkey.userName, credentialID: passkey.credentialID, userHandle: passkey.userHandle, recordIdentifier: passkey.recordIdentifier, rank: passkey.rank)
}
@available(iOS 17.0, *)
init(type: ASCredentialRequestCompatType, credentialIdentity: ASCredentialIdentity) {
self.type = type
self.credentialIdentity = credentialIdentity
@ -114,6 +118,7 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont @@ -114,6 +118,7 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont
{
// MARK: iOS 17 new methods
@available(iOS 17.0, *)
override final public func prepareInterfaceToProvideCredential(for credentialRequest: ASCredentialRequest) {
guard let compatDelegate = compatDelegate else {
return
@ -121,6 +126,7 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont @@ -121,6 +126,7 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont
compatDelegate.prepareInterfaceToProvideCredentialCompat(for: convertRequestToCompat(from: credentialRequest))
}
@available(iOS 17.0, *)
override final public func provideCredentialWithoutUserInteraction(for credentialRequest: ASCredentialRequest) {
guard let compatDelegate = compatDelegate else {
return
@ -128,6 +134,7 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont @@ -128,6 +134,7 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont
compatDelegate.provideCredentialWithoutUserInteractionCompat(for: convertRequestToCompat(from: credentialRequest))
}
@available(iOS 17.0, *)
override final public func prepareInterface(forPasskeyRegistration registrationRequest: ASCredentialRequest) {
guard let compatDelegate = compatDelegate else {
return
@ -140,11 +147,13 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont @@ -140,11 +147,13 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont
var compatDelegate: ASCredentialProviderCompatDelegate? = nil;
@objc
@available(iOS 17.0, *)
public func SetCompatDelegate(_ delegate: ASCredentialProviderCompatDelegate)
{
compatDelegate = delegate
}
@available(iOS 17.0, *)
func convertRequestToCompat(from credentialRequest: ASCredentialRequest) -> ASCredentialRequestCompat {
return ASCredentialRequestCompat(
type: credentialRequest.type == .password ? .password : .passkeyAssertion,
@ -155,12 +164,25 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont @@ -155,12 +164,25 @@ open class BaseASCredentialProviderViewController : ASCredentialProviderViewCont
@objc(ASCredentialProviderCompatDelegate)
public protocol ASCredentialProviderCompatDelegate
{
@available(iOS 17.0, *)
@objc
func prepareInterfaceToProvideCredentialCompat(for credentialRequest: ASCredentialRequestCompat)
@available(iOS 17.0, *)
@objc
func provideCredentialWithoutUserInteractionCompat(for credentialRequest: ASCredentialRequestCompat)
@available(iOS 17.0, *)
@objc
func prepareInterfaceCompat(forPasskeyRegistration registrationRequest: ASCredentialRequestCompat)
}
@objc(MyTest)
public class MyTest : NSObject
{
var a: String
init(a: String) {
self.a = a
}
}

44
src/iOS.Autofill/CredentialProviderViewController.cs

@ -16,6 +16,7 @@ using Bit.iOS.Core.Views; @@ -16,6 +16,7 @@ using Bit.iOS.Core.Views;
using CoreFoundation;
using CoreNFC;
using Foundation;
using NativeLibrary;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
@ -50,8 +51,11 @@ namespace Bit.iOS.Autofill @@ -50,8 +51,11 @@ namespace Bit.iOS.Autofill
{
ExtContext = ExtensionContext
};
var del = new ASCredentialProviderDelegate(this);
SetCompatDelegate(del);
if (UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
{
var del = new ASCredentialProviderDelegate(this);
SetCompatDelegate(del);
}
}
catch (Exception ex)
{
@ -667,47 +671,11 @@ namespace Bit.iOS.Autofill @@ -667,47 +671,11 @@ namespace Bit.iOS.Autofill
public void PrepareInterfaceToProvideCredentialCompatFor(ASCredentialRequestCompat credentialRequest)
{
CredentialProviderViewController?.CompleteRequest(null, "lala", "qerqrw");
//try
//{
// InitAppIfNeeded();
// if (!await IsAuthed())
// {
// await _accountsManager.NavigateOnAccountChangeAsync(false);
// return;
// }
// _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity;
// await CheckLockAsync(async () => await ProvideCredentialAsync());
//}
//catch (Exception ex)
//{
// LoggerHelper.LogEvenIfCantBeResolved(ex);
// throw;
//}
}
public void ProvideCredentialWithoutUserInteractionCompatFor(ASCredentialRequestCompat credentialRequest)
{
CredentialProviderViewController?.CompleteRequest(null, "nouserinteraction", "qerqrw");
//try
//{
// InitAppIfNeeded();
// await _stateService.Value.SetPasswordRepromptAutofillAsync(false);
// await _stateService.Value.SetPasswordVerifiedAutofillAsync(false);
// if (!await IsAuthed() || await IsLocked())
// {
// var err = new NSError(new NSString("ASExtensionErrorDomain"),
// Convert.ToInt32(ASExtensionErrorCode.UserInteractionRequired), null);
// ExtensionContext.CancelRequest(err);
// return;
// }
// _context.CredentialIdentity = credentialRequest.PasswordCredentialIdentity;
// await ProvideCredentialAsync(false);
//}
//catch (Exception ex)
//{
// LoggerHelper.LogEvenIfCantBeResolved(ex);
// throw;
//}
}
public void PrepareInterfaceCompatForPasskeyRegistration(ASCredentialRequestCompat registrationRequest)

Loading…
Cancel
Save