Flutter苹果账号登录插件the_apple_sign_in的使用

Flutter苹果账号登录插件the_apple_sign_in的使用

The Apple Sign In - Flutter Plugin

注意!the_apple_sign_influtter_apple_sign_in 的修订和更新版本,由 beerstorm 维护。

在开始之前,请阅读关于 Sign In with Apple 的相关文档。

平台支持

此插件目前仅支持iOS平台。如果需要,可以使用JavaScript框架来为Android提供支持。

实现步骤

  1. 在Xcode中配置您的应用程序以添加“使用Apple登录”功能。具体操作可参考官方指南
  2. 查看示例应用,了解API的工作原理。

常见问题解答 (FAQs)

用户信息为空

用户详细信息(如电子邮件和姓名)仅在用户首次通过“使用Apple登录”注册时提供。这并不是插件的限制,而是原生SDK的功能

重新登录后,所有属性都将为空。您需要在第一次登录时存储这些信息。

为了测试目的,您可以撤销凭据并再次登录:

  1. 登录 Apple ID管理页面
  2. 转到“使用Apple ID的应用程序和网站”,点击“管理”
  3. 选择您的应用程序
  4. 点击“停止使用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

1 回复

更多关于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插件:

  1. 配置iOS项目

    • 打开Xcode,选择你的Runner项目。
    • 转到Signing & Capabilities标签。
    • 确保你的应用已经配置了正确的Team和Signing Certificate。
    • Capabilities部分,启用Sign in with Apple
  2. 在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对象。

确保在实际应用中遵循苹果的安全和隐私政策,正确处理用户数据。

回到顶部