unity3D接入Sign in with Apple
前言,觉得好的同学别忘了给个好评哦,另外,如果有什么疑问的,欢迎随时提问~~
苹果明确规定2020.6.30之后提交到AppStroe审核的app如接入了第三方登录,则必须接入Sign in with Apple;下面给大家分享一下unity3D接入Sign in with Apple的具体流程:
1、首先是按钮格式必须使用苹果给定的几种,具体可以参考链接 苹果官方登录按钮样式;
2、oc代码:
#import <Foundation/Foundation.h>
#import <AuthenticationServices/AuthenticationServices.h>
#import "UnityAppController.h"
struct UserInfo
{
const char * userId;
const char * email;
const char * displayName;
const char * idToken;
const char * error;
ASUserDetectionStatus userDetectionStatus;
};
typedef void (*SignInWithAppleCallback)(int result, struct UserInfo s1);
API_AVAILABLE(ios(13.0), tvos(13.0))
typedef void (*CredentialStateCallback)(ASAuthorizationAppleIDProviderCredentialState state);
API_AVAILABLE(ios(13.0), tvos(13.0))
@interface UnitySignInWithApple : NSObject<ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding>
@property (nonatomic) SignInWithAppleCallback loginCallback;
@property (nonatomic) CredentialStateCallback credentialStateCallback;
@end
API_AVAILABLE(ios(13.0), tvos(13.0))
static UnitySignInWithApple* _unitySignInWithAppleInstance;
@implementation UnitySignInWithApple
{
ASAuthorizationAppleIDRequest* request;
}
+(UnitySignInWithApple*)instance
{
if (_unitySignInWithAppleInstance == nil)
_unitySignInWithAppleInstance = [[UnitySignInWithApple alloc] init];
return _unitySignInWithAppleInstance;
}
-(void)startRequest
{
if (@available(iOS 13.0, tvOS 13.0, *)) {
ASAuthorizationAppleIDProvider* provider = [[ASAuthorizationAppleIDProvider alloc] init];
request = [provider createRequest];
[request setRequestedScopes: @[ASAuthorizationScopeEmail, ASAuthorizationScopeFullName]];
ASAuthorizationController* controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
controller.delegate = self;
controller.presentationContextProvider = self;
[controller performRequests];
} else {
// Fallback on earlier versions
}
}
-(ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller
{
return _UnityAppController.window;
}
-(void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization
{
if (self.loginCallback)
{
struct UserInfo data;
if (@available(iOS 13.0, tvOS 13.0, *)) {
ASAuthorizationAppleIDCredential* credential = (ASAuthorizationAppleIDCredential*)authorization.credential;
NSString* idToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];
NSPersonNameComponents* name = credential.fullName;
data.idToken = [idToken UTF8String];
data.displayName = [[NSPersonNameComponentsFormatter localizedStringFromPersonNameComponents:name
style:NSPersonNameComponentsFormatterStyleDefault
options:0] UTF8String];
data.email = [credential.email UTF8String];
data.userId = [credential.user UTF8String];
data.userDetectionStatus = credential.realUserStatus;
data.error = "";
self.loginCallback(1, data);
} else {
// Fallback on earlier versions
}
}
}
-(void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error
{
if (self.loginCallback)
{
// All members need to be set to a non-null value.
struct UserInfo data;
data.idToken = "";
data.displayName = "";
data.email = "";
data.userId = "";
data.userDetectionStatus = 1;
data.error = [error.localizedDescription UTF8String];
self.loginCallback(0, data);
}
}
@end
void UnitySignInWithApple_Login(SignInWithAppleCallback callback)
{
if (@available(iOS 13.0, tvOS 13.0, *)) {
UnitySignInWithApple* login = [UnitySignInWithApple instance];
login.loginCallback = callback;
[login startRequest];
} else {
struct UserInfo data;
data.idToken = "";
data.displayName = "";
data.email = "";
data.userId = "";
data.userDetectionStatus = 1;
data.error = "";
callback(2, data);
}
}
3、然后是C#代码,由于我们项目是用toLua开发的,所以这里的C#提供Lua接口
using System;
using System.Runtime.InteropServices;
using AOT;
using UnityEngine;
public class SignInWithApple
{
private static LuaFunction s_LoginCompletedCallback;
public enum UserDetectionStatus
{
LikelyReal,
Unknown,
Unsupported
}
public enum UserCredentialState
{
Revoked,
Authorized,
NotFound
}
public struct UserInfo
{
public string userId;
public string email;
public string displayName;
public string idToken;
public string error;
public UserDetectionStatus userDetectionStatus;
}
public delegate void LuaFunction(int result,string str);
private delegate void LoginCompleted(int result, UserInfo info);
[MonoPInvokeCallback(typeof(LoginCompleted))]
private static void LoginCompletedCallback(int result, [MarshalAs(UnmanagedType.Struct)]UserInfo info)
{
UserInfo userInfo = new UserInfo
{
idToken = info.idToken,
displayName = info.displayName,
email = info.email,
userId = info.userId,
error = info.error,
userDetectionStatus = info.userDetectionStatus
};
string str = JsonUtility.ToJson(userInfo);
s_LoginCompletedCallback(result,str);//result:0-失败,1-成功,2-iOs版本低于13
s_LoginCompletedCallback = null;
}
public static void Login(LuaFunction callback)
{
if (s_LoginCompletedCallback != null)
throw new InvalidOperationException("Login called while another login is in progress");
s_LoginCompletedCallback = callback;
LoginInternal();
}
private static void LoginInternal()
{
IntPtr cback = IntPtr.Zero;
LoginCompleted d = LoginCompletedCallback;
cback = Marshal.GetFunctionPointerForDelegate(d);
UnitySignInWithApple_Login(cback);
}
[DllImport("__Internal")]
private static extern void UnitySignInWithApple_Login(IntPtr callback);
}
4、在toLua的CustomSettings(这里的类名可以自定义,我用的是toLua默认的)类中注册SignInWithApple后就可以在Lua中调用了:
例如,SignInWithApple.Login(function(result,userInfo) end)。