Flutter SDK 4.2 migration guide

Nutrient Flutter SDK 4.2 introduces significant improvements to annotation handling with the introduction of Dart model classes, providing a more type-safe and intuitive way to work with annotations. This guide will help you migrate your existing code to take advantage of these new capabilities.

Updating to Nutrient Flutter SDK 4.2

To update your project to Nutrient Flutter SDK 4.2, update your pubspec.yaml file:

dependencies:
   pspdfkit_flutter: ^4.2.0

Run flutter pub get to install the latest version.

Annotation model classes

The most significant change in version 4.2 is the introduction of Dart model classes for annotations. These classes replace the previous JSON-based approach and provide a more structured way to work with annotations.

Key benefits

  • Type safety — Model classes provide type checking at compile time, reducing runtime errors.

  • Better IDE support — Enjoy code completion and documentation for annotation properties.

  • Simplified API — Work with annotations using native Dart objects instead of raw JSON.

  • Serialization support — All annotation model classes can be serialized to and deserialized from JSON.

API changes

Read the following sections to learn more about API changes in Nutrient Flutter SDK 4.2.

Annotation methods

This section details which annotation methods were changed.

addAnnotation and removeAnnotation

The addAnnotation and removeAnnotation methods now accept both model classes and plain JSON, providing backward compatibility, while encouraging migration to model classes.

Before:

// Using JSON only.
await pdfDocument.addAnnotation({
  'type': 'pspdfkit/ink',
  'bbox': [89.0, 98.0, 143.0, 207.0],
  'lines': [[[92.0, 159.0], [95.0, 155.0]]],
  'pageIndex': 0
});

After:

// Using model class.
// Create an ink annotation with drawing points.
final inkAnnotation =  InkAnnotation(
      id: 'ink-annotation-1',
      bbox: [267.4, 335.1, 97.2, 10.3],
      createdAt: '2025-01-06T16:36:59+03:00',
      lines: InkLines(
        points: [
          [
            [269.4, 343.4],
            [308.4, 341.7],
            [341.2, 339.6],
            [358.8, 339.6],
            [360.9, 339.2],
            [362.6, 338.8],
            [361.7, 337.1],
          ]
        ],
        intensities: [
          [1.0, 0.43, 0.64, 0.83, 0.98, 0.99, 0.97]
        ],
      ),
      pageIndex: 0
		// ...other fields.
	);

await pdfDocument.addAnnotation(inkAnnotation);

// Still supports JSON for backward compatibility.
await pdfDocument.addAnnotation({
  'type': 'pspdfkit/ink',
  'bbox': [89.0, 98.0, 143.0, 207.0],
  'lines': [[[92.0, 159.0], [95.0, 155.0]]],
  'pageIndex': 0
   //...other fields
});

A new method has been added to simplify updating existing annotations:

// Get an annotation.
final annotations = await pdfDocument.getAnnotations(pageIndex: 0);
final annotation = annotations.first;

// Modify it.
if (annotation is InkAnnotation) {
  annotation.copyWith(
	  strokeColor: Color.red
  )
}

// Update it.
await pdfDocument.updateAnnotation(annotation);

getAnnotations

The getAnnotations method now returns a list of model classes instead of JSON objects.

Before:

final annotations = await pdfDocument.getAnnotations( 0, "all");
// annotations is List<Map<String, dynamic>>
final type = annotations[0]['type'];

After:

var pageIndex  = 0;
final annotations = await pdfDocument.getAnnotations(pageIndex, AnnotationType.all);
// annotations is List<Annotation>
final type = annotations[0].type;

// You can use type checking.
if (annotations[0] is InkAnnotation) {
  final inkAnnotation = annotations[0] as InkAnnotation;
  final lines = inkAnnotation.lines;
}

getUnsavedAnnotations

The getUnsavedAnnotations method now returns a list of model classes instead of JSON objects.

To get annotations as JSON

If you still need to work with JSON representations, use the following code:

// Get annotations as model classes.
final annotations = await pdfDocument.getAnnotations(pageIndex: 0);

// Get annotations as JSON.
final annotationsJson = await pdfDocument.getAnnotationsAsJSON(pageIndex: 0);

getAllUnsavedAnnotations

The getAllUnsavedAnnotations method has been deprecated in favor of getUnsavedAnnotations. It still works, but it’ll be removed in a future release.

Event listeners

Annotation-related event listeners now use model classes instead of plain JSON.

Before:

pdfDocument.addEventListener(PdfDocumentEvent.annotationChanged, (data) {
  final annotationJson = data['annotation'];
  print('Annotation changed: ${annotationJson['type']}');
});

After:

pdfDocument.addEventListener(PdfDocumentEvent.annotationChanged, (data) {
  final annotation = data['annotation'] as Annotation;
  print('Annotation changed: ${annotation.type}');

  // Type checking.
  if (annotation is InkAnnotation) {
    print('Ink annotation lines: ${annotation.lines}');
  }
});

Migrating step by step

  1. Update your pubspec.yaml to use version 4.2.0 or later.

  2. Import the new model classes where you work with annotations.

  3. Update your code to use model classes instead of JSON objects.

  4. Test your application thoroughly, especially annotation-related functionality.

Backward compatibility

To ease migration, many methods accept both model classes and JSON objects. However, we recommend transitioning to model classes for better type safety and code maintainability.

Changelog

For a complete list of changes in Nutrient Flutter SDK 4.2, see the changelog.