从字典访问 FlutterStandardTypedData 时出现“[__NSArrayI 数据]:无法识别的选择器”

Posted

技术标签:

【中文标题】从字典访问 FlutterStandardTypedData 时出现“[__NSArrayI 数据]:无法识别的选择器”【英文标题】:"[__NSArrayI data]: unrecognized selector" when accessing FlutterStandardTypedData from dictionary 【发布时间】:2020-01-19 21:40:27 【问题描述】:

我正在尝试在 Flutter 中创建一个 Uint8List,将其放入 JSON 字符串并将该字符串传递给本机代码。 这是我的 Flutter 代码

final jsonObj = 
  "dataBuffer": dataBuffer, // dataBuffer is of type Uint8List
;

String encodedJson = json.encode(jsonObj);

await _channel.invokeMethod('testMethod', <String, dynamic>
  'jsonObj': encodedJson,
);

这是原生 iOS 代码,我尝试在其中将 Uint8List 作为 FlutterStandardTypedData 从 JSON 字符串中取出:

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result 
  if ([@"testMethod" isEqualToString:call.method]) 
    NSString* jsonString = (NSString*)call.arguments[@"jsonObj"];
    NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];

    NSError *error = nil;
    NSDictionary *responseObj = [NSJSONSerialization
                                 JSONObjectWithData:jsonData
                                 options:0
                                 error:&error];

    if(! error) 
        FlutterStandardTypedData *dataBufferJson = [responseObj objectForKey:@"dataBuffer"];
        NSData *bufferData = [dataBufferJson data]; *** // Here is where the exception is thrown ***
    
  

当我尝试获取 FlutterStandardTypedDatadata 属性时,出现以下异常:

'NSInvalidArgumentException',原因:'-[__NSArrayI 数据]: 无法识别的选择器发送到实例 0x7ff8f21ad000'

我不明白我收到此错误的原因,但我认为这是因为Uint8List 已放入 JSON 中,或者我正在尝试获取 @ 987654329@ 以错误的方式从字典中获取。反正我找不到解决办法。

我还尝试以另一种方式将 Uint8List 从 Flutter 传递给原生代码:在 Dart 中,我将 Uint8List 直接传递给原生代码(没有将其封装在 JSON 字符串中)。这样我就可以成功获取FlutterStandardTypedData对象。这是另一个例子的代码。

飞镖代码:

await _channel.invokeMethod('testMethod',
  dataBuffer, // example Uint8List
);

iOS 代码:

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result 
  if ([@"testMethod" isEqualToString:call.method]) 
    FlutterStandardTypedData* dataBuffer = (FlutterStandardTypedData*)call.arguments[@"dataBuffer"];
  

但是我需要通过 JSON 字符串传递 Uint8List

如何将 Uint8List 从 Flutter 传递到 ios 原生,并将其封装在 JSON 字符串中?

【问题讨论】:

您想在 JSON 中包装字节的原因是什么?如您所见,正确的做法是直接传递。 在我的应用程序中,我调用了一个本地方法,传入一个存储“Uint8List”和其他属性的对象。为了将此对象传递给本机代码,我必须将其转换为 JSON 字符串。 字节数组并没有真正的 JSON 表示。它处理数字、字符串、布尔值等。您的 API 如何希望以 JSON 表示的字节数组? 我不知道,但在 android 本机代码中,我可以使用 Gson 成功地将 JSON 字符串(包含 Uint8List)转换为 Java 对象。在 Java 中,我将 Uint8List 转换为 byte[] 如果您在本机端将 JSON 解码回其组成部分,那么中间 JSON 形式的意义何在?只需将 Map&lt;String, dynamic&gt; 传递到 Dart-native 边界即可。映射的每个成员都可以是不同的(支​​持的)类型,例如字符串、布尔值、整数、浮点数、字节数组等。 【参考方案1】:

我猜你想要做的是在 Dart-native 边界上传递多个“参数”。为此使用Map&lt;String, dynamic&gt;。例如:

await _channel.invokeMethod('testMethod', <String, dynamic>
    'bytes': dataBuffer, // example Uint8List
    'someBool': true,
    'someInt': 123,
  
);

在本机端,您将获得一个映射或字典,其中包含作为键的键名和作为其本机等效项的值(例如 bool->Boolean 等)

【讨论】:

感谢您的回答。我不能完全做到这一点,但我可以尝试将另一个Map(包含dataBuffer,这次不转换为字符串)作为Map 的参数传递给invokeMethod 非常感谢!我做了我之前评论中所说的,它解决了我的问题。而不是将 JSON 转换为字符串并将其作为 Map 传递给 invokeMethod,然后在 iOS 中我将其作为普通的 NSDictionary 访问。【参考方案2】:

Objective-C 没有任何编译时类型安全工具,并将该责任留给开发人员。这里的异常表示您尝试使用数组对象,就好像它是 FlutterStandardTypedData 对象一样。但在运行时似乎并非如此。

我不知道 Dart 是如何将 Uint8List 序列化为 json,但查看异常,它看起来像是“[3,5,7]”。在 Objective-C 中反序列化它,你会得到一个整数数组,而不是 FlutterStandardTypedData。数组中的项目可能是 FlutterStandardTypedData 类型。

【讨论】:

那么,如何从 JSON 字符串中获取“‘‘FlutterStandardTypedData‘‘’?我是否应该将“dataBuffer”提取为一个整数数组,然后从该数组中创建一个“FlutterStandardTypedData”? 我不知道 Flutter 以及 FlutterStandardTypedData 的作用,但在 Objective-C 方面考虑,您需要将 json 反序列化为一个数组,并且该数组的每个成员都将是一个 int/float(或NS 编号)。只需在您的代码中放置一个断点并检查您在数组中的值的类型。 我试图从字典中提取数组作为NSArray,将其转换为NSData 对象,然后转换为FlutterStandardTypedData 对象,但我无法访问缓冲区,所以我认为在这个过程中有些东西被破坏了。 不要将 NSArray 转换为 NSData。只需像 arr[0] 这样访问数组的成员,您就会在那里找到一个 int 或一个 NSNumber。 谢谢@Srdr,但我用 Richard Heap 的回答解决了我的问题。请看他回答下的cmets。

以上是关于从字典访问 FlutterStandardTypedData 时出现“[__NSArrayI 数据]:无法识别的选择器”的主要内容,如果未能解决你的问题,请参考以下文章

从 Parse 访问字典数据并在 Tableview Cell 上显示

如何通过创建字典从python中的以下映射访问城市名称

Django模板:从字典访问值列表

尝试从 Pandas DataFrame 中的字典访问第一个值时出现浮点错误

从字典的 JSON 数组访问键/值 C#,Unity [重复]

从 pandas.core.series.Series 字典中访问唯一项目