Home > Back-end >  How to create Hive adapter for XFile class
How to create Hive adapter for XFile class

Time:10-28

I'm trying to store custom object that has variable storing list of XFile's; cross platform image representation from package called image_picker version 0.8.4 3. When writing an error occurs saying that im missing Adapter for XFile which is understandable, but I'm having hard time deciding how to declare such Adapter for external source file class.

This is my Receipt class that has some list of XFile's.

Note: I've removed nonmeaningful variables from snippet.

@HiveType(typeId: 0)
class Receipt extends HiveObject with EquatableMixin {
  Receipt({
    List<XFile>? files,
  }) {
    this.files = files ?? <XFile>[];
  }

  @HiveField(6)
  late final List<XFile> files;

  @override
  List<Object?> get props => [
        files,
      ];
}

Now I was thinking about two possible solutions; one - copy whole source code from XFile, add HiveType and HiveField decorators and generate adapter from that or two - create class that will extend from XFile and add decorators something like this:

@HiveType(typeId: 1)
class XFileAdapter extends XFile with HiveObjectMixin {
    // access fields and add decorators here 
}

but I have no clue how to add decorators to these field without overriding every one of them. And even if I knew how to do that, it turns out that XFile's doesn't have its own variables I've could add Hive decorators to, it simply takes paramethers and passes them down to XFileBase class since it further decides what to do with them.

Very similar question has been asked in this thread but the only aswer suggests creating new class from scratch that imitates source class which is not solution to my problem.

CodePudding user response:

I think creating a new MyXFile class as you suggested might be the way to go. But as you've said you will need to override the properties you want to keep in hive. This code seems to be working as intended:

Code

import 'dart:typed_data';

import 'package:image_picker/image_picker.dart';
import 'package:hive_flutter/adapters.dart';

part 'my_xfile.g.dart';

@HiveType(typeId: 1)
class MyXFile extends XFile {
  @override
  @HiveField(1)
  final String path;

  @override
  @HiveField(2)
  final String? mimeType;

  @HiveField(3)
  final String? _name;

  /// The base implementation of `XFileBase.name` throws an
  /// [UnimplementedError] so we are overriding it to return a known
  /// [_name] value.
  @override
  String get name {
    if (_name != null) {
      return _name!;
    }
    return super.name;
  }

  @HiveField(4)
  final int? _length;

  /// The base implementation of `XFileBase.length()` throws an
  /// [UnimplementedError] so we are overriding it to return a known
  /// [_length] value.
  @override
  Future<int> length() {
    return _length != null ? Future.value(_length!) : super.length();
  }

  @HiveField(5)
  final Uint8List? bytes;

  @HiveField(6)
  final DateTime? _lastModified;

  /// The base implementation of `XFileBase.lastModified()` throws an
  /// [UnimplementedError] so we are overriding it to return a known
  /// [_lastModified] value.
  @override
  Future<DateTime> lastModified() {
    return _lastModified != null
        ? Future.value(_lastModified!)
        : super.lastModified();
  }

  MyXFile(
    this.path, {
    this.mimeType,
    String? name,
    int? length,
    this.bytes,
    DateTime? lastModified,
  })  : _name = name,
        _length = length,
        _lastModified = lastModified,
        super(
          path,
          mimeType: mimeType,
          name: name,
          length: length,
          bytes: bytes,
          lastModified: lastModified,
        );
}

By using this I've been able to save and retrieve my object MyXFile and as it is extending XFile you should be able to use it the same way.

Then instead of having a List<XFile>? files in your Receipt class you will need a List<MyXFile>? files.

  • Related