[Flutter] 하이브를 시도하는 후계자 Isar.

isar | Dart Package


hive의 v2시스템으로서 다른 프로젝트에서 추진하기 위해 저는 실제적으로 isar를 응용 프로그램에 편입하여 사용하고 다양한 방법을 시도하고 싶습니다.

환경 설정

pubspec.yaml에 다음을 추가합니다.
dependencies:
  isar: 2.2.1
  isar_flutter_libs: 2.2.1 # contains the binaries

dev_dependencies:
  isar_generator: 2.2.1
  build_runner: any

user 테이블을 만들어 볼게요.


import 'package:isar/isar.dart';

part 'user.g.dart';

()
class User {
  ()
  int? id;

  late String name;

  String? avatarUri;

  late DateTime createdAt;

  late DateTime updatedAt;
}
build_runner 실행
생성
$ flutter pub run build_runner build
user.g.dart하면 OK.

튀는 화면에서 isar 초기화를 한다고 가정해 보세요.


실제 isar 초기화 장면을 가정하면 이번에는 튀는 화면 디스플레이에서 초기화를 실시하고자 합니다.
우선 추가flutter_native_splashpath_provider 포장이 있다.
dependencies:
  flutter_native_splash: ^2.1.6
  path_provider: ^2.0.9
적당한 아이콘pubspec.yaml을 준비하고 아래 내용을 추가합니다.
flutter_native_splash:
  color: '#ffffff'
  image: 'assets/images/splash.png'
  fullscreen: true
※ 안드로이드 12 대응 등 세부 사항은 생략flutter pub run flutter_native_splash:create 명령을 실행하여 splash 화면을 만듭니다.
ver2.0.3 이후부터 FlutterNativeSplash.remove()까지 부르기 전에 splash 화면이 나올 것 같아서 그걸로 isar의 초기화를 실현하고 싶어요.
main.dart
import 'package:flutter_native_splash/flutter_native_splash.dart';

void main() {
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
  runApp(const MyApp());
}
MyApp에 초기화 + 스파크 화면이 표시되지 않는 처리를 추가합니다.
import 'package:isar/isar.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';

late Isar isar;

class MyApp extends StatelessWidget {
 const MyApp({Key? key}) : super(key: key);

 Future<void> initialize() async {
   final dir = await getApplicationSupportDirectory();

   isar = await Isar.open(
       schemas: [UserSchema],
       directory: dir.path,
       inspector: true);
   FlutterNativeSplash.remove(); // ← スプラッシュを非表示にする
 }

 
 Widget build(BuildContext context) {
   return FutureBuilder(
       future: initialize(),
       builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
         if (snapshot.connectionState == ConnectionState.waiting) {
           return const Center(child: CircularProgressIndicator());
         }
         return MaterialApp(
           title: 'Flutter Demo',
           theme: ThemeData(
             primarySwatch: Colors.blue,
           ),
           home: const MyHomePage(title: 'Flutter Demo Home Page'),
         );
       });
 }
}
이렇게 하면 튀는 화면 뒤에 사용할 수 있다isar.

Riverpod와 함께 사용


나는 실제 있을 수 있는 Riverpod와 조합하여 사용하려는 구상을 추진하고 싶다.
이번에는 isaruser_service.dart와 이용user_repository.dart을 실제로 사용해야 한다.
  • user_service.dart
  • Riverpod의 패밀리를 사용하여 외부 DI isar의 실례를 허용
  • import 'package:hooks_riverpod/hooks_riverpod.dart';
    import 'package:isar/isar.dart';
    import 'package:xxxx/repositories/entities/user.dart';
    
    final ProviderFamily<UserService, Isar> userServiceProvider =
        Provider.family<UserService, Isar>((_, isar) => UserService(isar: isar));
    
    class UserService {
      UserService({required this.isar});
    
      final Isar isar;
    
      Future<User?> find() async {
        return isar.users.where().findFirst(); // 1ユーザーしか登録しない想定
      }
    
      Future<int> add({required String name, String? avatarUri}) async {
        final user = User()
          ..name = name
          ..avatarUri = avatarUri
          ..createdAt = DateTime.now()
          ..updatedAt = DateTime.now();
        return isar.writeTxn((isar) => isar.users.put(user));
      }
    }
    
  • user_repository.dart
  • user_서비스에 맡긴 isar는 튀는 화면에서 초기화 후
  • 에 맡긴다.
    import 'package:hooks_riverpod/hooks_riverpod.dart';
    import 'package:xxxx/app.dart';
    import 'package:xxxx/repositories/entities/user.dart';
    import 'package:xxxx/repositories/services/db/user_service.dart';
    
    final Provider<UserRepository> userRepositoryProvider =
        Provider<UserRepository>(
            (ref) => UserRepository(service: ref.watch(userServiceProvider(isar))));
    
    class UserRepository {
      UserRepository({required this.service});
    
      final UserService service;
    
      Future<User?> find() => service.find();
    
      // ユーザー未登録の場合ユーザー作成
      Future<void> initUser() async {
        final user = await find();
        if (user == null) {
          await service.add(name: 'anonymous');
        }
      }
    }
    
    이후 ref.watch(userRepositoryProvider)로 진행하시면 됩니다.

    Isar Inspector 사용


    isar/README.md at main · isar/isar
    실제 데이터를 참조할 수 있는 Isar Inspector를 사용하고 싶습니다.
    먼저 릴리즈 페이지에서 다운로드Isar.Inspector.zip합니다.Isar.openinspector: true매개변수가 필요하므로 추가inspector: true하고 부팅하면 콘솔에 들어갑니다.
    다음 정보를 표시합니다.

    지정한 URL을 Isar Inspector로 설정하면 볼 수 있습니다.
    ↓ Isar Inspector를 시작하는 모습

    방독 기술

    build_runner 실행 중 다음 오류가 발생했습니다.
    line 1, column 22 of package:xxxx/user.dart: Could not resolve annotation for `class User`.
      ╷
    1 │ @Collection()
      │ ^^^^^^^^^^^^^
      ╵
    
    공식 샘플에 없는import 'package:isar/isar.dart';로 시작하여 보충

    참조 링크

  • Flutter로 일기 앱 만들어요.
  • [Flutter] 초기화가 끝나기 전에 스파크 화면을 보여주고 싶어요[fluter native splash]
  • [Flutter] 지령 한 번에 튀는 화면을 구현할 수 있는 [fluter native splash]
  • 좋은 웹페이지 즐겨찾기