
C# から直接 Swift のコードを呼び出す、の例として生体認証(TouchID、FaceID)を実装します。
Swift ド素人が書いた適当コードなので、色々と目を瞑ってください……。
GitHub
コード
iOSAuthentication.cs
using UnityEngine;
using System.Runtime.InteropServices;
using System;
public class iOSAuthentication : MonoBehaviour
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void CallbackDelegate([MarshalAs(UnmanagedType.I4)] Int32 num);
[DllImport("__Internal", EntryPoint = "registerAuthCallback")]
static extern void RegisterAuthCallback([MarshalAs(UnmanagedType.FunctionPtr)] CallbackDelegate callback);
[DllImport("__Internal", EntryPoint = "authentication")]
static extern long Authentication();
void Start()
{
RegisterAuthCallback(callback);
}
public void onPressButton()
{
Authentication();
}
[AOT.MonoPInvokeCallbackAttribute(typeof(CallbackDelegate))]
static void callback(Int32 num)
{
Debug.Log($"call native code: {num}");
}
}
Plugin/iOS/iOSAuthentication.swift
import Foundation
import LocalAuthentication
public typealias CallbackDelegate = @convention(c) (Int32) -> Void
public class iOSAuthentication
{
static private var authCallbackDelegate: CallbackDelegate? = nil;
public static func registerAuthCallback(_ delegate: @escaping CallbackDelegate)
{
authCallbackDelegate = delegate
}
public static func authentication()
{
var description: String = "サインイン"
let context = LAContext()
context.localizedFallbackTitle = "他の方法を試す"
var error: NSError?
// Face ID, Touch IDが利用できるデバイスか確認する
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
{
// Face ID, Touch IDが利用できる場合は認証用ダイアログを表示
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: description,
reply:
{
success, evaluateError in
if (success)
{
// 認証成功
switch context.biometryType
{
case .faceID:
authCallbackDelegate?(1)
break
case .touchID:
authCallbackDelegate?(1)
break
case .none:
// Face ID, Touch IDが利用出来ない (unknown)
authCallbackDelegate?(0)
break
@unknown default:
authCallbackDelegate?(0)
break
}
}
else
{
// 認証失敗
authCallbackDelegate?(0)
}
}
)
}
else
{
// Face ID, Touch IDが利用出来ない
authCallbackDelegate?(-1)
}
}
}
@_cdecl("registerAuthCallback")
public func registerAuthCallback(_ delegate: @escaping CallbackDelegate)
{
return iOSAuthentication.registerAuthCallback(delegate)
}
@_cdecl("authentication")
public func authentication()
{
return iOSAuthentication.authentication()
}
Editor/OnPostBuildProcess.cs

FaceID を有効にするためには、Info.plist にキーを用意しておく必要があります。
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.IO;
#if UNITY_IOS
using UnityEditor.iOS.Xcode;
#endif
public class OnPostBuildProcess : MonoBehaviour
{
[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
{
if (buildTarget == BuildTarget.iOS)
{
processForiOS(path);
}
}
static void processForiOS(string path)
{
#if UNITY_IOS
var plistPath = Path.Combine(path, "Info.plist");
var plist = new PlistDocument();
plist.ReadFromFile(plistPath);
var root = plist.root;
root.SetString("NSFaceIDUsageDescription", "認証に必要");
plist.WriteToFile(plistPath);
#endif
}
}
実行

TouchID、FaceID 両方に対応しています。
Authentification() で認証スタート、認証画面が終わると RegisterAuthCallback() で設定したコールバックに値を返します。
-1 .. TouchID、FaceID が許可されていない
0 .. 認証失敗
1 .. 認証成功
シミュレーターで確認可能
Xcode のシミュレーターで確認するのがお手軽です(Face ID は実機で見た方がいいかも)。
TouchID、FaceID を許可する

Features > Touch(Face)ID > Enrolled
Enrolled に✓マークがつくと、TouchID・FaceIDの動作を確認することができます。
判定の OK、NG
Features > Touch(Face)ID > Matching Touch(Face)
Features > Touch(Face)ID > Non-matching Touch(Face)
認証判定の OK、NG をシミュレートするにはこの2つのコマンドを選択します。
AppStore に提出する場合
一点問題があります。それについては別の記事にしましたので、必要に応じてご覧ください。



