본문 바로가기
프레임워크/flutter

[공부] Shared preference 사용하기

by seongjko 2023. 10. 6.
728x90

1. Shared preference란?

RPG 모바일 게임을 하나 만들었다고 생각해 보자.

게임이란 게 워낙 무겁다 보니 사용자들은 실제로 게임을 할 때만 앱을 켰다가 게임이 끝나면 앱을 종료한다.

그런데, 게임을 끌 때마다 오늘 내가 했던 플레이 기록들이 날아간다면?

게임 다시 켤 때마다 튜토리얼부터 다시 시작해야 될 텐데, 이거 뭐 열받아서 플레이 할수나 있을까?

꼭 게임이 아니더라도 대부분의 경우엔 앱이 꺼져도 이전 기록을 저장할 수 있도록 Database 즉, 데이터 저장소가 필요하다.

Shared preference도 일종의 데이터 저장소인데, 로그인 정보라던지, 알림 수신 동의 여부 같은 비교적 간단한 정보를 

주로 담는 데이터 저장소라고 이해할 수 있으며 아래와 같은 특징이 있다.

  • Application에 xml 파일 형태로 데이터를 저장.
  • Application이 삭제되기 전까지 저장한 데이터가 보존.
  • key와 value을 담을 수 있는 Map 형태로 저장.
  •  

2. 사용 준비

제대로 안 하면 필자처럼 위젯 하나 적용하는 데 일주일을 날릴 수 있으니 하나하나 꼼꼼하게 준비하자.

일단, 터미널에 아래 명령어를 입력해서 shared_preferences를 다운받는다.

fltter pub add shared_preferences

그리고 나서 아래와 같이 pubspec.yaml 파일의 dependencies 항목에 shared preferences가 추가되었는지 확인한다.

아주 기초적인 준비는 됐다.

 

음 근데 chatGPT는 

Android: android/app/src/main/AndroidManifest.xml 파일에 다음 코드를 추가합니다.

<uses-permission android:name="android.permission.INTERNET" />

이렇게 해야 된다고 하는데 일단 두고보자(믿을 수가 있어야지)

안 해도 되는 것 같다.

안 해도 유튜브 보고 따라하니까 잘 된다.

생각보다 뭐 특별히 준비해야 될 건 없는 것 같다.

 

3. 실전 

뭔지 대충 알았고, 사용 준비까지 마쳤으면 두말할 것 없이 바로 실전으로 들어가면 된다. 

아래 영상과 같이 동작하는 코드를 짤 것이다. 

영상에서 보듯 현재 사용자 이름을 apple로 설정하고 나면, 앱을 종료하고 다시 켜더라도 apple이 그대로 남아 있는 것을 볼 수 있다.

 

위 영상의 앱은 아래와 같은 코드로 만들어졌다. 

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

void main() async {
  runApp(const testShared());
}

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

  @override
  testSharedState createState() => testSharedState();
}

class testSharedState extends State<testShared> {
  late SharedPreferences _prefs;
  String _username = "";
  final TextEditingController _usernameController = TextEditingController();

  @override
  void initState() {
    //getUsername 때문에 넣어 준거임
    super.initState();
    _getUsername();
  }

  _saveUsername() {
    setState(() {
      _username = _usernameController.text;
      _prefs.setString("currentUsername", _username);
    });
  }

  _getUsername() async {
    //이름을 가져오는 과정은 비동기로(데이터 양 방대한면 로딩시간 UP)
    _prefs = await SharedPreferences.getInstance();
    setState(() {
      _username = _prefs.getString("currentUsername") ?? "";
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Test App"),
        ),
        body: Container(
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.all(15),
                child: Text("현재 사용자 이름: $_username"),
              ),
              Container(
                padding: const EdgeInsets.all(15),
                child: TextField(
                  controller: _usernameController,
                  textAlign: TextAlign.left,
                  decoration: const InputDecoration(
                    border: InputBorder.none,
                    hintText: "Input your username",
                  ),
                ),
              ),
              TextButton(
                onPressed: () => _saveUsername(),
                child: const Text("저장"),
              )
            ],
          ),
        ),
      ),
    );
  }
}

 코드를 보면 복잡해 보이지만 핵심은 단순하다. 

일단 앱이 실행되면 initState 메서드에서 _getUsername 메서드를 실행시킨다.

그러면 사용자의 입력을 받을 준비가 된 것이다. 

그 다음 사용자가 TextField에 원하는 이름을 입력하고 TextButton을 누르면 _saveUsername 메서드가 실행되어

shared preference에 그 이름을 저장하게 된다.

전체적인 흐름은 알았으니 이제 _getUsername과 _saveUsername 메서드가 어떻게 돌아가는지만 알면 끝난다.

참 쉽죠?

 

_getUsername

 _getUsername() async {
    //이름을 가져오는 과정은 비동기로(데이터 양 방대한면 로딩시간 UP)
    _prefs = await SharedPreferences.getInstance();
    setState(() {
      _username = _prefs.getString("currentUsername") ?? "";
    });
  }

 

    _prefs = await SharedPreferences.getInstance();

Sharedpreference의 인스턴스를 SharedPreferences 자료형의 _prefs 변수에 저장한다는 것을  나타낸다.

이게 도대체 무슨 이야기냐

인스턴스란 클래스라는 설계도를 갖고 만든 하나의 실질적인 객체를 의미한다.

그러니까 자동차 설계도를 갖고 자동차를 만든다고 치면, 자동차 설계도가 클래스고 자동차 설계도로 만들어진 자동차가 

인스턴스인 것이다.

정리하자면 위의 코드는 SharedPreference라는 설계도로 SharedPreference의 인스턴스라는 자동차를 만들어서 실질적인 사용이 가능하도록 _prefs라는 변수에 담는 과정이라고 할 수 있다.

 

 

_saveUsername

  _saveUsername() {
    setState(() {
      _username = _usernameController.text;
      _prefs.setString("currentUsername", _username);
    });
  }

저장 버튼을 누르면 텍스트 입력창에 있는 텍스트를 가져와서 _username에 저장한 후

_prefs 변수에 저장된 Sharedpreference 인스턴스 내부의 "currentUsername"이라는 키에 _username 변수 안의 내용을 대응시켜 저장한다.

(Sharedpreference는 정보를 Key: value 이런 식으로 대응시켜 저장하는 특성이 있다.)

 

 

 

참고영상

 

https://www.youtube.com/watch?v=6qlmky1xuKY 

 

 

 

반응형