更新记录

1.0.1(2025-05-14)

更新一些配置问题

1.0.0(2025-05-12)

uniapp-x苹果登录原生插件


平台兼容性

uni-app x(4.36)

Chrome Safari Android iOS iOS插件版本 鸿蒙 微信小程序
× × × 13 1.0.1 × ×

tt-apple-signin

🍎 苹果登录SDK插件,为 uni-app x 提供完整的 Sign in with Apple 集成解决方案

📖 目录

SDK版本信息

平台 版本 支持状态
iOS 13.0+ ✅ 完全支持
Android - ❌ 不支持
HarmonyOS - ❌ 不支持

📚 推荐阅读: Apple官方文档 - Sign in with Apple

🚨 重要提示

⚠️ 必须使用自定义基座运行,标准基座无法调试苹果登录

⚠️ 仅支持 iOS 平台,与其他平台同时运行需要加条件编译

环境配置

前置条件

  1. Apple Developer 账号中启用 Sign in with Apple 功能
  2. 更新打包证书的描述文件
  3. iOS 系统版本 13.0 及以上

Apple Developer 配置

1. 启用 Sign in with Apple

  1. 登录 Apple Developer Portal
  2. 进入 Certificates, Identifiers & Profiles
  3. 选择你的 App ID,编辑配置
  4. 勾选 Sign in with Apple 选项
  5. 保存配置

2. 更新描述文件

启用 Sign in with Apple 功能后,必须重新生成并下载描述文件:

  1. 在 Provisioning Profiles 中重新生成描述文件
  2. 下载新的描述文件
  3. 在 HBuilderX 中更新证书配置

重要注意事项

💡 用户信息获取说明:只有首次弹出登录授权框时才会有用户名及邮箱信息

⚠️ 用户隐私控制:用户可以删除或编辑用户名,或选择隐藏邮箱

🔄 重新授权:如需再次获取用户信息,需要在 iOS 设置中取消授权后重新登录:

系统设置 > Apple ID > 密码与安全性 > 使用 Apple ID 的 App > 取消授权

快速开始

1. 导入插件

import * as apple from "@/uni_modules/tt-apple-signin";

export default {
    data() {
        return {
            appleSignIn: null as apple.TTAppleSignIn | null,
        }
    },
    onLoad() {
        // 初始化苹果登录实例
        this.appleSignIn = apple.getAppleSignIn();
    },
    methods: {
        // 苹果登录方法
        handleAppleLogin() {
            // 登录实现代码见下方
        }
    }
}

2. 条件编译

由于苹果登录仅支持 iOS 平台,建议使用条件编译:

// #ifdef APP-IOS
import * as apple from "@/uni_modules/tt-apple-signin";
// #endif

export default {
    data() {
        return {
            // #ifdef APP-IOS
            appleSignIn: null as apple.TTAppleSignIn | null,
            // #endif
        }
    },
    onLoad() {
        // #ifdef APP-IOS
        this.appleSignIn = apple.getAppleSignIn();
        // #endif
    }
}

基础使用

平台检测

checkPlatformSupport() {
    // #ifndef APP-IOS
    uni.showModal({
        title: '平台不支持',
        content: 'Sign in with Apple 仅支持 iOS 平台',
        showCancel: false
    });
    return false;
    // #endif

    return true;
}

API文档

苹果登录

参数说明

TTAppleSignInOptions

参数 类型 必填 说明
success function 登录成功回调函数
fail function 登录失败回调函数

示例代码

// 苹果登录
handleAppleLogin() {
    // #ifdef APP-IOS
    this.appleSignIn?.signIn({
        success: (result) => {
            console.log("✅ 苹果登录成功:", result);
            // 处理登录成功逻辑
            this.handleLoginSuccess(result);
        },
        fail: (error) => {
            console.error("❌ 苹果登录失败:", error);
            // 处理登录失败逻辑
            this.handleLoginError(error);
        }
    } as apple.TTAppleSignInOptions);
    // #endif

    // #ifndef APP-IOS
    uni.showModal({
        title: '平台不支持',
        content: 'Sign in with Apple 仅支持 iOS 平台',
        showCancel: false
    });
    // #endif
}

// 处理登录成功
handleLoginSuccess(result: apple.TTAppleSignInSuccess) {
    // 将用户信息发送到后端验证
    uni.request({
        url: 'https://your-server.com/api/apple/verify',
        method: 'POST',
        data: {
            identityToken: result.identityToken,
            authorizationCode: result.authorizationCode,
            user: result.user
        },
        success: (res) => {
            console.log('后端验证成功:', res.data);
            // 保存用户登录状态
            uni.setStorageSync('userInfo', res.data);
            // 跳转到主页面
            uni.switchTab({
                url: '/pages/tabBar/home/home'
            });
        },
        fail: (err) => {
            console.error('后端验证失败:', err);
            uni.showToast({
                title: '登录验证失败',
                icon: 'error'
            });
        }
    });
}

// 处理登录失败
handleLoginError(error: any) {
    const errCode = error.errCode;
    const cause = error.cause;

    // 检查是否为用户取消(错误码999且Apple原始错误为1001)
    if (errCode === 999 && cause && cause.code) {
        const appleErrorCode = cause.code.intValue || parseInt(cause.code.toString());
        if (appleErrorCode === 1001) {
            console.log('用户取消登录');
            return;
        }
    }

    // 其他错误显示通用提示
    uni.showToast({
        title: error.errMsg || '登录失败',
        icon: 'error'
    });
}

返回值说明

TTAppleSignInSuccess

参数名称 类型 描述
user string 用户唯一标识符,用于识别用户
state string 验证信息状态
authorizedScopes array 用户授权的作用域信息
authorizationCode string 授权码,用于服务器端验证
identityToken string JWT格式的身份令牌
email string 用户邮箱(可选,用户可选择隐藏)
realUserStatus number 真实用户状态:0-不支持,1-无法确认,2-真实性很高
fullName TTAppleSignInPersonName 用户姓名信息(可选)

TTAppleSignInPersonName

参数名称 类型 描述
namePrefix string 名字前缀(如:Dr.、Mr.)
givenName string 名字(Given Name)
middleName string 中间名
familyName string 姓氏(Family Name)
nameSuffix string 名字后缀(如:Jr.、Sr.)
nickname string 昵称

错误处理

插件错误码

错误码 描述 解决方案
101 当前系统版本不支持苹果登录 确认 iOS 版本(需 13.0+)
999 其他错误 查看原始 Apple 错误信息

Apple 原始错误码

当错误码为 999 时,可以查看 cause 字段中的 Apple 原始错误:

Apple 错误码 描述 常见原因
1001 用户取消登录 用户主动取消授权
1000 未知错误 系统或网络异常
1002 无效请求 应用配置错误
1003 不支持的操作 设备或系统限制
1004 用户交互被阻止 界面或线程问题

📖 Apple 错误码参考: ASAuthorizationError 官方文档

错误处理最佳实践

// 统一错误处理函数
handleAppleSignInError(error: any) {
    console.error('❌ 苹果登录失败:', error);

    const errCode = error.errCode;
    const errMsg = error.errMsg;
    const cause = error.cause; // Apple 原始错误信息

    console.log('插件错误码:', errCode);
    console.log('错误信息:', errMsg);
    if (cause) {
        console.log('Apple 原始错误:', cause);
    }

    switch(errCode) {
        case 101:
            uni.showModal({
                title: '系统版本不支持',
                content: '苹果登录需要 iOS 13.0 及以上版本',
                showCancel: false
            });
            break;

        case 999:
            // 处理 Apple 原始错误
            if (cause && cause.code) {
                // 注意:cause.code 是 NSNumber 类型,需要转换为数字
                const appleErrorCode = cause.code.intValue || parseInt(cause.code.toString());

                switch(appleErrorCode) {
                    case 1001:
                        // 用户取消,不显示错误提示
                        console.log('用户取消登录');
                        return;

                    case 1000:
                        uni.showToast({
                            title: '登录出现未知错误',
                            icon: 'error'
                        });
                        break;

                    case 1002:
                        uni.showModal({
                            title: '请求无效',
                            content: '请检查应用配置是否正确',
                            showCancel: false
                        });
                        break;

                    case 1003:
                        uni.showModal({
                            title: '不支持的操作',
                            content: '请检查设备和系统版本',
                            showCancel: false
                        });
                        break;

                    case 1004:
                        uni.showToast({
                            title: '用户交互被阻止',
                            icon: 'error'
                        });
                        break;

                    default:
                        uni.showToast({
                            title: cause.message || '登录失败',
                            icon: 'error'
                        });
                        break;
                }
            } else {
                // 没有原始错误信息,显示通用错误
                uni.showToast({
                    title: errMsg || '登录失败',
                    icon: 'error'
                });
            }
            break;

        default:
            uni.showToast({
                title: errMsg || '登录失败',
                icon: 'error'
            });
            break;
    }
}

// 使用示例
this.appleSignIn?.signIn({
    success: (result) => {
        this.handleLoginSuccess(result);
    },
    fail: (error) => {
        this.handleAppleSignInError(error);
    }
} as apple.TTAppleSignInOptions);

常见问题

1. 标准基座无法调试?

解决方案: 苹果登录必须使用自定义基座,标准基座不包含苹果登录功能。

2. 打包失败?

解决方案:

  • 确认已在 Apple Developer 中启用 Sign in with Apple
  • 重新生成并下载最新的描述文件
  • 在 HBuilderX 中更新证书配置

3. 其他平台兼容性问题?

解决方案:

  • 使用条件编译,仅在 iOS 平台引入插件
  • 为非 iOS 平台用户提供其他登录方式
  • 确保在非 iOS 平台有友好的提示信息

4. 无法获取用户邮箱和姓名?

解决方案:

  • 用户信息仅在首次授权时提供
  • 用户可选择隐藏邮箱或编辑姓名
  • 如需重新获取,请引导用户在设置中取消授权后重新登录

5. 身份令牌验证失败?

解决方案:

  • 确保后端正确验证 identityToken
  • 检查苹果公钥是否为最新版本
  • 验证应用的 Bundle ID 是否正确

6. 跨平台兼容性处理?

最佳实践:

// 登录方法封装
handleLogin() {
    // #ifdef APP-IOS
    this.handleAppleLogin();
    // #endif

    // #ifndef APP-IOS
    // 其他平台显示其他登录方式
    this.showOtherLoginOptions();
    // #endif
}

showOtherLoginOptions() {
    // 显示微信、QQ等其他登录方式
    console.log('显示其他登录选项');
    uni.showActionSheet({
        itemList: ['微信登录', 'QQ登录', '手机号登录'],
        success: (res) => {
            // 处理其他登录方式
            console.log('选择的登录方式:', res.tapIndex);
        }
    });
}

技术支持

如果在使用过程中遇到问题,请:

  1. 查阅上方常见问题
  2. 参考苹果官方开发文档
  3. 检查证书和配置是否正确
  4. 确认应用在 Apple Developer 中的配置

祝您开发愉快! 🎉

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: