medyas
medyas

Reputation: 1286

Flutter pass Uint8List to iOS Objective-c

I am trying to pass an image as Uint8List to native code Android/iOS from Flutter, but getting an error in iOS side. I am modifying a plugin and i never developed in iOS before. Here is the Flutter code to capture an image from widget and send the Uint8List to native code.

  Future<void> _capturePng() async {
    RenderRepaintBoundary boundary =
    globalKey.currentContext.findRenderObject();
    ui.Image image = await boundary.toImage(pixelRatio: 1.50);
    ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
    Uint8List pngBytes = byteData.buffer.asUint8List();

    printer.printImage(pngBytes);
  }

In Android, i am using Kotlin:

private fun printImage(call: MethodCall, result: Result) {
    val image = call.arguments as ByteArray
    val res = mPrinterPlugin.printImage(image)
    result.success(res)
}

In iOS, the plugin is written in Objective-C. i added this check for my image

else if([@"imagePrint" isEqualToString:call.method]){

     NSData *imgBytes = call.arguments;

     UIImage *label = [UIImage imageWithData:imgBytes];

 }

I saw that Uint8List is FlutterStandardTypedData typedDataWithBytes in iOS, but when i set the imgBytes type to it i get an error.

Upvotes: 0

Views: 1584

Answers (2)

BT b killin me
BT b killin me

Reputation: 81

I just dealt with this. Letting Xcode do its magical conversion was burning me. For instance, in your iOS plugin implementation, the line:

NSData *imgBytes = call.arguments;

When i was doing this, in Xcode the debugger would see the data type would come through as a FlutterStandardTypedData (as i passed in a list of ints) but every time i would try to access an element/object it would give me memory errors. It was like Xcode was honoring my parameter list (NSArray) in reality, but showing me the data type as a FlutterStandardTypedData while debugging. Seemed like a bug in the IDE to be honest.

Just as the upvoted answer shows, i resolved by using the flutter data type:

FlutterStandardTypedData *bytesList = call.arguments[@"listOfBytes"];

Upvotes: 0

Igor Kharakhordin
Igor Kharakhordin

Reputation: 9913

You should take first argument as a typed data, probably:

NSArray *args = call.arguments;
FlutterStandardTypedData *list = args[0];

kotlin:

val args: List<Any> = call.arguments as List<Any>
val list = args[0] as ByteArray

and you invoke it like this:

Uint8List uint8List;
_channel.invokeMethod("your_function_name", [uint8List]);

Upvotes: 2

Related Questions