3

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"]

2 Answers 2

16

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)
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

This looks like a swift syntax error.

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

1 Comment

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 !!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.