如何在iOS Flutter App中保存用户登录信息

hmae6n7t  于 12个月前  发布在  iOS
关注(0)|答案(2)|浏览(242)

我在保存flutter应用的ios版本的用户凭证时遇到了问题。
我已经实现了AutofillGroupautofillHints,我还添加了关联域,在这里你可以看到代码和Xcode设置:

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_fimber/flutter_fimber.dart';
import 'package:get_it/get_it.dart';
import 'package:medfyle/bloc/auth/auth_form_cubit.dart';
import 'package:medfyle/presentation/theme/theme.dart';

import '../../../bloc/user/user_bloc.dart';
import '../../../navigator.dart';
import '../../component/mixin/custom_tracker.dart';
import '../../component/mixin/loading.dart';
import '../../component/mixin/manage_error.dart';
import '../../component/widget/appbar/base_app_bar.dart';
import '../../component/widget/custom_button.dart';

class LoginPage extends StatefulWidget {
  static const routeName = '/login_page';

  const LoginPage({Key? key}) : super(key: key);

  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage>
    with Loading, ManageError, CustomTracker {
  @override
  Widget build(BuildContext context) {
    trackScreenWithName(traceName: LoginPage.routeName);
    return BlocProvider<AuthFormBlocCubit>(
      create: (BuildContext context) => GetIt.instance.get<AuthFormBlocCubit>(),
      child: Scaffold(
          appBar: BaseAppBar(label: "auth.login.title".tr()),
          body: SafeArea(
            child: BlocListener<UserBloc, UserState>(
              listener: (context, state) {
                if (state is UserIsLoading) {
                  showLoader(context);
                }
                if (state is UserLoginError) {
                  manageError(context, state.error,
                      showDialog: state.showDialog,
                      showSnack: false,
                      dialogCb: hideLoader(context));
                  hideLoader(context);
                  Fimber.e(state.error.toString());
                }
                if (state is UserIsLogged) {
                  N.goToHome(context);
                }
              },
              child: Padding(
                padding: kDefaultPadding,
                child: BlocBuilder<AuthFormBlocCubit, AuthFormState>(
                    builder: (context, state) {
                  return AutofillGroup(
                    child: Column(
                      children: <Widget>[
                        TextFormField(
                          onChanged: (v) {
                            context.read<AuthFormBlocCubit>().changeEmail(v);
                          },
                          autofillHints: const [
                            AutofillHints.email,
                            AutofillHints.username,
                            AutofillHints.newUsername
                          ],
                          keyboardType: TextInputType.emailAddress,
                          decoration: InputDecoration(
                            hintText: "auth.form.email".tr(),
                            labelText: "auth.form.email".tr(),
                          ),
                        ),
                        const SizedBox(height: 16),
                        TextFormField(
                          onChanged: (v) {
                            context.read<AuthFormBlocCubit>().changePassword(v);
                          },
                          keyboardType: TextInputType.visiblePassword,
                          obscureText: true,
                          autofillHints: const [
                            AutofillHints.password,
                            AutofillHints.newPassword
                          ],
                          decoration: InputDecoration(
                            hintText: "auth.form.password".tr(),
                            labelText: "auth.form.password".tr(),
                          ),
                        ),
                        const SizedBox(height: 8),
                        const Spacer(),
                        CustomButton.fullWidth(
                          label: "auth.login.btn_enter".tr(),
                          onPressed: state.validLoginForm
                              ? () {
                                  context.read<UserBloc>().add(Login(
                                      state.email!.trim(),
                                      state.password!.trim()));
                                  TextInput.finishAutofillContext();
                                }
                              : null,
                        ),
                      ],
                    ),
                  );
                }),
              ),
            ),
          )),
    );
  }
}

Flutter医生:

[✓] Flutter (Channel stable, 3.7.12, on macOS 13.0 22A380 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.80.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

这就是我得到的

我错过了登录后的“保存”弹出窗口:

此外,我如何才能使建议像这样工作(而不是简单的“密码”建议,我现在得到的):

llycmphe

llycmphe1#

试着遵循这个格式。将TextFormFields替换为TextFields。您需要将控制器传递给每个TextField。

@override
  Widget build(BuildContext context) {
    return AutofillGroup(
      child: Column(
        children: <Widget>[
          TextField(controller: username, autofillHints: [AutofillHints.username]),
          Checkbox(
            value: isNewUser,
            onChanged: (bool newValue) {
              setState(() { isNewUser = newValue; });
            },
          ),
          if (isNewUser) TextField(controller: newPassword, autofillHints: [AutofillHints.newPassword]),
          if (isNewUser) TextField(controller: repeatNewPassword, autofillHints: [AutofillHints.newPassword]),
          if (!isNewUser) TextField(controller: password, autofillHints: [AutofillHints.password]),
        ],
      ),
    );
  }

For more info see the documentation.

sbtkgmzw

sbtkgmzw2#

首先,将keychain_service包添加到pubspec.yaml文件中:

dependencies:
  keychain_service: ^1.0.0

2、导入widget中保存用户登录信息的包:

import 'package:keychain_service/keychain_service.dart';

3、登录页面,登录成功后,使用KeychainService示例保存数据:

final keychain = KeychainService();
await keychain.write(key: 'email', value: email);
await keychain.write(key: 'password', value: password);

4、这将保存钥匙串中的电子邮件和密码。要检索数据,请再次使用KeychainService示例:

final keychain = KeychainService();
String email = await keychain.read(key: 'email');
String password = await keychain.read(key: 'password');

第五,要做到这一点,用户必须启用他们的iCloud钥匙串,

相关问题