Flutter苹果账号登录插件the_apple_sign_in的使用
Flutter苹果账号登录插件the_apple_sign_in的使用
The Apple Sign In - Flutter Plugin
注意!the_apple_sign_in
是 flutter_apple_sign_in
的修订和更新版本,由 beerstorm 维护。
在开始之前,请阅读关于 Sign In with Apple 的相关文档。
平台支持
此插件目前仅支持iOS平台。如果需要,可以使用JavaScript框架来为Android提供支持。
实现步骤
常见问题解答 (FAQs)
用户信息为空
用户详细信息(如电子邮件和姓名)仅在用户首次通过“使用Apple登录”注册时提供。这并不是插件的限制,而是原生SDK的功能。
重新登录后,所有属性都将为空。您需要在第一次登录时存储这些信息。
为了测试目的,您可以撤销凭据并再次登录:
- 登录 Apple ID管理页面
- 转到“使用Apple ID的应用程序和网站”,点击“管理”
- 选择您的应用程序
- 点击“停止使用Apple ID”
构建项目时遇到错误
“使用Apple登录”要求Xcode 11,因为它需要iOS 13 SDK。请确保您的开发环境是最新的。
示例代码
以下是完整的示例代码:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:the_apple_sign_in/the_apple_sign_in.dart';
import 'button_test/button_test_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: SignInPage());
}
}
class SignInPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _SignInPageState();
}
class _SignInPageState extends State<SignInPage> {
final Future<bool> _isAvailableFuture = TheAppleSignIn.isAvailable();
String errorMessage;
@override
void initState() {
super.initState();
checkLoggedInState();
TheAppleSignIn.onCredentialRevoked.listen((_) {
print("Credentials revoked");
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sign In with Apple Example App'),
),
backgroundColor: Colors.grey,
body: SingleChildScrollView(
child: Center(
child: SizedBox(
width: 280,
child: FutureBuilder<bool>(
future: _isAvailableFuture,
builder: (context, isAvailableSnapshot) {
if (!isAvailableSnapshot.hasData) {
return Container(child: Text('Loading...'));
}
return isAvailableSnapshot.data
? Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 100,
),
AppleSignInButton(
onPressed: logIn,
),
if (errorMessage != null) Text(errorMessage),
SizedBox(
height: 200,
),
ElevatedButton(
child: Text("Button Test Page"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ButtonTestPage()));
},
)
])
: Text(
'Sign in With Apple not available. Must be run on iOS 13+');
},
)))),
);
}
void logIn() async {
final AuthorizationResult result = await TheAppleSignIn.performRequests([
AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
]);
switch (result.status) {
case AuthorizationStatus.authorized:
// Store user ID
await FlutterSecureStorage()
.write(key: "userId", value: result.credential.user);
// Navigate to secret page (shhh!)
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (_) => AfterLoginPage(credential: result.credential)));
break;
case AuthorizationStatus.error:
print("Sign in failed: ${result.error.localizedDescription}");
setState(() {
errorMessage = "Sign in failed";
});
break;
case AuthorizationStatus.cancelled:
print('User cancelled');
break;
}
}
void checkLoggedInState() async {
final userId = await FlutterSecureStorage().read(key: "userId");
if (userId == null) {
print("No stored user ID");
return;
}
final credentialState = await TheAppleSignIn.getCredentialState(userId);
switch (credentialState.status) {
case CredentialStatus.authorized:
print("getCredentialState returned authorized");
break;
case CredentialStatus.error:
print(
"getCredentialState returned an error: ${credentialState.error.localizedDescription}");
break;
case CredentialStatus.revoked:
print("getCredentialState returned revoked");
break;
case CredentialStatus.notFound:
print("getCredentialState returned not found");
break;
case CredentialStatus.transferred:
print("getCredentialState returned not transferred");
break;
}
}
}
class AfterLoginPage extends StatelessWidget {
final AppleIdCredential credential;
const AfterLoginPage({@required this.credential});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Logged in Success️'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Welcome ${credential.fullName?.givenName}!",
style: TextStyle(fontSize: 25),
textAlign: TextAlign.center,
),
Text(
"Your email: '${credential.email}'",
style: TextStyle(fontSize: 15),
textAlign: TextAlign.center,
),
OutlinedButton(
child: Text("Log out"),
onPressed: () async {
await FlutterSecureStorage().deleteAll();
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => SignInPage()));
})
]),
)));
}
}
以上是关于Flutter苹果账号登录插件the_apple_sign_in
的使用说明及完整示例代码。希望对您有所帮助!
更多关于Flutter苹果账号登录插件the_apple_sign_in的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter苹果账号登录插件the_apple_sign_in的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用Flutter插件the_apple_sign_in
来实现苹果账号登录的示例代码。这个插件允许你在Flutter应用中集成Apple Sign In功能。
首先,确保你已经在pubspec.yaml
文件中添加了the_apple_sign_in
依赖:
dependencies:
flutter:
sdk: flutter
the_apple_sign_in: ^2.0.0 # 请检查最新版本号
然后运行flutter pub get
来获取依赖。
接下来,按照以下步骤配置和使用the_apple_sign_in
插件:
-
配置iOS项目:
- 打开Xcode,选择你的Runner项目。
- 转到
Signing & Capabilities
标签。 - 确保你的应用已经配置了正确的Team和Signing Certificate。
- 在
Capabilities
部分,启用Sign in with Apple
。
-
在Flutter代码中集成Apple Sign In:
下面是一个完整的示例,展示了如何使用
the_apple_sign_in
插件:
import 'package:flutter/material.dart';
import 'package:the_apple_sign_in/the_apple_sign_in.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Apple Sign In Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SignInScreen(),
);
}
}
class SignInScreen extends StatefulWidget {
@override
_SignInScreenState createState() => _SignInScreenState();
}
class _SignInScreenState extends State<SignInScreen> {
final AppleSignIn _appleSignIn = AppleSignIn();
UserCredential? _userCredential;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Apple Sign In Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () async {
try {
final AppleSignInCredential appleCredential =
await _appleSignIn.signIn();
// 在这里,你通常会将凭证发送到你的后端服务器进行验证
// 这里只是简单地将凭证信息打印出来
print('User ID: ${appleCredential.user}');
print('Email: ${appleCredential.email}');
print('Full Name: ${appleCredential.fullName}');
// 假设后端返回了一个UserCredential对象,这里我们模拟一下
setState(() {
_userCredential = UserCredential(
userId: appleCredential.user,
email: appleCredential.email,
displayName: appleCredential.fullName,
);
});
} catch (e) {
print(e);
}
},
child: Text('Sign in with Apple'),
),
if (_userCredential != null)
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('User ID: ${_userCredential!.userId}'),
Text('Email: ${_userCredential!.email}'),
Text('Display Name: ${_userCredential!.displayName}'),
],
),
),
],
),
),
);
}
}
// 模拟的用户凭证类
class UserCredential {
final String userId;
final String? email;
final String? displayName;
UserCredential({required this.userId, this.email, this.displayName});
}
说明:
- AppleSignIn类:这是
the_apple_sign_in
插件提供的主要类,用于处理Apple Sign In流程。 - signIn方法:调用此方法将启动Apple Sign In流程,并返回一个
AppleSignInCredential
对象,其中包含用户的ID、电子邮件和全名等信息。 - 用户凭证处理:在实际应用中,你需要将
AppleSignInCredential
发送到你的后端服务器进行进一步验证和处理。上面的示例只是简单地将信息打印出来,并模拟了一个UserCredential
对象。
确保在实际应用中遵循苹果的安全和隐私政策,正确处理用户数据。