更新记录
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 平台,与其他平台同时运行需要加条件编译
环境配置
前置条件
- 在 Apple Developer 账号中启用
Sign in with Apple
功能 - 更新打包证书的描述文件
- iOS 系统版本 13.0 及以上
Apple Developer 配置
1. 启用 Sign in with Apple
- 登录 Apple Developer Portal
- 进入
Certificates, Identifiers & Profiles
- 选择你的 App ID,编辑配置
- 勾选
Sign in with Apple
选项 - 保存配置
2. 更新描述文件
启用 Sign in with Apple
功能后,必须重新生成并下载描述文件:
- 在 Provisioning Profiles 中重新生成描述文件
- 下载新的描述文件
- 在 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格式的身份令牌 |
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);
}
});
}
技术支持
如果在使用过程中遇到问题,请:
- 查阅上方常见问题
- 参考苹果官方开发文档
- 检查证书和配置是否正确
- 确认应用在 Apple Developer 中的配置
祝您开发愉快! 🎉