前言
上一篇主要介紹iOS工程 和 Flutter工程編譯器上的操作,那么本文就來介紹下代碼上如何交互不见。
iOS 和Flutter界面跳轉(zhuǎn)
1、iOS跳轉(zhuǎn)Flutter工程
iOS跳轉(zhuǎn)Flutter工程這個是最簡單也是最容易的一種崔步,我們只需在已經(jīng)配置好的iOS工程(不知道怎么配置可看iOS混編Flutter 之我見一
如下操作:
頭文件引入Flutter
import UIKit
import Flutter
iOS跳轉(zhuǎn)代碼
let vc : FlutterViewController = FlutterViewController.init();
vc.fd_prefersNavigationBarHidden = true;//隱藏iOS工程導(dǎo)航欄
self.navigationController?.pushViewController(vc, animated: true);
2稳吮、iOS跳轉(zhuǎn)Flutter工程指定界面
跳轉(zhuǎn)到指定界面相比上面來說會復(fù)雜一點,我們查看FlutterViewController的Api會發(fā)現(xiàn)井濒,內(nèi)部有這樣一個方法
/**
* Sets the first route that the Flutter app shows. The default is "/".
* This method will guarnatee that the initial route is delivered, even if the
* Flutter window hasn't been created yet when called. It cannot be used to update
* the current route being shown in a visible FlutterViewController (see pushRoute
* and popRoute).
*
* @param route The name of the first route to show.
*/
- (void)setInitialRoute:(NSString*)route;
這時候我們就可以用這個Api來跳轉(zhuǎn)指定的界面,比如我這邊route到Home
Flutter 中main.dart端代碼
import 'dart:ui' as ui; // 調(diào)用window拿到route判斷跳轉(zhuǎn)哪個界面
void main() => runApp(jumpToRoute(ui.window.defaultRouteName));
Widget jumpToRoute(String route) {
switch (route) {
case 'fav':
return Fav();//route到Fav界面
case 'home':
return Home();//route到home界面
case 'detail':
return Detail();//route到Detail界面
default:
return Main();//route到整個app
}
}
Flutter中Home界面代碼
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
),
home:MyHomeCtrl(title: "",),
);
}
}
class MyHomeCtrl extends StatefulWidget{
MyHomeCtrl({Key key, this.title}) : super(key: key);
final String title;
@override
State<StatefulWidget> createState() {
return _MyHomeState();
}
}
接下來我們來看看iOS端的跳轉(zhuǎn)代碼
let vc : FlutterViewController = FlutterViewController.init();
vc.fd_prefersNavigationBarHidden = true;
vc.setInitialRoute("home");
self.navigationController?.pushViewController(vc, animated: true);
3灶似、iOS跳轉(zhuǎn)Flutter工程指定界面并發(fā)送數(shù)據(jù)
其實3和4很多時候是合在一起的這邊為了方便大家理解把他們分開講,為了方便理解我畫了一個圖如下瑞你。
簡單講就是跳轉(zhuǎn)Flutter界面的時候發(fā)送一組字典數(shù)據(jù)酪惭,F(xiàn)lutter收到這組數(shù)據(jù)的時候去請求數(shù)據(jù)。這是3者甲,我們來看看代碼上的實現(xiàn)春感。
iOS中跳轉(zhuǎn)的代碼實現(xiàn)
let vc : FlutterViewController = FlutterViewController.init();
vc.fd_prefersNavigationBarHidden = true;
vc.setInitialRoute("detail");
let eventChannel : FlutterEventChannel = FlutterEventChannel.init(name: "com.pages.event/detail", binaryMessenger: vc.binaryMessenger);
eventChannel.setStreamHandler(self);
self.navigationController?.pushViewController(vc, animated: true);
FlutterStreamHandler協(xié)議的實現(xiàn)
extension GKAboutController : FlutterStreamHandler{
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
//向flutter發(fā)送數(shù)據(jù)
print(arguments as Any);
let param :[String : String] = ["gender":"male","major":"玄幻"];
events(param)
return nil;
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
print(arguments as Any);
return nil;
}
}
Flutter中Detail界面代碼
頭文件引入
import 'package:flutter/services.dart';
class Detail extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
),
home:DetailCtrl(title: "",),
);
}
}
監(jiān)聽數(shù)據(jù)、類似iOS中的通知(注意Channel定義要和iOS的定義一致)
static const methodChannel = const MethodChannel('com.pages.method/detail'); //Flutter向iOS發(fā)送數(shù)據(jù)
static const eventChannel = const EventChannel('com.pages.event/detail');//接收iOS向Flutter發(fā)送過來的數(shù)據(jù)
接收數(shù)據(jù)
@override
void initState(){
super.initState();
eventChannel.receiveBroadcastStream(1).listen(onEvent,onError: onError);
loadData();
}
void onEvent(Object event) {
Map map = event;
String gender = map["gender"];
String title = map["major"];
widget.gender = gender;
widget.title = title;
loadData();
}
// 錯誤返回
void onError(Object error) {
print(error.toString());
}
這時候我們就可以拿到gender和major 這兩個數(shù)據(jù)的值,難后去做網(wǎng)絡(luò)請求鲫懒,獲取網(wǎng)絡(luò)數(shù)據(jù)嫩实。
4、Flutter跳轉(zhuǎn)iOS工程指定界面并發(fā)送數(shù)據(jù)
通過3我們了解到了iOS想Flutter發(fā)送數(shù)據(jù)窥岩,有時候僅僅發(fā)送數(shù)據(jù)是不夠的甲献,我們還需要接收數(shù)據(jù),所以很多時候發(fā)送數(shù)據(jù)和接收數(shù)據(jù)是聯(lián)系起來的颂翼。
在上面3中Flutter定義監(jiān)聽我們還多定義了一個
static const methodChannel = const MethodChannel('com.pages.method/detail'); //Flutter向iOS發(fā)送數(shù)據(jù)
這個就是Flutter要向iOS發(fā)送數(shù)據(jù)的監(jiān)聽晃洒,我們看下Flutter是如何向iOS發(fā)送數(shù)據(jù)的,上代碼
Fluttre代碼實現(xiàn)
methodChannel.invokeMethod('detail',{"bookId":male.sId});
這里的detail有時候我們需要發(fā)送多種數(shù)據(jù)朦乏,我們就可以用這個字段區(qū)分開球及。
看看iOS 代碼的實現(xiàn)
let vc : FlutterViewController = FlutterViewController.init();
vc.fd_prefersNavigationBarHidden = true;
vc.setInitialRoute("detail");
//iOS 向Flutter發(fā)送數(shù)據(jù)的EventChanne(EventChanne同F(xiàn)lutter)
let eventName = "com.pages.event/detail";
let eventChannel : FlutterEventChannel = FlutterEventChannel.init(name:eventName, binaryMessenger: vc.binaryMessenger);
eventChannel.setStreamHandler(self);
//iOS 接收Flutter發(fā)送過來數(shù)據(jù)的MethodChannel(MethodChannel同F(xiàn)lutter)
let methodName = "com.pages.method/detail";
let methodChannel : FlutterMethodChannel = FlutterMethodChannel.init(name:methodName, binaryMessenger: vc.binaryMessenger);
methodChannel.setMethodCallHandler { (call, result) in
if call.method == "detail"{
let json = JSON(call.arguments as Any);
let bookId = json["bookId"].stringValue
GKJump.jumpToDetail(bookId:bookId);
}
print(call.method);
print(call.arguments as Any);
};
self.navigationController?.pushViewController(vc, animated: true);
看下交互效果圖吧
以上4步基本上實現(xiàn)了iOS和Flutter代碼交互的邏輯。