原生通信系列

1. Flutter 调用 Android
2. Android 通知 Flutter
3. Flutter 调用 iOS
4. iOS 通知 Flutter

项目地址


本篇要介绍的是 flutter 调用 iOS 篇

如果你没有看过我的前 2 篇,建议看一下. dart 端会承接上一篇的结果

dart

import 'dart:async';

import 'package:flutter/services.dart';

class BattlePower {
  static const MethodChannel _channel = const MethodChannel('battle_power');

  static Future<String> get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }

  static Future<int> requestNativeAdd(int x, int y) async {
    int result = await _channel.invokeMethod('add', {"x": x, "y": y});
    return result;
  }

  //....
}

这里和第一篇一样

不详细介绍了


这里是以 oc 为例的,不建议用 swift 开发插件,尤其是开源插件

当然如果你自用 还是可以用 swift 的. 后面有机会会更新一下 swift 的版本

找到你的 oc 插件文件夹

如果你是苹果的死忠那就用 xcode 就好 不然 jetbrains 有一款 AppCode 很适合开发 oc,比 xcode 开发的体验好很多

图片

这里参考截图这里打开 会发现不太对 图片 只有 Runner 部分,没有  插件部分,这时候需要在命令行做如下操作

cd example/ios
pod install

大概会得到如下的输出 图片

这时候关闭 xcode 重新点 open in xcode

打开后应该会看到项目变成了两个,这就说明你成功了,参考下图 图片

接着准备开发插件


这里比较坑,对于初次开发插件的人来说可能不太好找

图片

点开那个.m 就对了

如果不会 oc 语法 你还是需要熟悉下的. 你看这篇文章学不到 oc 语法 😄😉

oc 代码

#import "BattlePowerPlugin.h"

@implementation BattlePowerPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"battle_power"
            binaryMessenger:[registrar messenger]];
  BattlePowerPlugin* instance = [[BattlePowerPlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
    result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  } else {
    result(FlutterMethodNotImplemented);
  }
}

@end

略微分析下:

这里使用 [FlutterMethodChannel methodChannelWithName] 来定义插件的方法

使用 handleMethodCall 来处理调用

关于 dart-oc 类型对应查看文档

添加方法

dart 中有一个 add 方法,我们在 OC 中添加这个 add 方法

#import "BattlePowerPlugin.h"

@implementation BattlePowerPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel* channel = [FlutterMethodChannel
                                     methodChannelWithName:@"battle_power"
                                     binaryMessenger:[registrar messenger]];
    BattlePowerPlugin* instance = [[BattlePowerPlugin alloc] init];
    [registrar addMethodCallDelegate:instance channel:channel];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([@"getPlatformVersion" isEqualToString:call.method]) {
        result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
    } if([@"add" isEqualToString:call.method]){
        NSDictionary *args = call.arguments;
        int x = [[args valueForKey:@"x"] intValue];
        int y = [[args valueForKey:@"y"] intValue];
        NSNumber *sum = [NSNumber numberWithLong:(x+y)];
        result(sum);
    }else {
        result(FlutterMethodNotImplemented);
    }
}

@end

这里参考文档可知

图片

我传入的参数在 dart 端会被解析为Map ,到了 oc 中会变成NSDictionary,然后通过 key 获取到对应的值

 接着将 x y 相加后传为NSNumber传回 dart 即可


这样一个简单的插件交互方法就完成了

这里是 dart => oc 的传递

如果你是对于 oc 如何通知 dart 请看第四篇