플러터 shared preferences 패키지 사용법 (로컬에 데이터 저장하기)

소요 시간: 10분

shared_preferences라는 패키지를 사용했는데, 이 패키지가 꽤 유용하다는 생각이 들었다. 복잡한 데이터베이스를 사용하지 않고도 앱의 설정이나 사용자 정보를 로컬에 저장할 수 있다는 점이 매력적이었다.


1. 패키지 설치

먼저, 이 패키지를 사용하려면 pubspec.yaml 파일에 shared_preferences를 추가해야 했다. 아래와 같이 작성했다.

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.0.9  # 최신 버전으로 추가

이후 터미널에서 flutter pub get을 실행하여 패키지를 다운로드했다. 간단한 설정이지만, 이 과정이 없으면 나중에 코드를 작성할 수 없으니 중요한 단계였다.


2. SharedPreferences 기본 사용법

가장 먼저 이해한 부분은 SharedPreferences 인스턴스를 얻는 방법이었다. SharedPreferences.getInstance()를 호출하면 인스턴스를 가져올 수 있는데, 비동기로 동작하기 때문에 await 키워드가 필요했다.

final prefs = await SharedPreferences.getInstance();

이 인스턴스를 통해 데이터를 저장하고 불러올 수 있다는 점이 매우 중요했다.


3. 데이터 저장하기

SharedPreferences에서는 여러 타입의 값을 저장할 수 있다. 다음과 같이 다양한 데이터를 저장할 수 있었다:

예를 들어, 사용자의 이름, 나이, 로그인 상태를 저장하는 코드는 다음과 같다:

Future saveData() async {
  final prefs = await SharedPreferences.getInstance();

  // 데이터 저장
  await prefs.setString('username', 'flutter_user');  // 문자열 저장
  await prefs.setInt('userAge', 25);  // 정수 저장
  await prefs.setBool('isLoggedIn', true);  // 부울값 저장
  await prefs.setDouble('userHeight', 5.9);  // 실수 저장
  await prefs.setStringList('favorites', ['apple', 'banana', 'orange']);  // 문자열 리스트 저장
}


4. 데이터 불러오기

저장된 데이터를 불러올 때는 저장한 데이터의 타입에 맞는 메서드를 사용해야 한다. 예를 들어:

Future loadData() async {
  final prefs = await SharedPreferences.getInstance();

  // 저장된 데이터 불러오기
  String? username = prefs.getString('username');  // 문자열 읽기
  int? userAge = prefs.getInt('userAge');  // 정수 읽기
  bool? isLoggedIn = prefs.getBool('isLoggedIn');  // 부울값 읽기
  double? userHeight = prefs.getDouble('userHeight');  // 실수 읽기
  List? favorites = prefs.getStringList('favorites');  // 문자열 리스트 읽기

  print('Username: $username');
  print('User age: $userAge');
  print('Is logged in: $isLoggedIn');
  print('User height: $userHeight');
  print('Favorite fruits: $favorites');
}

데이터를 불러올 때는 null이 반환될 수 있으니 기본값을 설정하거나 null 처리를 할 방법이 필요했다.


5. 데이터 삭제하기

저장된 데이터를 삭제할 때는 remove() 메서드를 사용한다. 특정 키에 해당하는 데이터를 삭제하는 방법은 다음과 같다:

Future removeData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.remove('username');  // 'username'에 해당하는 데이터 삭제
}

앱 내 모든 데이터를 한꺼번에 삭제하고 싶다면 clear() 메서드를 사용한다:

Future clearAllData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.clear();  // 모든 데이터 삭제
}


6. 간단한 예제 만들기

오늘 배운 내용을 바탕으로 간단한 예제를 만들어 보았다. 이 앱은 사용자가 로그인했는지 확인하고, 로그인하지 않았으면 버튼을 눌러 로그인할 수 있도록 구성했다. 사용자가 로그인하면 이름과 로그인 상태가 SharedPreferences에 저장된다. 아래는 그 코드다:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State {
  String? _username;
  bool? _isLoggedIn;

  @override
  void initState() {
    super.initState();
    _loadUserData();  // 앱 시작 시 저장된 데이터 불러오기
  }

  // 데이터 불러오기
  Future _loadUserData() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      _username = prefs.getString('username');
      _isLoggedIn = prefs.getBool('isLoggedIn') ?? false;  // 기본값 설정
    });
  }

  // 데이터 저장하기
  Future _saveUserData() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('username', 'flutter_user');
    await prefs.setBool('isLoggedIn', true);
    setState(() {
      _username = 'flutter_user';
      _isLoggedIn = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Shared Preferences Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              _isLoggedIn == true
                ? 'Welcome, $_username'
                : 'Please log in.',
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _saveUserData,
              child: Text('Log In'),
            ),
          ],
        ),
      ),
    );
  }
}

이 앱을 실행하면 처음에는 "Please log in."이라는 메시지가 나타난다. 로그인을 클릭하면 "Welcome, flutter_user" 메시지가 나타나고, 앱을 종료했다가 다시 실행해도 로그인이 유지된다. 이렇게 SharedPreferences를 통해 상태를 관리할 수 있다는 점이 매우 흥미로웠다.


7. 한계와 보안

마지막으로, 오늘 배운 shared_preferences의 한계에 대해서도 생각해보았다. 이 패키지는 소량의 데이터를 저장하는 데 적합하지만, 복잡한 구조나 대규모 데이터를 다루기에는 적합하지 않았다. 특히, 보안이 민감한 정보(비밀번호나 개인 데이터)는 안전한 저장소를 사용해야 한다는 점을 유념해야겠다.

오늘 배운 내용이 유용했기 때문에, 앞으로 앱 개발할 때 shared_preferences를 활용할 수 있을 것 같다. 데이터 저장과 관리를 간편하게 해주는 이 패키지는 분명히 많은 도움이 될 것이다!

플러터 리스트