Commit a3383261 authored by Mikkel Nygaard Ravn's avatar Mikkel Nygaard Ravn Committed by GitHub

Document channel message value conversions (#9635)

parent 11fa80bb
...@@ -21,12 +21,12 @@ import 'platform_channel.dart'; ...@@ -21,12 +21,12 @@ import 'platform_channel.dart';
abstract class MessageCodec<T> { abstract class MessageCodec<T> {
/// Encodes the specified [message] in binary. /// Encodes the specified [message] in binary.
/// ///
/// Returns `null` if the message is `null`. /// Returns null if the message is null.
ByteData encodeMessage(T message); ByteData encodeMessage(T message);
/// Decodes the specified [message] from binary. /// Decodes the specified [message] from binary.
/// ///
/// Returns `null` if the message is `null`. /// Returns null if the message is null.
T decodeMessage(ByteData message); T decodeMessage(ByteData message);
} }
...@@ -155,10 +155,10 @@ class PlatformException implements Exception { ...@@ -155,10 +155,10 @@ class PlatformException implements Exception {
/// An error code. /// An error code.
final String code; final String code;
/// A human-readable error message, possibly `null`. /// A human-readable error message, possibly null.
final String message; final String message;
/// Error details, possibly `null`. /// Error details, possibly null.
final dynamic details; final dynamic details;
@override @override
...@@ -174,13 +174,13 @@ class PlatformException implements Exception { ...@@ -174,13 +174,13 @@ class PlatformException implements Exception {
/// with a [MissingPluginException], if no plugin handler for the method call /// with a [MissingPluginException], if no plugin handler for the method call
/// was found. /// was found.
/// * [OptionalMethodChannel.invokeMethod], which completes the returned future /// * [OptionalMethodChannel.invokeMethod], which completes the returned future
/// with `null`, if no plugin handler for the method call was found. /// with null, if no plugin handler for the method call was found.
class MissingPluginException implements Exception { class MissingPluginException implements Exception {
/// Creates a [MissingPluginException] with an optional human-readable /// Creates a [MissingPluginException] with an optional human-readable
/// error message. /// error message.
MissingPluginException([this.message]); MissingPluginException([this.message]);
/// A human-readable error message, possibly `null`. /// A human-readable error message, possibly null.
final String message; final String message;
@override @override
......
...@@ -10,6 +10,9 @@ import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer, required; ...@@ -10,6 +10,9 @@ import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer, required;
import 'message_codec.dart'; import 'message_codec.dart';
/// [MessageCodec] with unencoded binary messages represented using [ByteData]. /// [MessageCodec] with unencoded binary messages represented using [ByteData].
///
/// On Android, messages will be represented using `java.nio.ByteBuffer`.
/// On iOS, messages will be represented using `NSData`.
class BinaryCodec implements MessageCodec<ByteData> { class BinaryCodec implements MessageCodec<ByteData> {
/// Creates a [MessageCodec] with unencoded binary messages represented using /// Creates a [MessageCodec] with unencoded binary messages represented using
/// [ByteData]. /// [ByteData].
...@@ -23,6 +26,9 @@ class BinaryCodec implements MessageCodec<ByteData> { ...@@ -23,6 +26,9 @@ class BinaryCodec implements MessageCodec<ByteData> {
} }
/// [MessageCodec] with UTF-8 encoded String messages. /// [MessageCodec] with UTF-8 encoded String messages.
///
/// On Android, messages will be represented using `java.util.String`.
/// On iOS, messages will be represented using `NSString`.
class StringCodec implements MessageCodec<String> { class StringCodec implements MessageCodec<String> {
/// Creates a [MessageCodec] with UTF-8 encoded String messages. /// Creates a [MessageCodec] with UTF-8 encoded String messages.
const StringCodec(); const StringCodec();
...@@ -47,12 +53,20 @@ class StringCodec implements MessageCodec<String> { ...@@ -47,12 +53,20 @@ class StringCodec implements MessageCodec<String> {
/// ///
/// Supported messages are acyclic values of these forms: /// Supported messages are acyclic values of these forms:
/// ///
/// * `null` /// * null
/// * [bool]s /// * [bool]s
/// * [num]s /// * [num]s
/// * [String]s /// * [String]s
/// * [List]s of supported values /// * [List]s of supported values
/// * [Map]s from strings to supported values /// * [Map]s from strings to supported values
///
/// On Android, messages are decoded using the `org.json` library.
/// On iOS, messages are decoded using the `NSJSONSerialization` library.
/// In both cases, the use of top-level simple messages (null, [bool], [num],
/// and [String]) is supported (by the Flutter SDK). The decoded value will be
/// null/nil for null, and identical to what would result from decoding a
/// singleton JSON array with a Boolean, number, or string value, and then
/// extracting its single element.
class JSONMessageCodec implements MessageCodec<dynamic> { class JSONMessageCodec implements MessageCodec<dynamic> {
// The codec serializes messages as defined by the JSON codec of the // The codec serializes messages as defined by the JSON codec of the
// dart:convert package. The format used must match the Android and // dart:convert package. The format used must match the Android and
...@@ -156,13 +170,45 @@ class JSONMethodCodec implements MethodCodec { ...@@ -156,13 +170,45 @@ class JSONMethodCodec implements MethodCodec {
/// ///
/// Supported messages are acyclic values of these forms: /// Supported messages are acyclic values of these forms:
/// ///
/// * `null` /// * null
/// * [bool]s /// * [bool]s
/// * [num]s /// * [num]s
/// * [String]s /// * [String]s
/// * [Uint8List]s, [Int32List]s, [Int64List]s, [Float64List]s /// * [Uint8List]s, [Int32List]s, [Int64List]s, [Float64List]s
/// * [List]s of supported values /// * [List]s of supported values
/// * [Map]s from supported values to supported values /// * [Map]s from supported values to supported values
///
/// On Android, messages are represented as follows:
///
/// * null: null
/// * [bool]: `java.lang.Boolean`
/// * [int]: `java.lang.Integer` for values that are representable using 32-bit
/// two's complement; otherwise, `java.lang.Long` for values that are
/// representable using 64-bit two's complement; otherwise,
/// `java.math.BigInteger`.
/// * [double]: `java.lang.Double`
/// * [String]: `java.lang.String`
/// * [Uint8List]: `byte[]`
/// * [Int32List]: `int[]`
/// * [Int64List]: `long[]`
/// * [Float64List]: `double[]`
/// * [List]: `java.util.ArrayList`
/// * [Map]: `java.util.HashMap`
///
/// On iOS, messages are represented as follows:
///
/// * null: nil
/// * [bool]: `NSNumber numberWithBool:`
/// * [int]: `NSNumber numberWithInt:` for values that are representable using
/// 32-bit two's complement; otherwise, `NSNumber numberWithLong:` for values
/// that are representable using 64-bit two's complement; otherwise,
/// `FlutterStandardBigInteger`.
/// * [double]: `NSNumber numberWithDouble:`
/// * [String]: `NSString`
/// * [Uint8List], [Int32List], [Int64List], [Float64List]:
/// `FlutterStandardTypedData`
/// * [List]: `NSArray`
/// * [Map]: `NSDictionary`
class StandardMessageCodec implements MessageCodec<dynamic> { class StandardMessageCodec implements MessageCodec<dynamic> {
// The codec serializes messages as outlined below. This format must // The codec serializes messages as outlined below. This format must
// match the Android and iOS counterparts. // match the Android and iOS counterparts.
......
...@@ -21,7 +21,7 @@ import 'platform_messages.dart'; ...@@ -21,7 +21,7 @@ import 'platform_messages.dart';
/// platform side. The Dart type of messages sent and received is [T], /// platform side. The Dart type of messages sent and received is [T],
/// but only the values supported by the specified [MessageCodec] can be used. /// but only the values supported by the specified [MessageCodec] can be used.
/// The use of unsupported values should be considered programming errors, and /// The use of unsupported values should be considered programming errors, and
/// will result in exceptions being thrown. The `null` message is supported /// will result in exceptions being thrown. The null message is supported
/// for all codecs. /// for all codecs.
/// ///
/// The logical identity of the channel is given by its name. Identically named /// The logical identity of the channel is given by its name. Identically named
...@@ -31,32 +31,32 @@ import 'platform_messages.dart'; ...@@ -31,32 +31,32 @@ import 'platform_messages.dart';
class BasicMessageChannel<T> { class BasicMessageChannel<T> {
/// Creates a [BasicMessageChannel] with the specified [name] and [codec]. /// Creates a [BasicMessageChannel] with the specified [name] and [codec].
/// ///
/// Neither [name] nor [codec] may be `null`. /// Neither [name] nor [codec] may be null.
const BasicMessageChannel(this.name, this.codec); const BasicMessageChannel(this.name, this.codec);
/// The logical channel on which communication happens, not `null`. /// The logical channel on which communication happens, not null.
final String name; final String name;
/// The message codec used by this channel, not `null`. /// The message codec used by this channel, not null.
final MessageCodec<T> codec; final MessageCodec<T> codec;
/// Sends the specified [message] to the platform plugins on this channel. /// Sends the specified [message] to the platform plugins on this channel.
/// ///
/// Returns a [Future] which completes to the received response, which may /// Returns a [Future] which completes to the received response, which may
/// be `null`. /// be null.
Future<T> send(T message) async { Future<T> send(T message) async {
return codec.decodeMessage(await BinaryMessages.send(name, codec.encodeMessage(message))); return codec.decodeMessage(await BinaryMessages.send(name, codec.encodeMessage(message)));
} }
/// Sets a callback for receiving messages from the platform plugins on this /// Sets a callback for receiving messages from the platform plugins on this
/// channel. Messages may be `null`. /// channel. Messages may be null.
/// ///
/// The given callback will replace the currently registered callback for this /// The given callback will replace the currently registered callback for this
/// channel, if any. To remove the handler, pass `null` as the `handler` /// channel, if any. To remove the handler, pass null as the `handler`
/// argument. /// argument.
/// ///
/// The handler's return value is sent back to the platform plugins as a /// The handler's return value is sent back to the platform plugins as a
/// message reply. It may be `null`. /// message reply. It may be null.
void setMessageHandler(Future<T> handler(T message)) { void setMessageHandler(Future<T> handler(T message)) {
if (handler == null) { if (handler == null) {
BinaryMessages.setMessageHandler(name, null); BinaryMessages.setMessageHandler(name, null);
...@@ -68,13 +68,13 @@ class BasicMessageChannel<T> { ...@@ -68,13 +68,13 @@ class BasicMessageChannel<T> {
} }
/// Sets a mock callback for intercepting messages sent on this channel. /// Sets a mock callback for intercepting messages sent on this channel.
/// Messages may be `null`. /// Messages may be null.
/// ///
/// The given callback will replace the currently registered mock callback for /// The given callback will replace the currently registered mock callback for
/// this channel, if any. To remove the mock handler, pass `null` as the /// this channel, if any. To remove the mock handler, pass null as the
/// `handler` argument. /// `handler` argument.
/// ///
/// The handler's return value is used as a message reply. It may be `null`. /// The handler's return value is used as a message reply. It may be null.
/// ///
/// This is intended for testing. Messages intercepted in this manner are not /// This is intended for testing. Messages intercepted in this manner are not
/// sent to platform plugins. /// sent to platform plugins.
...@@ -99,7 +99,7 @@ class BasicMessageChannel<T> { ...@@ -99,7 +99,7 @@ class BasicMessageChannel<T> {
/// platform side. The Dart type of arguments and results is `dynamic`, /// platform side. The Dart type of arguments and results is `dynamic`,
/// but only values supported by the specified [MethodCodec] can be used. /// but only values supported by the specified [MethodCodec] can be used.
/// The use of unsupported values should be considered programming errors, and /// The use of unsupported values should be considered programming errors, and
/// will result in exceptions being thrown. The `null` value is supported /// will result in exceptions being thrown. The null value is supported
/// for all codecs. /// for all codecs.
/// ///
/// The logical identity of the channel is given by its name. Identically named /// The logical identity of the channel is given by its name. Identically named
...@@ -112,20 +112,20 @@ class MethodChannel { ...@@ -112,20 +112,20 @@ class MethodChannel {
/// The [codec] used will be [StandardMethodCodec], unless otherwise /// The [codec] used will be [StandardMethodCodec], unless otherwise
/// specified. /// specified.
/// ///
/// Neither [name] nor [codec] may be `null`. /// Neither [name] nor [codec] may be null.
const MethodChannel(this.name, [this.codec = const StandardMethodCodec()]); const MethodChannel(this.name, [this.codec = const StandardMethodCodec()]);
/// The logical channel on which communication happens, not `null`. /// The logical channel on which communication happens, not null.
final String name; final String name;
/// The message codec used by this channel, not `null`. /// The message codec used by this channel, not null.
final MethodCodec codec; final MethodCodec codec;
/// Invokes a [method] on this channel with the specified [arguments]. /// Invokes a [method] on this channel with the specified [arguments].
/// ///
/// Returns a [Future] which completes to one of the following: /// Returns a [Future] which completes to one of the following:
/// ///
/// * a result (possibly `null`), on successful invocation; /// * a result (possibly null), on successful invocation;
/// * a [PlatformException], if the invocation failed in the platform plugin; /// * a [PlatformException], if the invocation failed in the platform plugin;
/// * a [MissingPluginException], if the method has not been implemented by a /// * a [MissingPluginException], if the method has not been implemented by a
/// platform plugin. /// platform plugin.
...@@ -143,7 +143,7 @@ class MethodChannel { ...@@ -143,7 +143,7 @@ class MethodChannel {
/// Sets a callback for receiving method calls on this channel. /// Sets a callback for receiving method calls on this channel.
/// ///
/// The given callback will replace the currently registered callback for this /// The given callback will replace the currently registered callback for this
/// channel, if any. To remove the handler, pass `null` as the /// channel, if any. To remove the handler, pass null as the
/// `handler` argument. /// `handler` argument.
/// ///
/// If the future returned by the handler completes with a result, that value /// If the future returned by the handler completes with a result, that value
...@@ -164,7 +164,7 @@ class MethodChannel { ...@@ -164,7 +164,7 @@ class MethodChannel {
/// Sets a mock callback for intercepting method invocations on this channel. /// Sets a mock callback for intercepting method invocations on this channel.
/// ///
/// The given callback will replace the currently registered mock callback for /// The given callback will replace the currently registered mock callback for
/// this channel, if any. To remove the mock handler, pass `null` as the /// this channel, if any. To remove the mock handler, pass null as the
/// `handler` argument. /// `handler` argument.
/// ///
/// Later calls to [invokeMethod] will result in a successful result, /// Later calls to [invokeMethod] will result in a successful result,
...@@ -238,20 +238,20 @@ class EventChannel { ...@@ -238,20 +238,20 @@ class EventChannel {
/// The [codec] used will be [StandardMethodCodec], unless otherwise /// The [codec] used will be [StandardMethodCodec], unless otherwise
/// specified. /// specified.
/// ///
/// Neither [name] nor [codec] may be `null`. /// Neither [name] nor [codec] may be null.
const EventChannel(this.name, [this.codec = const StandardMethodCodec()]); const EventChannel(this.name, [this.codec = const StandardMethodCodec()]);
/// The logical channel on which communication happens, not `null`. /// The logical channel on which communication happens, not null.
final String name; final String name;
/// The message codec used by this channel, not `null`. /// The message codec used by this channel, not null.
final MethodCodec codec; final MethodCodec codec;
/// Sets up a broadcast stream for receiving events on this channel. /// Sets up a broadcast stream for receiving events on this channel.
/// ///
/// Returns a broadcast [Stream] which emits events to listeners as follows: /// Returns a broadcast [Stream] which emits events to listeners as follows:
/// ///
/// * a decoded data event (possibly `null`) for each successful event /// * a decoded data event (possibly null) for each successful event
/// received from the platform plugin; /// received from the platform plugin;
/// * an error event containing a [PlatformException] for each error event /// * an error event containing a [PlatformException] for each error event
/// received from the platform plugin; /// received from the platform plugin;
......
...@@ -92,7 +92,7 @@ class BinaryMessages { ...@@ -92,7 +92,7 @@ class BinaryMessages {
/// given channel, without decoding them. /// given channel, without decoding them.
/// ///
/// The given callback will replace the currently registered callback for that /// The given callback will replace the currently registered callback for that
/// channel, if any. To remove the handler, pass `null` as the `handler` /// channel, if any. To remove the handler, pass null as the `handler`
/// argument. /// argument.
/// ///
/// The handler's return value, if non-null, is sent as a response, unencoded. /// The handler's return value, if non-null, is sent as a response, unencoded.
...@@ -107,7 +107,7 @@ class BinaryMessages { ...@@ -107,7 +107,7 @@ class BinaryMessages {
/// this class, on the given channel, without decoding them. /// this class, on the given channel, without decoding them.
/// ///
/// The given callback will replace the currently registered mock callback for /// The given callback will replace the currently registered mock callback for
/// that channel, if any. To remove the mock handler, pass `null` as the /// that channel, if any. To remove the mock handler, pass null as the
/// `handler` argument. /// `handler` argument.
/// ///
/// The handler's return value, if non-null, is used as a response, unencoded. /// The handler's return value, if non-null, is used as a response, unencoded.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment