오프라인 상태에서도 앱이 데이터를 저장하고 사용할 수 있게 하는 것은 현대 모바일 애플리케이션에서 중요한 기능입니다. Flutter에서는 다양한 방법을 통해 데이터를 로컬에 저장하고, 네트워크 연결이 없을 때에도 앱이 원활하게 작동할 수 있도록 지원합니다. 이번 글에서는 Flutter에서 오프라인 데이터 저장을 구현하는 방법을 단계별로 설명하겠습니다.
1. Flutter에서 오프라인 데이터 저장 방식
Flutter에서 데이터를 오프라인으로 저장할 때 주로 사용되는 방법은 다음과 같습니다.
- SharedPreferences: 간단한 키-값 형태의 데이터를 저장하는 데 사용.
- SQLite: 관계형 데이터베이스로 구조화된 데이터를 저장하는 데 사용.
- Hive: NoSQL 데이터베이스로 빠르고 경량화된 데이터베이스.
- Moor: SQLite를 기반으로 한 ORM 패키지로, SQL 쿼리를 더 쉽게 사용.
이 글에서는 각 방법의 사용법을 간단히 소개하고, 실제로 어떻게 구현할 수 있는지 살펴보겠습니다.
2. SharedPreferences를 사용한 간단한 데이터 저장
SharedPreferences는 작은 양의 데이터를 저장하는 데 적합한 방법입니다. 주로 설정, 사용자 정보, 앱 상태 등을 저장할 때 사용됩니다.
2.1 SharedPreferences 설치
먼저 pubspec.yaml 파일에 shared_preferences 패키지를 추가합니다.
dependencies:
shared_preferences: ^2.0.8
2.2 SharedPreferences 사용 예제
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<HomeScreen> {
String? savedData = '';
@override
void initState() {
super.initState();
_loadData();
}
Future<void> _loadData() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
savedData = prefs.getString('key') ?? 'No Data';
});
}
Future<void> _saveData(String data) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('key', data);
_loadData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SharedPreferences Example')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Saved Data: $savedData'),
TextField(
onSubmitted: (value) {
_saveData(value);
},
decoration: InputDecoration(labelText: 'Enter data to save'),
),
],
),
);
}
}
위 예제는 사용자가 입력한 값을 SharedPreferences에 저장하고, 저장된 데이터를 다시 불러와 화면에 표시하는 방식입니다.
3. SQLite를 사용한 데이터 저장
SQLite는 구조화된 데이터를 저장하기 위한 관계형 데이터베이스입니다. Flutter에서 SQLite는 sqflite 패키지를 사용하여 관리됩니다.
3.1 SQLite 패키지 설치
pubspec.yaml 파일에 sqflite 패키지를 추가합니다.
dependencies:
sqflite: ^2.0.0+4
path: ^1.8.0 # 경로 관리를 위한 패키지
3.2 SQLite 사용 예제
SQLite 데이터베이스를 생성하고 데이터를 저장 및 불러오는 기본적인 예제입니다.
import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.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<HomeScreen> {
late Database database;
List<Map<String, dynamic>> dataList = [];
@override
void initState() {
super.initState();
_initDatabase();
}
Future<void> _initDatabase() async {
String path = join(await getDatabasesPath(), 'example.db');
database = await openDatabase(
path,
onCreate: (db, version) {
return db.execute(
'CREATE TABLE items(id INTEGER PRIMARY KEY, name TEXT)',
);
},
version: 1,
);
_loadData();
}
Future<void> _loadData() async {
final List<Map<String, dynamic>> maps = await database.query('items');
setState(() {
dataList = maps;
});
}
Future<void> _insertData(String name) async {
await database.insert(
'items',
{'name': name},
conflictAlgorithm: ConflictAlgorithm.replace,
);
_loadData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SQLite Example')),
body: Column(
children: [
TextField(
onSubmitted: (value) {
_insertData(value);
},
decoration: InputDecoration(labelText: 'Enter item to add'),
),
Expanded(
child: ListView.builder(
itemCount: dataList.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(dataList[index]['name']),
);
},
),
),
],
),
);
}
}
위 예제는 SQLite 데이터베이스에 아이템을 저장하고, 저장된 아이템을 불러와 리스트에 표시하는 방식입니다.
4. Hive를 사용한 데이터 저장
Hive는 Flutter에서 많이 사용되는 NoSQL 데이터베이스입니다. 경량화된 데이터베이스로 빠르고 사용이 간편해, 많은 개발자들이 선호합니다.
4.1 Hive 패키지 설치
pubspec.yaml 파일에 hive 및 hive_flutter 패키지를 추가합니다.
dependencies:
hive: ^2.0.4
hive_flutter: ^1.1.0
4.2 Hive 사용 예제
Hive를 사용하여 데이터를 저장하고 불러오는 기본적인 예제입니다.
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
void main() async {
await Hive.initFlutter();
await Hive.openBox('myBox');
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<HomeScreen> {
final myBox = Hive.box('myBox');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Hive Example')),
body: Column(
children: [
TextField(
onSubmitted: (value) {
myBox.put('name', value);
setState(() {});
},
decoration: InputDecoration(labelText: 'Enter name'),
),
SizedBox(height: 20),
Text('Saved Name: ${myBox.get('name', defaultValue: 'No Name')}'),
],
),
);
}
}
위 예제는 Hive를 사용해 간단한 데이터를 저장하고 불러오는 방식입니다. 사용자가 입력한 데이터를 로컬 데이터베이스에 저장하고, 저장된 데이터를 화면에 표시합니다.
5. Moor를 사용한 SQLite 관리
Moor는 SQLite 기반의 ORM 패키지로, SQL 쿼리를 더 쉽게 관리할 수 있도록 도와줍니다.
5.1 Moor 패키지 설치
pubspec.yaml 파일에 moor 및 moor_flutter 패키지를 추가합니다.
dependencies:
moor: ^4.5.0
moor_flutter: ^4.0.0
5.2 Moor 사용 예제
Moor를 사용하여 SQLite를 간편하게 관리할 수 있는 기본적인 예제입니다.
import 'package:flutter/material.dart';
import 'package:moor_flutter/moor_flutter.dart';
part 'database.g.dart';
@DataClassName('Task')
class Tasks extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text().withLength(min: 1, max: 50)();
}
@UseMoor(tables: [Tasks])
class AppDatabase extends _$AppDatabase {
AppDatabase()
: super(FlutterQueryExecutor.inDatabaseFolder(path: 'db.sqlite'));
@override
int get schemaVersion => 1;
Future<List<Task>> getAllTasks() => select(tasks).get();
Future insertTask(Insertable<Task> task) => into(tasks).insert(task);
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final AppDatabase database = AppDatabase();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(database: database),
);
}
}
class HomeScreen extends StatelessWidget {
final AppDatabase database;
HomeScreen({required this.database});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Moor Example')),
body: FutureBuilder<List<Task>>(
future: database.getAllTasks(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
}
final tasks = snapshot.data!;
return ListView.builder(
itemCount: tasks.length,
itemBuilder: (context, index) {
return ListTile(title: Text(tasks[index].name));
},
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
database.insertTask(TasksCompanion(name: Value('New Task')));
},
child: Icon(Icons.add),
),
);
}
}
위 예제에서는 Moor를 사용하여 데이터베이스를 쉽게 관리하는 방법을 보여줍니다. Moor는 SQLite의 복잡한 SQL 쿼리들을 간편하게 처리할 수 있는 좋은 도구입니다.
결론
Flutter에서 오프라인 데이터를 저장하는 방법은 다양하며, 앱의 요구 사항에 맞춰 적절한 저장 방식을 선택할 수 있습니다. SharedPreferences는 간단한 데이터를 저장하는 데 유용하고, SQLite와 Moor는 구조화된 데이터를 다룰 때 유용합니다. Hive는 빠르고 경량화된 NoSQL 데이터베이스로 적합합니다. 이 글에서 소개한 방법들을 활용하여 오프라인에서도 잘 작동하는 Flutter 애플리케이션을 구현해보세요.
'Flutter' 카테고리의 다른 글
Flutter의 데이터 동기화(Data Synchronization) 사용법 (0) | 2025.01.28 |
---|---|
Flutter의 네트워크 이미지(Network Image) 사용법 (0) | 2025.01.27 |
Flutter의 이미지 캐싱(Image Caching) 사용법 (0) | 2025.01.27 |
Flutter의 커스텀 아이콘(Custom Icons) 사용법 (1) | 2025.01.26 |
Flutter의 폰트 커스터마이징(Font Customization) 사용법 (1) | 2025.01.25 |