[flutter] 플러터(Flutter)에서 오프라인 동기화 기능 구현하기

플러터(Flutter)는 크로스 플랫폼 모바일 앱 개발을 위한 프레임워크로, 많은 개발자들에게 인기를 끌고 있습니다. 온라인 상태가 아닐 때 앱 사용을 지원하는 오프라인 동기화 기능은 사용자 경험을 향상시키는 중요한 기능입니다. 이번 개발자 블로그에서는 플러터에서 오프라인 동기화 기능을 구현하는 방법을 알아보겠습니다.

1. 네트워크 상태 확인

오프라인 동기화를 구현하기 전에 사용자의 네트워크 상태를 확인해야 합니다. 플러터에서는 connectivity 패키지를 사용하여 네트워크 상태를 감지할 수 있습니다. 앱의 pubspec.yaml 파일에 connectivity 패키지를 추가해 주세요.

dependencies:
  flutter:
    sdk: flutter
  connectivity: ^0.4.9+2

이제 connectivity 패키지를 사용하여 네트워크 상태를 확인하는 코드를 작성해 보겠습니다.

import 'package:connectivity/connectivity.dart';

Future<bool> checkInternetConnection() async {
  var connectivityResult = await (Connectivity().checkConnectivity());
  if (connectivityResult == ConnectivityResult.none) {
    return false;
  }
  return true;
}

위 코드는 checkInternetConnection() 함수를 통해 현재 네트워크 상태를 확인합니다. 결과가 ConnectivityResult.none인 경우에는 네트워크가 연결되어 있지 않음을 나타냅니다.

2. 로컬 데이터베이스 사용하기

플러터에서 오프라인 동기화를 구현하기 위해 로컬 데이터베이스를 사용할 수 있습니다. 가장 많이 사용되는 로컬 데이터베이스 중 하나는 sqflite 패키지입니다. sqflite 패키지를 사용하기 위해 pubspec.yaml 파일에 추가해 주세요.

dependencies:
  flutter:
    sdk: flutter
  sqflite: any

데이터베이스 테이블을 생성하고 데이터를 저장하고 검색하는 코드를 작성해 보겠습니다.

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class DBHelper {
  static final String _databaseName = "my_database.db";
  static final int _databaseVersion = 1;
  static final String _tableName = "my_table";

  static Database _database;

  Future<Database> get database async {
    if (_database != null) return _database;

    _database = await initializeDatabase();
    return _database;
  }

  Future<Database> initializeDatabase() async {
    String databasesPath = await getDatabasesPath();
    String path = join(databasesPath, _databaseName);

    return await openDatabase(
      path,
      version: _databaseVersion,
      onCreate: _onCreate,
    );
  }

  Future<void> _onCreate(Database db, int version) async {
    await db.execute(
      "CREATE TABLE $_tableName ("
      "id INTEGER PRIMARY KEY AUTOINCREMENT,"
      "data TEXT,"
      "timestamp INTEGER"
      ")",
    );
  }

  Future<void> saveData(String data) async {
    final db = await database;
    int timestamp = DateTime.now().millisecondsSinceEpoch;
    await db.insert(
      _tableName,
      {
        "data": data,
        "timestamp": timestamp,
      },
      conflictAlgorithm: ConflictAlgorithm.replace,
    );
  }

  Future<List<Map<String, dynamic>>> getData() async {
    final db = await database;
    return await db.query(_tableName);
  }
}

위 코드는 DBHelper 클래스를 통해 데이터베이스를 초기화하고 테이블을 생성하며 데이터를 저장하고 검색할 수 있습니다. 데이터는 saveData() 함수를 사용하여 저장되며, getData() 함수를 사용하여 검색할 수 있습니다.

3. 오프라인 동기화 기능 구현하기

이제 네트워크 상태도 확인하고 로컬 데이터베이스도 설정했으므로, 오프라인 동기화 기능을 구현할 수 있습니다. 일단 오프라인인 경우 데이터를 로컬 데이터베이스에 저장하고, 온라인 상태일 때 로컬 데이터베이스의 데이터를 서버로 동기화하는 방식을 사용해 보겠습니다.

import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  DBHelper _dbHelper = DBHelper();
  List<String> _dataList = [];

  @override
  void initState() {
    super.initState();
    checkSync();
  }

  Future<void> checkSync() async {
    bool isConnected = await checkInternetConnection();
    if (isConnected) {
      syncData();
    } else {
      getDataFromLocal();
    }
  }

  Future<void> syncData() async {
    List<Map<String, dynamic>> data = await _dbHelper.getData();
    // 서버로 데이터 동기화하는 로직 구현
  }

  Future<void> getDataFromLocal() async {
    List<Map<String, dynamic>> data = await _dbHelper.getData();
    setState(() {
      _dataList = data.map((item) => item['data']).toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: _dataList.length,
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text(_dataList[index]),
        );
      },
    );
  }
}

위 코드는 MyWidget 클래스에서 상태를 관리하며, 초기 상태에서 오프라인 동기화를 확인하여 오프라인인 경우 로컬 데이터베이스에서 데이터를 가져오고, 온라인인 경우 서버로 데이터를 동기화합니다. 가져온 데이터는 ListView.builder 위젯을 사용하여 보여줍니다.

결론

이상으로 플러터(Flutter)에서 오프라인 동기화 기능을 구현하는 방법을 알아보았습니다. 네트워크 상태 확인, 로컬 데이터베이스 사용 등을 통해 사용자 경험을 향상시킬 수 있는 오프라인 동기화 기능을 구현해 보세요.

더 자세한 내용은 Flutter 공식 문서를 참조하시기 바랍니다.