Flutter plugin: invoking iOS and Android method including parameters not working

9,068

Solution 1

This looks like a swift syntax error.

You want to do let someInfo1 : String = args[“someInfo1”]

Solution 2

With the help of miguelpruivo, I found the solution.

Here is the working code:

The Flutter-world in Dart was correct:

import 'dart:async';
import 'package:flutter/services.dart';

class SomeName {
  static const MethodChannel _channel =
      const MethodChannel('myTestMethod');

  static Future<String> get sendParamsTest async {
    final String version = await _channel.invokeMethod('sendParams',<String, dynamic>{
        'someInfo1': "test123",
        'someInfo2': 3.22,
      });
    return version;
  }
}

.

And here below, the iOS-world in Swift - now working as well...

(Dart's dynamic corresponds to Swift's Any)

(the method parameter is a dictionary of type [String:Any] - kind of like Swift's often used userInfo - therefore you need to cast at the receiver handler)...

import Flutter
import UIKit

public class SwiftSomeNamePlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(name: "myTestMethod", binaryMessenger: registrar.messenger())
    let instance = SwiftSomeNamePlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {

    // flutter cmds dispatched on iOS device :
    if call.method == "sendParams" {

      guard let args = call.arguments else {
        return
      }
      if let myArgs = args as? [String: Any],
         let someInfo1 = myArgs["someInfo1"] as? String,
         let someInfo2 = myArgs["someInfo2"] as? Double {
        result("Params received on iOS = \(someInfo1), \(someInfo2)")
      } else {
        result(FlutterError(code: "-1", message: "iOS could not extract " + 
           "flutter arguments in method: (sendParams)", details: nil))
      } 
    } else if call.method == "getPlatformVersion" {
      result("Running on: iOS " + UIDevice.current.systemVersion)
    } else {
      result(FlutterMethodNotImplemented)
    }
  }
}
Share:
9,068
iKK
Author by

iKK

Updated on December 08, 2022

Comments

  • iKK
    iKK over 1 year

    Trying my first Flutter plugin, I try to invoke a method in both, the iOS and the Android-world. I successfully was able to invoke such a method without any parameters.

    But now I would like to invoke a method that has parameters.

    For iOS, I can't get it to work for some reason. (maybe it is just an autocomplete thing that I keep overseeing since VSCode is not autocompleting my Swift code). But maybe it is something else. Please any help on this.

    Here is my code:

    My lib (Flutter-world) looks like this:

    import 'dart:async';
    import 'package:flutter/services.dart';
    
    class SomeName {
      static const MethodChannel _channel =
          const MethodChannel('myTestMethod');
    
      static Future<String> get sendParamsTest async {
        final String version = await _channel.invokeMethod('sendParams',<String, dynamic>{
            'someInfo1': "test123",
            'someInfo2': "hello",
          });
        return version;
      }
    }
    

    .

    My swift plugin (iOS-world) looks like this:

    import Flutter
    import UIKit
    
    public class SwiftSomeNamePlugin: NSObject, FlutterPlugin {
    
      public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "myTestMethod", binaryMessenger: registrar.messenger())
        let instance = SwiftSomeNamePlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
      }
    
      public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    
        // flutter cmds dispatched on iOS device :
        if call.method == "sendParams" {
    
          guard let args = call.arguments else {
            result("iOS could not recognize flutter arguments in method: (sendParams)") 
          }
          String someInfo1 = args["someInfo1"]
          String someInfo2 = args["someInfo2"]
          print(someInfo1)
          print(someInfo2)
          result("Params received on iOS = \(someInfo1), \(someInfo2)")
        } else {
          result("Flutter method not implemented on iOS")
        }
      }
    }
    

    The error messages say:

    note: add arguments after the type to construct a value of the type String someInfo1 = args["someInfo1"]

    note: add arguments after the type to construct a value of the type String someInfo2 = args["someInfo2"]

    note: use '.self' to reference the type object String someInfo1 = args["someInfo1"]

    note: use '.self' to reference the type object String someInfo2 = args["someInfo2"]

    warning: expression of type 'String.Type' is unused String someInfo1 = args["someInfo1"]

    warning: expression of type 'String.Type' is unused String someInfo2 = args["someInfo2"]

  • iKK
    iKK over 5 years
    Thank you, miguelpruivo! Of course :). There was too much Dart, Swift, Java mixture these days... ;)... I present the working version as an answer. Again thanks for your hint !!
  • Miguel Ruivo
    Miguel Ruivo over 5 years
    No problem, glad to help.