from static method

SmartPosterRecord? from(
  1. NdefRecord record
)

Reads record as a smart poster, or returns null when it is not one or is malformed.

Implementation

static SmartPosterRecord? from(NdefRecord record) {
  if (record.typeNameFormat != NdefTypeNameFormat.wellKnown) return null;
  if (!_bytesEqual(record.type, NdefRecord.wellKnownTypeSmartPoster)) return null;

  final NdefMessage nested;
  try {
    nested = NdefMessage.fromBytes(record.payload);
  } on FormatException {
    return null;
  }

  Uri? uri;
  var sawWellKnownUri = false;
  final titles = <String, String>{};
  SmartPosterAction? action;
  ({String mimeType, Uint8List data})? icon;

  for (final inner in nested.records) {
    final asUri = UriRecord.from(inner);
    if (asUri != null) {
      // The poster's destination is its well-known `U` record; an absolute-URI record is a
      // fallback and never displaces one. Taking whichever came first let a leading
      // absolute-URI record shadow and discard the tag's real destination.
      final isWellKnownUri =
          inner.typeNameFormat == NdefTypeNameFormat.wellKnown &&
          _bytesEqual(inner.type, NdefRecord.wellKnownTypeUri);
      if (uri == null || (isWellKnownUri && !sawWellKnownUri)) {
        uri = asUri.uri;
        sawWellKnownUri = isWellKnownUri;
      }
      continue;
    }

    final asText = TextRecord.from(inner);
    if (asText != null) {
      titles[asText.languageCode] = asText.text;
      continue;
    }

    if (inner.typeNameFormat == NdefTypeNameFormat.wellKnown &&
        _bytesEqual(inner.type, Uint8List.fromList(ascii.encode('act'))) &&
        inner.payload.length == 1 &&
        inner.payload[0] < SmartPosterAction.values.length) {
      action = SmartPosterAction.values[inner.payload[0]];
      continue;
    }

    final asMime = MimeRecord.from(inner);
    if (asMime != null && icon == null && asMime.mimeType.startsWith('image/')) {
      icon = (mimeType: asMime.mimeType, data: asMime.data);
    }
  }

  // The URI is the one mandatory part; without it this is not a usable poster.
  if (uri == null) return null;
  return SmartPosterRecord._(uri: uri, titles: titles, action: action, icon: icon);
}