diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index a1cf6d0f1e3..daab8da8bcb 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 12.0.1 + +* [swift] Adds protocol for Flutter APIs. + ## 12.0.0 * Adds error handling on Flutter API methods. diff --git a/packages/pigeon/example/app/ios/Runner/Messages.g.swift b/packages/pigeon/example/app/ios/Runner/Messages.g.swift index 3c0433a7425..ef38ee5849c 100644 --- a/packages/pigeon/example/app/ios/Runner/Messages.g.swift +++ b/packages/pigeon/example/app/ios/Runner/Messages.g.swift @@ -173,13 +173,16 @@ class ExampleHostApiSetup { } } } -/// Generated class from Pigeon that represents Flutter messages that can be called from Swift. -class MessageFlutterApi { +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol MessageFlutterApiProtocol { + func flutterMethod(aString aStringArg: String?, completion: @escaping (Result) -> Void) +} +class MessageFlutterApi: MessageFlutterApiProtocol { private let binaryMessenger: FlutterBinaryMessenger init(binaryMessenger: FlutterBinaryMessenger){ self.binaryMessenger = binaryMessenger } - func flutterMethod(aString aStringArg: String?, completion: @escaping (Result) -> Void) { + func flutterMethod(aString aStringArg: String?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_example_package.MessageFlutterApi.flutterMethod", binaryMessenger: binaryMessenger) channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 3dfd1141bc8..c2d2bfad607 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -13,7 +13,7 @@ import 'ast.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '12.0.0'; +const String pigeonVersion = '12.0.1'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index d558c877b2b..af96efd0205 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -291,13 +291,22 @@ import FlutterMacOS if (isCustomCodec) { _writeCodec(indent, api, root); } + const List generatedComments = [ - ' Generated class from Pigeon that represents Flutter messages that can be called from Swift.' + ' Generated protocol 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('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)'); @@ -314,47 +323,19 @@ import FlutterMacOS }); } 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 - ? 'Void' - : _nullsafeSwiftTypeForDartType(func.returnType); - String sendArgument; + addDocumentationComments( indent, func.documentationComments, _docCommentSpec); - - if (func.arguments.isEmpty) { - indent.write( - 'func ${func.name}(completion: @escaping (Result<$returnType, FlutterError>) -> Void) '); - sendArgument = 'nil'; - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); - final Iterable argLabels = indexMap(components.arguments, - (int index, _SwiftFunctionArgument argument) { - return argument.label ?? - _getArgumentName(index, argument.namedType); - }); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); + indent.writeScoped('${_getMethodSignature(func)} {', '}', () { final Iterable enumSafeArgNames = func.arguments .asMap() .entries .map((MapEntry e) => getEnumSafeArgumentExpression(root, e.key, e.value)); - sendArgument = '[${enumSafeArgNames.join(', ')}] as [Any?]'; - final String argsSignature = map3( - argTypes, - argLabels, - argNames, - (String type, String label, String name) => - '$label $name: $type').join(', '); - indent.write( - 'func ${components.name}($argsSignature, completion: @escaping (Result<$returnType, FlutterError>) -> Void) '); - } - indent.addScoped('{', '}', () { + final String sendArgument = func.arguments.isEmpty + ? 'nil' + : '[${enumSafeArgNames.join(', ')}] as [Any?]'; const String channel = 'channel'; indent.writeln( 'let $channel = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger$codecArgumentString)'); @@ -893,6 +874,31 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { return '${_swiftTypeForDartType(type)}$nullSafe'; } +String _getMethodSignature(Method func) { + final _SwiftFunctionComponents components = + _SwiftFunctionComponents.fromMethod(func); + final String returnType = func.returnType.isVoid + ? 'Void' + : _nullsafeSwiftTypeForDartType(func.returnType); + + if (func.arguments.isEmpty) { + return 'func ${func.name}(completion: @escaping (Result<$returnType, FlutterError>) -> Void) '; + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); + final Iterable argLabels = indexMap(components.arguments, + (int index, _SwiftFunctionArgument argument) { + return argument.label ?? _getArgumentName(index, argument.namedType); + }); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + final String argsSignature = map3(argTypes, argLabels, argNames, + (String type, String label, String name) => '$label $name: $type') + .join(', '); + return 'func ${components.name}($argsSignature, completion: @escaping (Result<$returnType, FlutterError>) -> Void) '; + } +} + /// A class that represents a Swift function argument. /// /// The [name] is the name of the argument. diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index ffe94ace2d3..2f5ef13732b 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -661,6 +661,10 @@ abstract class FlutterSmallApi { @ObjCSelector('echoWrappedList:') @SwiftFunction('echo(_:)') TestMessage echoWrappedList(TestMessage msg); + + @ObjCSelector('echoString:') + @SwiftFunction('echo(_:)') + String echoString(String aString); } /// A data class containing a List, used in unit tests. diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index 2eaaa7c3594..f23d543647d 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -4390,5 +4390,41 @@ public void echoWrappedList(@NonNull TestMessage msgArg, @NonNull Result result) { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString", + getCodec()); + channel.send( + new ArrayList(Collections.singletonList(aStringArg)), + channelReply -> { + if (channelReply instanceof List) { + List listReply = (List) channelReply; + if (listReply.size() > 1) { + result.error( + new FlutterError( + (String) listReply.get(0), + (String) listReply.get(1), + (String) listReply.get(2))); + } else if (listReply.get(0) == null) { + result.error( + new FlutterError( + "null-error", + "Flutter api returned null value for non-null return value.", + "")); + } else { + @SuppressWarnings("ConstantConditions") + String output = (String) listReply.get(0); + result.success(output); + } + } else { + result.error( + new FlutterError( + "channel-error", "Unable to establish connection on channel.", "")); + } + }); + } } } diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index d2fac067fea..f330fc4c68f 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -494,6 +494,8 @@ NSObject *FlutterSmallApiGetCodec(void); - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; - (void)echoWrappedList:(TestMessage *)msg completion:(void (^)(TestMessage *_Nullable, FlutterError *_Nullable))completion; +- (void)echoString:(NSString *)aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; @end NS_ASSUME_NONNULL_END diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index 634c3e5503b..60bcbb34651 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -2971,4 +2971,30 @@ - (void)echoWrappedList:(TestMessage *)arg_msg } }]; } +- (void)echoString:(NSString *)arg_aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { + FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel + messageChannelWithName: + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString" + binaryMessenger:self.binaryMessenger + codec:FlutterSmallApiGetCodec()]; + [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, [FlutterError + errorWithCode:@"channel-error" + message:@"Unable to establish connection on channel." + details:@""]); + } + }]; +} @end diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h index d2fac067fea..f330fc4c68f 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.h @@ -494,6 +494,8 @@ NSObject *FlutterSmallApiGetCodec(void); - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; - (void)echoWrappedList:(TestMessage *)msg completion:(void (^)(TestMessage *_Nullable, FlutterError *_Nullable))completion; +- (void)echoString:(NSString *)aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; @end NS_ASSUME_NONNULL_END diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m index 634c3e5503b..60bcbb34651 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/macos/Classes/CoreTests.gen.m @@ -2971,4 +2971,30 @@ - (void)echoWrappedList:(TestMessage *)arg_msg } }]; } +- (void)echoString:(NSString *)arg_aString + completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { + FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel + messageChannelWithName: + @"dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString" + binaryMessenger:self.binaryMessenger + codec:FlutterSmallApiGetCodec()]; + [channel sendMessage:@[ arg_aString ?: [NSNull null] ] + reply:^(NSArray *reply) { + if (reply != nil) { + if (reply.count > 1) { + completion(nil, [FlutterError errorWithCode:reply[0] + message:reply[1] + details:reply[2]]); + } else { + NSString *output = reply[0] == [NSNull null] ? nil : reply[0]; + completion(output, nil); + } + } else { + completion(nil, [FlutterError + errorWithCode:@"channel-error" + message:@"Unable to establish connection on channel." + details:@""]); + } + }]; +} @end diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index 0ec2bcd8a44..98a5b81a3f6 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -3120,6 +3120,8 @@ abstract class FlutterSmallApi { TestMessage echoWrappedList(TestMessage msg); + String echoString(String aString); + static void setup(FlutterSmallApi? api, {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel channel = BasicMessageChannel( @@ -3148,5 +3150,32 @@ abstract class FlutterSmallApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString was null.'); + final List args = (message as List?)!; + final String? arg_aString = (args[0] as String?); + assert(arg_aString != null, + 'Argument for dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString was null, expected non-null String.'); + try { + final String output = api.echoString(arg_aString!); + return wrapResponse(result: output); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse( + error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } } } diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index 07de3995f0a..86ec6755240 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -2479,4 +2479,21 @@ class FlutterSmallApi(private val binaryMessenger: BinaryMessenger) { } } } + fun echoString(aStringArg: String, callback: (Result) -> Unit) { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString", codec) + channel.send(listOf(aStringArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))); + } else if (it[0] == null) { + callback(Result.failure(FlutterError("null-error", "Flutter api returned null value for non-null return value.", ""))); + } else { + val output = it[0] as String + callback(Result.success(output)); + } + } else { + callback(Result.failure(FlutterError("channel-error", "Unable to establish connection on channel.", ""))); + } + } + } } diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/RunnerTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/RunnerTests.swift index 4cbd6b0d1f2..9ad4dd95c0c 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/RunnerTests.swift +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/RunnerTests.swift @@ -2,11 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import Flutter +import Foundation import XCTest + @testable import test_plugin class RunnerTests: XCTestCase { - + func testToListAndBack() throws { let reply = MessageSearchReply(result: "foobar") let dict = reply.toList() @@ -27,4 +30,32 @@ class RunnerTests: XCTestCase { let copy = MessageSearchReply.fromList(dict) XCTAssertEqual(reply.error, copy?.error) } + + /// This validates that pigeon clients can easily write tests that mock out Flutter API + /// calls using a pigeon-generated protocol. + func testEchoStringFromProtocol() throws { + let api: FlutterApiFromProtocol = FlutterApiFromProtocol() + let aString = "aString" + api.echo(aString) { response in + switch response { + case .success(let res): + XCTAssertEqual(aString, res) + case .failure(let error): + XCTFail(error.code) + } + } + } +} + +class FlutterApiFromProtocol: FlutterSmallApiProtocol { + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + completion(.success(aStringArg)) + } + + func echo( + _ msgArg: test_plugin.TestMessage, + completion: @escaping (Result) -> Void + ) { + completion(.success(msgArg)) + } } diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 601136c458d..8b83e3d1771 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -1739,8 +1739,62 @@ class FlutterIntegrationCoreApiCodec: FlutterStandardMessageCodec { /// The core interface that the Dart platform_test code implements for host /// integration tests to call into. /// -/// Generated class from Pigeon that represents Flutter messages that can be called from Swift. -class FlutterIntegrationCoreApi { +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol FlutterIntegrationCoreApiProtocol { + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func throwError(completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func throwErrorFromVoid(completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echo(_ everythingArg: AllTypes, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable(_ everythingArg: AllNullableTypes?, completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypes(aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echo(_ aListArg: FlutterStandardTypedData, completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo(_ aListArg: [Any?], completion: @escaping (Result<[Any?], FlutterError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo(_ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], FlutterError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echoNullable(_ aDoubleArg: Double?, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echoNullable(_ aStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echoNullable(_ aListArg: FlutterStandardTypedData?, completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable(_ aListArg: [Any?]?, completion: @escaping (Result<[Any?]?, FlutterError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(_ aMapArg: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, FlutterError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echoNullable(_ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func noopAsync(completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) +} +class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { private let binaryMessenger: FlutterBinaryMessenger init(binaryMessenger: FlutterBinaryMessenger){ self.binaryMessenger = binaryMessenger @@ -1750,14 +1804,14 @@ class FlutterIntegrationCoreApi { } /// A no-op function taking no arguments and returning no value, to sanity /// test basic calling. - func noop(completion: @escaping (Result) -> Void) { + func noop(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { _ in completion(.success(Void())) } } /// Responds with an error from an async function returning a value. - func throwError(completion: @escaping (Result) -> Void) { + func throwError(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { response in guard let listResponse = response as? [Any?] else { @@ -1776,14 +1830,14 @@ class FlutterIntegrationCoreApi { } } /// Responds with an error from an async void function. - func throwErrorFromVoid(completion: @escaping (Result) -> Void) { + func throwErrorFromVoid(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { _ in completion(.success(Void())) } } /// Returns the passed object, to test serialization and deserialization. - func echo(_ everythingArg: AllTypes, completion: @escaping (Result) -> Void) { + func echo(_ everythingArg: AllTypes, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([everythingArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1804,7 +1858,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed object, to test serialization and deserialization. - func echoNullable(_ everythingArg: AllNullableTypes?, completion: @escaping (Result) -> Void) { + func echoNullable(_ everythingArg: AllNullableTypes?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([everythingArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1825,7 +1879,7 @@ class FlutterIntegrationCoreApi { /// Returns passed in arguments of multiple types. /// /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypes(aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) { + func sendMultipleNullableTypes(aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1846,7 +1900,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed boolean, to test serialization and deserialization. - func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aBoolArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1867,7 +1921,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed int, to test serialization and deserialization. - func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anIntArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1888,7 +1942,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed double, to test serialization and deserialization. - func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aDoubleArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1909,7 +1963,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed string, to test serialization and deserialization. - func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1930,7 +1984,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed byte list, to test serialization and deserialization. - func echo(_ aListArg: FlutterStandardTypedData, completion: @escaping (Result) -> Void) { + func echo(_ aListArg: FlutterStandardTypedData, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1951,7 +2005,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed list, to test serialization and deserialization. - func echo(_ aListArg: [Any?], completion: @escaping (Result<[Any?], FlutterError>) -> Void) { + func echo(_ aListArg: [Any?], completion: @escaping (Result<[Any?], FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1972,7 +2026,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed map, to test serialization and deserialization. - func echo(_ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], FlutterError>) -> Void) { + func echo(_ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1993,7 +2047,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed enum to test serialization and deserialization. - func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anEnumArg.rawValue] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2014,7 +2068,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed boolean, to test serialization and deserialization. - func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aBoolArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2033,7 +2087,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed int, to test serialization and deserialization. - func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) { + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anIntArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2052,7 +2106,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed double, to test serialization and deserialization. - func echoNullable(_ aDoubleArg: Double?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aDoubleArg: Double?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aDoubleArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2071,7 +2125,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed string, to test serialization and deserialization. - func echoNullable(_ aStringArg: String?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aStringArg: String?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2090,7 +2144,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed byte list, to test serialization and deserialization. - func echoNullable(_ aListArg: FlutterStandardTypedData?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aListArg: FlutterStandardTypedData?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2109,7 +2163,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed list, to test serialization and deserialization. - func echoNullable(_ aListArg: [Any?]?, completion: @escaping (Result<[Any?]?, FlutterError>) -> Void) { + func echoNullable(_ aListArg: [Any?]?, completion: @escaping (Result<[Any?]?, FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2128,7 +2182,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed map, to test serialization and deserialization. - func echoNullable(_ aMapArg: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, FlutterError>) -> Void) { + func echoNullable(_ aMapArg: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2147,7 +2201,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed enum to test serialization and deserialization. - func echoNullable(_ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) { + func echoNullable(_ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anEnumArg?.rawValue] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2167,14 +2221,14 @@ class FlutterIntegrationCoreApi { } /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. - func noopAsync(completion: @escaping (Result) -> Void) { + func noopAsync(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { _ in completion(.success(Void())) } } /// Returns the passed in generic Object asynchronously. - func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) { + func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAsyncString", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2307,8 +2361,12 @@ class FlutterSmallApiCodec: FlutterStandardMessageCodec { /// A simple API called in some unit tests. /// -/// Generated class from Pigeon that represents Flutter messages that can be called from Swift. -class FlutterSmallApi { +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol FlutterSmallApiProtocol { + func echo(_ msgArg: TestMessage, completion: @escaping (Result) -> Void) + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) +} +class FlutterSmallApi: FlutterSmallApiProtocol { private let binaryMessenger: FlutterBinaryMessenger init(binaryMessenger: FlutterBinaryMessenger){ self.binaryMessenger = binaryMessenger @@ -2316,7 +2374,7 @@ class FlutterSmallApi { var codec: FlutterStandardMessageCodec { return FlutterSmallApiCodec.shared } - func echo(_ msgArg: TestMessage, completion: @escaping (Result) -> Void) { + func echo(_ msgArg: TestMessage, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoWrappedList", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([msgArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2336,4 +2394,24 @@ class FlutterSmallApi { } } } + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(FlutterError(code: "channel-error", message: "Unable to establish connection on channel.", details: ""))) + return + } + if (listResponse.count > 1) { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(FlutterError(code: code, message: message, details: details))); + } else if (listResponse[0] == nil) { + completion(.failure(FlutterError(code: "null-error", message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } } diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 601136c458d..8b83e3d1771 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -1739,8 +1739,62 @@ class FlutterIntegrationCoreApiCodec: FlutterStandardMessageCodec { /// The core interface that the Dart platform_test code implements for host /// integration tests to call into. /// -/// Generated class from Pigeon that represents Flutter messages that can be called from Swift. -class FlutterIntegrationCoreApi { +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol FlutterIntegrationCoreApiProtocol { + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic calling. + func noop(completion: @escaping (Result) -> Void) + /// Responds with an error from an async function returning a value. + func throwError(completion: @escaping (Result) -> Void) + /// Responds with an error from an async void function. + func throwErrorFromVoid(completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echo(_ everythingArg: AllTypes, completion: @escaping (Result) -> Void) + /// Returns the passed object, to test serialization and deserialization. + func echoNullable(_ everythingArg: AllNullableTypes?, completion: @escaping (Result) -> Void) + /// Returns passed in arguments of multiple types. + /// + /// Tests multiple-arity FlutterApi handling. + func sendMultipleNullableTypes(aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echo(_ aListArg: FlutterStandardTypedData, completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echo(_ aListArg: [Any?], completion: @escaping (Result<[Any?], FlutterError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echo(_ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], FlutterError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) + /// Returns the passed boolean, to test serialization and deserialization. + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) + /// Returns the passed int, to test serialization and deserialization. + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) + /// Returns the passed double, to test serialization and deserialization. + func echoNullable(_ aDoubleArg: Double?, completion: @escaping (Result) -> Void) + /// Returns the passed string, to test serialization and deserialization. + func echoNullable(_ aStringArg: String?, completion: @escaping (Result) -> Void) + /// Returns the passed byte list, to test serialization and deserialization. + func echoNullable(_ aListArg: FlutterStandardTypedData?, completion: @escaping (Result) -> Void) + /// Returns the passed list, to test serialization and deserialization. + func echoNullable(_ aListArg: [Any?]?, completion: @escaping (Result<[Any?]?, FlutterError>) -> Void) + /// Returns the passed map, to test serialization and deserialization. + func echoNullable(_ aMapArg: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, FlutterError>) -> Void) + /// Returns the passed enum to test serialization and deserialization. + func echoNullable(_ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) + /// A no-op function taking no arguments and returning no value, to sanity + /// test basic asynchronous calling. + func noopAsync(completion: @escaping (Result) -> Void) + /// Returns the passed in generic Object asynchronously. + func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) +} +class FlutterIntegrationCoreApi: FlutterIntegrationCoreApiProtocol { private let binaryMessenger: FlutterBinaryMessenger init(binaryMessenger: FlutterBinaryMessenger){ self.binaryMessenger = binaryMessenger @@ -1750,14 +1804,14 @@ class FlutterIntegrationCoreApi { } /// A no-op function taking no arguments and returning no value, to sanity /// test basic calling. - func noop(completion: @escaping (Result) -> Void) { + func noop(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noop", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { _ in completion(.success(Void())) } } /// Responds with an error from an async function returning a value. - func throwError(completion: @escaping (Result) -> Void) { + func throwError(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwError", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { response in guard let listResponse = response as? [Any?] else { @@ -1776,14 +1830,14 @@ class FlutterIntegrationCoreApi { } } /// Responds with an error from an async void function. - func throwErrorFromVoid(completion: @escaping (Result) -> Void) { + func throwErrorFromVoid(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.throwErrorFromVoid", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { _ in completion(.success(Void())) } } /// Returns the passed object, to test serialization and deserialization. - func echo(_ everythingArg: AllTypes, completion: @escaping (Result) -> Void) { + func echo(_ everythingArg: AllTypes, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllTypes", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([everythingArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1804,7 +1858,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed object, to test serialization and deserialization. - func echoNullable(_ everythingArg: AllNullableTypes?, completion: @escaping (Result) -> Void) { + func echoNullable(_ everythingArg: AllNullableTypes?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAllNullableTypes", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([everythingArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1825,7 +1879,7 @@ class FlutterIntegrationCoreApi { /// Returns passed in arguments of multiple types. /// /// Tests multiple-arity FlutterApi handling. - func sendMultipleNullableTypes(aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) { + func sendMultipleNullableTypes(aBool aNullableBoolArg: Bool?, anInt aNullableIntArg: Int64?, aString aNullableStringArg: String?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.sendMultipleNullableTypes", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aNullableBoolArg, aNullableIntArg, aNullableStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1846,7 +1900,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed boolean, to test serialization and deserialization. - func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { + func echo(_ aBoolArg: Bool, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoBool", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aBoolArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1867,7 +1921,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed int, to test serialization and deserialization. - func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { + func echo(_ anIntArg: Int64, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoInt", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anIntArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1888,7 +1942,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed double, to test serialization and deserialization. - func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { + func echo(_ aDoubleArg: Double, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoDouble", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aDoubleArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1909,7 +1963,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed string, to test serialization and deserialization. - func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoString", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1930,7 +1984,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed byte list, to test serialization and deserialization. - func echo(_ aListArg: FlutterStandardTypedData, completion: @escaping (Result) -> Void) { + func echo(_ aListArg: FlutterStandardTypedData, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoUint8List", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1951,7 +2005,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed list, to test serialization and deserialization. - func echo(_ aListArg: [Any?], completion: @escaping (Result<[Any?], FlutterError>) -> Void) { + func echo(_ aListArg: [Any?], completion: @escaping (Result<[Any?], FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoList", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1972,7 +2026,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed map, to test serialization and deserialization. - func echo(_ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], FlutterError>) -> Void) { + func echo(_ aMapArg: [String?: Any?], completion: @escaping (Result<[String?: Any?], FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoMap", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -1993,7 +2047,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed enum to test serialization and deserialization. - func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { + func echo(_ anEnumArg: AnEnum, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoEnum", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anEnumArg.rawValue] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2014,7 +2068,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed boolean, to test serialization and deserialization. - func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aBoolArg: Bool?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableBool", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aBoolArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2033,7 +2087,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed int, to test serialization and deserialization. - func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) { + func echoNullable(_ anIntArg: Int64?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableInt", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anIntArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2052,7 +2106,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed double, to test serialization and deserialization. - func echoNullable(_ aDoubleArg: Double?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aDoubleArg: Double?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableDouble", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aDoubleArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2071,7 +2125,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed string, to test serialization and deserialization. - func echoNullable(_ aStringArg: String?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aStringArg: String?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableString", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2090,7 +2144,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed byte list, to test serialization and deserialization. - func echoNullable(_ aListArg: FlutterStandardTypedData?, completion: @escaping (Result) -> Void) { + func echoNullable(_ aListArg: FlutterStandardTypedData?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableUint8List", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2109,7 +2163,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed list, to test serialization and deserialization. - func echoNullable(_ aListArg: [Any?]?, completion: @escaping (Result<[Any?]?, FlutterError>) -> Void) { + func echoNullable(_ aListArg: [Any?]?, completion: @escaping (Result<[Any?]?, FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableList", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aListArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2128,7 +2182,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed map, to test serialization and deserialization. - func echoNullable(_ aMapArg: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, FlutterError>) -> Void) { + func echoNullable(_ aMapArg: [String?: Any?]?, completion: @escaping (Result<[String?: Any?]?, FlutterError>) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableMap", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aMapArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2147,7 +2201,7 @@ class FlutterIntegrationCoreApi { } } /// Returns the passed enum to test serialization and deserialization. - func echoNullable(_ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) { + func echoNullable(_ anEnumArg: AnEnum?, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoNullableEnum", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([anEnumArg?.rawValue] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2167,14 +2221,14 @@ class FlutterIntegrationCoreApi { } /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. - func noopAsync(completion: @escaping (Result) -> Void) { + func noopAsync(completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage(nil) { _ in completion(.success(Void())) } } /// Returns the passed in generic Object asynchronously. - func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) { + func echoAsync(_ aStringArg: String, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterIntegrationCoreApi.echoAsyncString", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([aStringArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2307,8 +2361,12 @@ class FlutterSmallApiCodec: FlutterStandardMessageCodec { /// A simple API called in some unit tests. /// -/// Generated class from Pigeon that represents Flutter messages that can be called from Swift. -class FlutterSmallApi { +/// Generated protocol from Pigeon that represents Flutter messages that can be called from Swift. +protocol FlutterSmallApiProtocol { + func echo(_ msgArg: TestMessage, completion: @escaping (Result) -> Void) + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) +} +class FlutterSmallApi: FlutterSmallApiProtocol { private let binaryMessenger: FlutterBinaryMessenger init(binaryMessenger: FlutterBinaryMessenger){ self.binaryMessenger = binaryMessenger @@ -2316,7 +2374,7 @@ class FlutterSmallApi { var codec: FlutterStandardMessageCodec { return FlutterSmallApiCodec.shared } - func echo(_ msgArg: TestMessage, completion: @escaping (Result) -> Void) { + func echo(_ msgArg: TestMessage, completion: @escaping (Result) -> Void) { let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoWrappedList", binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([msgArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -2336,4 +2394,24 @@ class FlutterSmallApi { } } } + func echo(_ aStringArg: String, completion: @escaping (Result) -> Void) { + let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString", binaryMessenger: binaryMessenger, codec: codec) + channel.sendMessage([aStringArg] as [Any?]) { response in + guard let listResponse = response as? [Any?] else { + completion(.failure(FlutterError(code: "channel-error", message: "Unable to establish connection on channel.", details: ""))) + return + } + if (listResponse.count > 1) { + let code: String = listResponse[0] as! String + let message: String? = nilOrValue(listResponse[1]) + let details: String? = nilOrValue(listResponse[2]) + completion(.failure(FlutterError(code: code, message: message, details: details))); + } else if (listResponse[0] == nil) { + completion(.failure(FlutterError(code: "null-error", message: "Flutter api returned null value for non-null return value.", details: ""))) + } else { + let result = listResponse[0] as! String + completion(.success(result)) + } + } + } } diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp index f4f557a664f..445911f7b30 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp @@ -4749,4 +4749,42 @@ void FlutterSmallApi::EchoWrappedList( }); } +void FlutterSmallApi::EchoString( + const std::string& a_string_arg, + std::function&& on_success, + std::function&& on_error) { + auto channel = std::make_unique>( + binary_messenger_, + "dev.flutter.pigeon.pigeon_integration_tests.FlutterSmallApi.echoString", + &GetCodec()); + EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ + EncodableValue(a_string_arg), + }); + channel->Send(encoded_api_arguments, [on_success = std::move(on_success), + on_error = std::move(on_error)]( + const uint8_t* reply, + size_t reply_size) { + std::unique_ptr response = + GetCodec().DecodeMessage(reply, reply_size); + const auto& encodable_return_value = *response; + const auto* list_return_value = + std::get_if(&encodable_return_value); + if (list_return_value) { + if (list_return_value->size() > 1) { + on_error(FlutterError(std::get(list_return_value->at(0)), + std::get(list_return_value->at(1)), + list_return_value->at(2))); + } else { + const auto& return_value = + std::get(list_return_value->at(0)); + on_success(return_value); + } + } else { + on_error(FlutterError("channel-error", + "Unable to establish connection on channel.", + EncodableValue(""))); + } + }); +} + } // namespace core_tests_pigeontest diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index 1076ae465c1..b579f9fa87e 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -847,6 +847,9 @@ class FlutterSmallApi { void EchoWrappedList(const TestMessage& msg, std::function&& on_success, std::function&& on_error); + void EchoString(const std::string& a_string, + std::function&& on_success, + std::function&& on_error); private: flutter::BinaryMessenger* binary_messenger_; diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 98b0fa577a5..867537f4be2 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -2,7 +2,7 @@ name: pigeon description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. repository: https://github.com/flutter/packages/tree/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 12.0.0 # This must match the version in lib/generator_tools.dart +version: 12.0.1 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.19.0 <4.0.0"