Description
Starting with Flutter 5.4.0, you can’t create or send RCIMIWCommandMessage (command message) and RCIMIWCommandNotificationMessage (command notification message) types.
Analysis
The Flutter SDK doesn’t currently provide a create
method for command messages (RCIMIWCommandMessage) and command notification messages (RCIMIWCommandNotificationMessage). To send these messages from the client, you’ll need to define a wrapper class in the Flutter layer. This approach is supported only in version 5.4.0 and above.
Follow the steps below for implementation.
Solution
Create a command message
-
Define the message in the Flutter layer by creating
wrapper_command_message.dart
.import 'package:rongcloud_im_wrapper_plugin/rongcloud_im_wrapper_plugin.dart'; import 'dart:convert' as json_lib show json; // Custom messages must extend RCIMIWUserCustomMessage class RCIMDCommandMessage extends RCIMIWUserCustomMessage { String? name; String? data; // 1. Define your constructor, calling the parent class RCIMIWUserCustomMessage(RCIMIWConversationType type, String targetId) RCIMDCommandMessage(RCIMIWConversationType type, String targetId, this.name, this.data) : super(type, targetId); // 2. Inherit the parent class constructor RCIMDCommandMessage.fromJson(Map<String, dynamic> json) : super.fromJson(json); // 3. Implement the parent class's decode/encode/messageObjectName @override void decode(String jsonStr) { Map map = json_lib.json.decode(jsonStr.toString()); // The key must match the one passed from the native layer name = map['name']; name = map['data']; } @override String encode() { Map map = {}; // The key must match the one passed to the native layer map['name'] = name; map['data'] = data; return json_lib.json.encode(map); } @override String messageObjectName() { return "RC:CmdMsg"; } // 4. Implement the parent class's toJson @override Map<String, dynamic> toJson() { final Map<String, dynamic> json = super.toJson(); // 'content' must not be modified json['content'] = encode(); return json; } }
-
Register the message in the native layer.
iOS:
xxxx/ios/Runner/AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; NSMutableArray *marr = [NSMutableArray arrayWithObjects:[RCDPokeMessage class], [RCCommandMessage class], nil]; [RCIMWrapperEngine sharedInstance].messageContentClassList = marr.copy; ... }
Android:
example/android/app/src/main/java/cn/rongcloud/im/wrapper/flutter/example/MainActivity.java
public class MainActivity extends FlutterActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); List<Class<? extends MessageContent>> list = new ArrayList<>(); list.add(PokeMessage.class); list.add(CommandMessage.class); RCIMWrapperEngine.getInstance().messageContentClassList = list; } }
Send a command message
RCIMDCommandMessage msg = RCIMDCommandMessage(type, targetId, "name", "data");
_sendMessage(msg, useCallback);
Both received and successfully sent messages will be processed as RCIMIWCommandMessage
. For other use cases like receiving messages, simply handle RCIMIWCommandMessage
.
If you have any questions, feel free to submit a ticket.