DevBoi

[Flutter] Splash Screen 에서 로그인 정보 기반 핸들링(자동로그인) 본문

[Mobile]/[Flutter]

[Flutter] Splash Screen 에서 로그인 정보 기반 핸들링(자동로그인)

HiSmith 2023. 8. 12. 00:34
반응형

Splash Screen 세팅은 아래 내 블로그 다른글에 집중적으로 작성했다. 참고하자

https://devboi.tistory.com/649

 

1. Splash Screen 의존성 추가해준다.

dependencies:
  flutter_native_splash: ^2.3.1 #Splash 스크린

 

2.Splash Screen을 세팅해준다.

프로젝트 루트 경로에 flutter_native_splash.yaml 파일 생성 (주석처리 된 부분 참고하여, 커스터마이징)

flutter_native_splash:
  # This package generates native code to customize Flutter's default white native splash screen
  # with background color and splash image.
  # Customize the parameters below, and run the following command in the terminal:
  # dart run flutter_native_splash:create
  # To restore Flutter's default white splash screen, run the following command in the terminal:
  # dart run flutter_native_splash:remove

  # color or background_image is the only required parameter.  Use color to set the background
  # of your splash screen to a solid color.  Use background_image to set the background of your
  # splash screen to a png image.  This is useful for gradients. The image will be stretch to the
  # size of the app. Only one parameter can be used, color and background_image cannot both be set.
  color: "#42a5f5"
  #background_image: "assets/background.png"

  # Optional parameters are listed below.  To enable a parameter, uncomment the line by removing
  # the leading # character.

  # The image parameter allows you to specify an image used in the splash screen.  It must be a
  # png file and should be sized for 4x pixel density.
  #image: assets/splash.png

  # The branding property allows you to specify an image used as branding in the splash screen.
  # It must be a png file. It is supported for Android, iOS and the Web.  For Android 12,
  # see the Android 12 section below.
  #branding: assets/dart.png

  # To position the branding image at the bottom of the screen you can use bottom, bottomRight,
  # and bottomLeft. The default values is bottom if not specified or specified something else.
  #branding_mode: bottom

  # The color_dark, background_image_dark, image_dark, branding_dark are parameters that set the background
  # and image when the device is in dark mode. If they are not specified, the app will use the
  # parameters from above. If the image_dark parameter is specified, color_dark or
  # background_image_dark must be specified.  color_dark and background_image_dark cannot both be
  # set.
  #color_dark: "#042a49"
  #background_image_dark: "assets/dark-background.png"
  #image_dark: assets/splash-invert.png
  #branding_dark: assets/dart_dark.png

  # Android 12 handles the splash screen differently than previous versions.  Please visit
  # https://developer.android.com/guide/topics/ui/splash-screen
  # Following are Android 12 specific parameter.
  android_12:
  # The image parameter sets the splash screen icon image.  If this parameter is not specified,
  # the app's launcher icon will be used instead.
  # Please note that the splash screen will be clipped to a circle on the center of the screen.
  # App icon with an icon background: This should be 960×960 pixels, and fit within a circle
  # 640 pixels in diameter.
  # App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
  # 768 pixels in diameter.
  #image: assets/android12splash.png

  # Splash screen background color.
  #color: "#42a5f5"

  # App icon background color.
  #icon_background_color: "#111111"

  # The branding property allows you to specify an image used as branding in the splash screen.
  #branding: assets/dart.png

  # The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that
  # apply when the device is in dark mode. If they are not specified, the app will use the
  # parameters from above.
  #image_dark: assets/android12splash-invert.png
  #color_dark: "#042a49"
  #icon_background_color_dark: "#eeeeee"

  # The android, ios and web parameters can be used to disable generating a splash screen on a given
  # platform.
  #android: false
  #ios: false
  #web: false

  # Platform specific images can be specified with the following parameters, which will override
  # the respective parameter.  You may specify all, selected, or none of these parameters:
  #color_android: "#42a5f5"
  #color_dark_android: "#042a49"
  #color_ios: "#42a5f5"
  #color_dark_ios: "#042a49"
  #color_web: "#42a5f5"
  #color_dark_web: "#042a49"
  #image_android: assets/splash-android.png
  #image_dark_android: assets/splash-invert-android.png
  #image_ios: assets/splash-ios.png
  #image_dark_ios: assets/splash-invert-ios.png
  #image_web: assets/splash-web.gif
  #image_dark_web: assets/splash-invert-web.gif
  #background_image_android: "assets/background-android.png"
  #background_image_dark_android: "assets/dark-background-android.png"
  #background_image_ios: "assets/background-ios.png"
  #background_image_dark_ios: "assets/dark-background-ios.png"
  #background_image_web: "assets/background-web.png"
  #background_image_dark_web: "assets/dark-background-web.png"
  #branding_android: assets/brand-android.png
  #branding_dark_android: assets/dart_dark-android.png
  #branding_ios: assets/brand-ios.gif
  #branding_dark_ios: assets/dart_dark-ios.gif

 

3.이제 앱의 초기 로드때 Preference로 이전에 로그인했어서, 로컬디비에 저장된 데이터가 있는지를 확인해야한다.

로컬 디비에서 확인 후에, 로그인했다면 Main으로, 로그인한 이력이 없으면 Login으로 이동시키면 된다.

 

main.dart

import 'package:boilerflutterapp/view/screen/login.dart';
import 'package:boilerflutterapp/view/screen/main_screen.dart';
import 'package:boilerflutterapp/view/widget/login/kakao/kakao_login.dart';
import 'package:boilerflutterapp/view/widget/login/kakao/kakao_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart';

import 'app.dart';

void main() async {
  Widget? startWidget;
  //카카오 로그인
  KakaoSdk.init(nativeAppKey: 'a052835de9e3c213cfb33745a93d0c8c');
  //스플래쉬 화면
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
  //카카오 로그인 정보 찾기.
  KakaoViewModel viewModel = KakaoViewModel(KakaoLogin());
  //스플래쉬 지연
  await Future.delayed(const Duration(seconds: 2));
  //카카오 로그인 회원 정보 로드 Result Id
  int? userId = viewModel.loadLoginInfo();
  //로그인 이력이 있다면, MainScreen 전달
  if(userId != null && userId != 0){
    startWidget = MainScreen();
  }
  else{
    startWidget = Login();
  }
  FlutterNativeSplash.remove();
  runApp(MyApp(startWidget: startWidget,userId: userId));
}

 

app.dart

import 'package:boilerflutterapp/util/const.dart';
import 'package:boilerflutterapp/util/router.dart';
import 'package:boilerflutterapp/util/theme_config.dart';
import 'package:boilerflutterapp/view/screen/login.dart';
import 'package:boilerflutterapp/view/screen/main_screen.dart';
import 'package:boilerflutterapp/view/widget/login/kakao/kakao_login.dart';
import 'package:boilerflutterapp/view/widget/login/kakao/kakao_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:google_fonts/google_fonts.dart';


class MyApp extends StatelessWidget {

  const MyApp({Key? key ,required this.startWidget,required this.userId})
      : super(key: key);
  final startWidget;
  final userId;

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: Constants.appName,
      theme: themeData(ThemeConfig.lightTheme),
      darkTheme: themeData(ThemeConfig.darkTheme),
      home: startWidget,
    );
  }

  ThemeData themeData(ThemeData theme) {
    return theme.copyWith(
      textTheme: GoogleFonts.sourceSansProTextTheme(
        theme.textTheme,
      ),
    );
  }
}

 

심플하다.

main.dart에서 데이터를 불러와서, widget을 파라미터로 넘겨주고,

app.dart는 이 받은 파라미터를 Home으로 세팅한다.

만약 Login에서 로그인을 성공하면, 로컬데이터에 넣기 때문에, 반복 시 login 화면이 아닌 Main화면으로 UserId와 함께 가게 된다.

 

int? loadLoginInfo() {
    return interface.load();
  }
int? load() {
    int id = 0;
    var user_profile =  prefs.getString(prefix);
    if(user_profile == null)
      return 0;
    var jsonData = json.decode(user_profile!);
    KakaoUserProfile userProfile = KakaoUserProfile.fromJson(jsonData);
    return userProfile.id;
  }

 

단순히 로드하는 쪽 소스는 위와 같다.

 

한군데 더 신경써줘야하는데

로그인 했을때, 해당 데이터에 대한 값을 넣어주는 부분이다.

        IconButton(
        icon: Image.asset('assets/images/kakao_login.png'),
        iconSize: 350,
        onPressed: () async {
          viewModel.login(context);
        }
        )
Future login(BuildContext context) async{
    int? load_id;
    isLogined = await _socialLogin.login();
    if(isLogined){
      user = await UserApi.instance.me();
      //카카오 로그인 로드/저장
      int? userid = user?.id;
      String? thumbnailImageUrl=user?.kakaoAccount?.profile?.thumbnailImageUrl;
      String? nickname = user?.kakaoAccount?.profile?.nickname;
      load_id = interface.load();
      //load 데이터 없는 경우
      if(load_id == null || load_id == 0){
        interface.save(new KakaoUserProfile(userid, nickname, thumbnailImageUrl));

      }
      //페이지 이동
      Navigate.pushPageReplacement(context, MainScreen());
    }
  }

 

위처럼 하면, 로그인했을때 로컬디비에 넣고, Main으로 이동해준다.

반응형