writeFlutterApi method
void
writeFlutterApi(
- SwiftOptions generatorOptions,
- Root root,
- Indent indent,
- Api api, {
- 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);
/// Returns an argument name that can be used in a context where it is possible to collide.
String getEnumSafeArgumentExpression(
Root root, int count, NamedType argument) {
String enumTag = '';
if (argument.type.isEnum) {
enumTag = argument.type.isNullable ? '?.rawValue' : '.rawValue';
}
return '${_getArgumentName(count, argument)}Arg$enumTag';
}
final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty;
if (isCustomCodec) {
_writeCodec(indent, api, root);
}
const List<String> generatedComments = <String>[
' Generated protocol from Pigeon that represents Flutter messages that can be called from Swift.'
];
addDocumentationComments(indent, api.documentationComments, _docCommentSpec,
generatorComments: generatedComments);
indent.addScoped('protocol ${api.name}Protocol {', '}', () {
for (final Method func in api.methods) {
addDocumentationComments(
indent, func.documentationComments, _docCommentSpec);
indent.writeln(_getMethodSignature(func));
}
});
indent.write('class ${api.name}: ${api.name}Protocol ');
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) {
addDocumentationComments(
indent, func.documentationComments, _docCommentSpec);
indent.writeScoped('${_getMethodSignature(func)} {', '}', () {
final Iterable<String> enumSafeArgNames = func.parameters
.asMap()
.entries
.map((MapEntry<int, NamedType> e) =>
getEnumSafeArgumentExpression(root, e.key, e.value));
final String sendArgument = func.parameters.isEmpty
? 'nil'
: '[${enumSafeArgNames.join(', ')}] as [Any?]';
const String channel = 'channel';
indent.writeln(
'let channelName: String = "${makeChannelName(api, func, dartPackageName)}"');
indent.writeln(
'let $channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger$codecArgumentString)');
indent.write('$channel.sendMessage($sendArgument) ');
indent.addScoped('{ response in', '}', () {
indent.writeScoped(
'guard let listResponse = response as? [Any?] else {', '}', () {
indent.writeln(
'completion(.failure(createConnectionError(withChannelName:channelName)))');
indent.writeln('return');
});
indent.writeScoped('if (listResponse.count > 1) {', '} ', () {
indent.writeln('let code: String = listResponse[0] as! String');
indent.writeln(
'let message: String? = nilOrValue(listResponse[1])');
indent.writeln(
'let details: String? = nilOrValue(listResponse[2])');
indent.writeln(
'completion(.failure(FlutterError(code: code, message: message, details: details)));');
}, addTrailingNewline: false);
if (!func.returnType.isNullable && !func.returnType.isVoid) {
indent.addScoped('else if (listResponse[0] == nil) {', '} ', () {
indent.writeln(
'completion(.failure(FlutterError(code: "null-error", message: "Flutter api returned null value for non-null return value.", details: "")))');
}, addTrailingNewline: false);
}
indent.addScoped('else {', '}', () {
if (func.returnType.isVoid) {
indent.writeln('completion(.success(Void()))');
} else {
final String fieldType = _swiftTypeForDartType(func.returnType);
_writeGenericCasting(
indent: indent,
value: 'listResponse[0]',
variableName: 'result',
fieldType: fieldType,
type: func.returnType);
indent.writeln('completion(.success(result))');
}
});
});
});
}
});
}