writeFlutterApi method

  1. @override
void writeFlutterApi(
  1. SwiftOptions generatorOptions,
  2. Root root,
  3. Indent indent,
  4. Api api, {
  5. required String dartPackageName,
})
override

Writes the code for a flutter Api, api. Example: class Foo { private let binaryMessenger: FlutterBinaryMessenger init(binaryMessenger: FlutterBinaryMessenger) {...} func add(x: Int32, y: Int32, completion: @escaping (Int32?) -> Void) {...} }

Implementation

@override
void writeFlutterApi(
  SwiftOptions generatorOptions,
  Root root,
  Indent indent,
  Api api, {
  required String dartPackageName,
}) {
  assert(api.location == ApiLocation.flutter);
  final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty;
  if (isCustomCodec) {
    _writeCodec(indent, api, root);
  }
  const List<String> generatedComments = <String>[
    ' Generated class from Pigeon that represents Flutter messages that can be called from Swift.'
  ];
  addDocumentationComments(indent, api.documentationComments, _docCommentSpec,
      generatorComments: generatedComments);

  indent.write('class ${api.name} ');
  indent.addScoped('{', '}', () {
    indent.writeln('private let binaryMessenger: FlutterBinaryMessenger');
    indent.write('init(binaryMessenger: FlutterBinaryMessenger)');
    indent.addScoped('{', '}', () {
      indent.writeln('self.binaryMessenger = binaryMessenger');
    });
    final String codecName = _getCodecName(api);
    String codecArgumentString = '';
    if (getCodecClasses(api, root).isNotEmpty) {
      codecArgumentString = ', codec: codec';
      indent.write('var codec: FlutterStandardMessageCodec ');
      indent.addScoped('{', '}', () {
        indent.writeln('return $codecName.shared');
      });
    }
    for (final Method func in api.methods) {
      final _SwiftFunctionComponents components =
          _SwiftFunctionComponents.fromMethod(func);

      final String channelName = makeChannelName(api, func, dartPackageName);
      final String returnType = func.returnType.isVoid
          ? ''
          : _nullsafeSwiftTypeForDartType(func.returnType);
      String sendArgument;
      addDocumentationComments(
          indent, func.documentationComments, _docCommentSpec);

      if (func.arguments.isEmpty) {
        indent.write(
            'func ${func.name}(completion: @escaping ($returnType) -> Void) ');
        sendArgument = 'nil';
      } else {
        final Iterable<String> argTypes = func.arguments
            .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type));
        final Iterable<String> argLabels = indexMap(components.arguments,
            (int index, _SwiftFunctionArgument argument) {
          return argument.label ??
              _getArgumentName(index, argument.namedType);
        });
        final Iterable<String> argNames =
            indexMap(func.arguments, _getSafeArgumentName);
        sendArgument = '[${argNames.join(', ')}] as [Any?]';
        final String argsSignature = map3(
            argTypes,
            argLabels,
            argNames,
            (String type, String label, String name) =>
                '$label $name: $type').join(', ');
        if (func.returnType.isVoid) {
          indent.write(
              'func ${components.name}($argsSignature, completion: @escaping () -> Void) ');
        } else {
          indent.write(
              'func ${components.name}($argsSignature, completion: @escaping ($returnType) -> Void) ');
        }
      }
      indent.addScoped('{', '}', () {
        const String channel = 'channel';
        indent.writeln(
            'let $channel = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger$codecArgumentString)');
        indent.write('$channel.sendMessage($sendArgument) ');
        if (func.returnType.isVoid) {
          indent.addScoped('{ _ in', '}', () {
            indent.writeln('completion()');
          });
        } else {
          indent.addScoped('{ response in', '}', () {
            _writeDecodeCasting(
              root: root,
              indent: indent,
              value: 'response',
              variableName: 'result',
              type: func.returnType,
            );
            indent.writeln('completion(result)');
          });
        }
      });
    }
  });
}