Flutter谷歌登录插件google_sign_in_ios的使用

Flutter谷歌登录插件google_sign_in_ios的使用

概述

google_sign_in_iosgoogle_sign_in 插件在 iOS 和 macOS 平台上的实现。它允许开发者通过Google账号进行用户认证,简化了应用中集成Google登录的过程。

使用方法

由于该插件是官方推荐使用的插件(endorsed),因此您可以在项目中直接使用 google_sign_in,而无需单独添加 google_sign_in_ios 到您的 pubspec.yaml 文件中。但如果您需要直接导入此包以使用其API,则应该像平常一样将其添加到 pubspec.yaml 中。

macOS 设置

为了确保 GoogleSignIn SDK 的正常工作,必须启用 keychain sharing 功能。这可以通过向项目的 entitlements 文件中添加以下内容来完成:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)com.google.GIDSignIn</string>
</array>

如果不执行此步骤,在尝试登录时可能会抛出 keychain errorPlatformException 异常。

iOS 集成步骤

  1. 创建并注册一个 Firebase 项目,并为您的应用启用 Google 登录。

  2. 下载最新的 GoogleService-Info.plist 文件,但不要将此文件放入项目中。

  3. GoogleService-Info.plist 文件中的客户端 ID 添加到 [my_project]/ios/Runner/Info.plist 文件中:

    <key>GIDClientID</key>
    <string>[YOUR IOS CLIENT ID]</string>
    
  4. 如果需要与后端服务器进行身份验证,还可以在 Info.plist 文件中添加 GIDServerClientID 键值对:

    <key>GIDServerClientID</key>
    <string>[YOUR SERVER CLIENT ID]</string>
    
  5. [my_project]/ios/Runner/Info.plist 文件中添加如下配置:

    <!-- Put me in the [my_project]/ios/Runner/Info.plist file -->
    <!-- Google Sign-in Section -->
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <!-- TODO Replace this value: -->
                <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
                <string>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string>
            </array>
        </dict>
    </array>
    <!-- End of the Google Sign-in Section -->
    

或者,您可以选择不在 Info.plist 中配置这些信息,而是直接在 Dart 代码中传递 clientIdserverClientId 参数给 GoogleSignIn 构造函数:

final GoogleSignIn googleSignIn = GoogleSignIn(
  clientId: 'Your Client ID',
  serverClientId: 'Your Server ID',
);

请注意,即使采用上述方法,第5步仍然是必需的。

示例 Demo

下面是一个完整的示例应用程序,展示了如何使用 google_sign_in 实现登录功能:

import 'dart:async';
import 'dart:convert' show json;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(
    const MaterialApp(
      title: 'Google Sign In',
      home: SignInDemo(),
    ),
  );
}

class SignInDemo extends StatefulWidget {
  const SignInDemo({super.key});

  @override
  State createState() => SignInDemoState();
}

class SignInDemoState extends State<SignInDemo> {
  GoogleSignInUserData? _currentUser;
  String _contactText = '';
  Future<void>? _initialization;

  @override
  void initState() {
    super.initState();
    _signIn();
  }

  Future<void> _ensureInitialized() async {
    return _initialization ??=
        GoogleSignInPlatform.instance.initWithParams(const SignInInitParameters(
      scopes: [
        'email',
        'https://www.googleapis.com/auth/contacts.readonly',
      ],
    )).catchError((_) {
      _initialization = null;
    });
  }

  void _setUser(GoogleSignInUserData? user) {
    setState(() {
      _currentUser = user;
      if (user != null) {
        _handleGetContact(user);
      }
    });
  }

  Future<void> _signIn() async {
    await _ensureInitialized();
    final newUser =
        await GoogleSignInPlatform.instance.signInSilently();
    _setUser(newUser);
  }

  Future<Map<String, String>> _getAuthHeaders() async {
    final user = _currentUser;
    if (user == null) {
      throw StateError('No user signed in');
    }

    final response =
        await GoogleSignInPlatform.instance.getTokens(
      email: user.email,
      shouldRecoverAuth: true,
    );

    return {
      'Authorization': 'Bearer ${response.accessToken}',
      'X-Goog-AuthUser': '0',
    };
  }

  Future<void> _handleGetContact(GoogleSignInUserData user) async {
    setState(() {
      _contactText = 'Loading contact info...';
    });
    final response = await http.get(
      Uri.parse('https://people.googleapis.com/v1/people/me/connections'
          '?requestMask.includeField=person.names'),
      headers: await _getAuthHeaders(),
    );
    if (response.statusCode != 200) {
      setState(() {
        _contactText = 'People API gave a ${response.statusCode} '
            'response. Check logs for details.';
      });
      print('People API ${response.statusCode} response: ${response.body}');
      return;
    }
    final data = json.decode(response.body) as Map<String, dynamic>;
    final contactCount =
        (data['connections'] as List<dynamic>?)?.length ?? 0;
    setState(() {
      _contactText = '$contactCount contacts found';
    });
  }

  Future<void> _handleSignIn() async {
    try {
      await _ensureInitialized();
      _setUser(await GoogleSignInPlatform.instance.signIn());
    } catch (error) {
      final canceled =
          error is PlatformException && error.code == 'sign_in_canceled';
      if (!canceled) {
        print(error);
      }
    }
  }

  Future<void> _handleSignOut() async {
    await _ensureInitialized();
    await GoogleSignInPlatform.instance.disconnect();
  }

  Widget _buildBody() {
    final user = _currentUser;
    if (user != null) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          ListTile(
            title: Text(user.displayName ?? ''),
            subtitle: Text(user.email),
          ),
          const Text('Signed in successfully.'),
          Text(_contactText),
          ElevatedButton(
            onPressed: _handleSignOut,
            child: const Text('SIGN OUT'),
          ),
          ElevatedButton(
            child: const Text('REFRESH'),
            onPressed: () => _handleGetContact(user),
          ),
        ],
      );
    } else {
      return Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          const Text('You are not currently signed in.'),
          ElevatedButton(
            onPressed: _handleSignIn,
            child: const Text('SIGN IN'),
          ),
        ],
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Google Sign In'),
      ),
      body: ConstrainedBox(
        constraints: const BoxConstraints.expand(),
        child: _buildBody(),
      ),
    );
  }
}

以上就是关于 google_sign_in_ios 插件的详细介绍以及一个简单的示例应用。希望这对您有所帮助!


更多关于Flutter谷歌登录插件google_sign_in_ios的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter谷歌登录插件google_sign_in_ios的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,google_sign_in_ios 插件用于在iOS平台上实现Google登录功能。不过需要注意的是,从Flutter 2.0开始,google_sign_in 插件已经支持多平台(包括iOS和Android),因此通常推荐使用 google_sign_in 插件而不是单独的 google_sign_in_ios

以下是一个使用 google_sign_in 插件在Flutter中实现Google登录功能的示例代码:

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 google_sign_in 依赖:

dependencies:
  flutter:
    sdk: flutter
  google_sign_in: ^5.0.0  # 请确保使用最新版本

2. 配置iOS项目

对于iOS项目,你需要执行以下步骤来配置Google登录:

  • 在Xcode中打开你的项目。
  • 选择你的项目目标(Target),然后在“Signing & Capabilities”标签页中启用“Sign In with Apple”和“Associated Domains”(如果你需要的话)。
  • 在Xcode的“Info.plist”文件中添加以下条目(确保替换 YOUR_REVERSED_CLIENT_ID 为你的GoogleService-Info.plist文件中的 REVERSED_CLIENT_ID):
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>com.googleusercontent.apps.YOUR_REVERSED_CLIENT_ID</string>
        </array>
    </dict>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>googlechrome</string>
    <string>com.google.chrome.ios</string>
</array>
  • 将下载的 GoogleService-Info.plist 文件添加到Xcode项目的根目录中。

3. 实现Google登录功能

接下来,在你的Flutter代码中实现Google登录功能:

import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Google Sign In Example'),
        ),
        body: GoogleSignInExample(),
      ),
    );
  }
}

class GoogleSignInExample extends StatefulWidget {
  @override
  _GoogleSignInExampleState createState() => _GoogleSignInExampleState();
}

class _GoogleSignInExampleState extends State<GoogleSignInExample> {
  final GoogleSignIn _googleSignIn = GoogleSignIn(
    scopes: [
      'email',
      'https://www.googleapis.com/auth/contacts.readonly',
    ],
  );

  GoogleSignInAccount? _currentUser;
  String _contactText = '';

  void _handleSignIn() async {
    try {
      GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
      if (googleUser == null) return;
      _currentUser = googleUser;
      _contactText = 'Hello,\n${googleUser.email}!\n';

      // 这里可以添加获取用户信息或其他操作的代码
      // 例如,使用Firebase进行身份验证等

    } catch (error) {
      print(error);
    }
  }

  void _handleSignOut() {
    _googleSignIn.signOut();
    _currentUser = null;
    _contactText = '';
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
            'Google Sign In',
            style: TextStyle(fontSize: 24),
          ),
          SizedBox(height: 24),
          if (_currentUser != null)
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Text(
                  'Signed in as $_contactText',
                  style: TextStyle(fontSize: 18),
                ),
                SizedBox(height: 8),
                ButtonBar(
                  alignment: MainAxisAlignment.center,
                  children: <Widget>[
                    TextButton(
                      onPressed: () => _handleSignOut(),
                      child: Text('Sign out'),
                    ),
                  ],
                ),
              ],
            )
          else
            ElevatedButton(
              onPressed: () => _handleSignIn(),
              child: Text('Sign in with Google'),
            ),
        ],
      ),
    );
  }
}

这个示例代码展示了如何使用 google_sign_in 插件在Flutter应用中实现Google登录功能。它包括登录、显示用户信息和登出的基本功能。请确保你已经按照上述步骤正确配置了iOS项目,并且使用了最新的插件版本。

回到顶部