flutter--OC 原生混编

一、集成混合开发环境

001 建立flutter_module 

% flutter create -t module flutter_module
Creating project flutter_module...
  flutter_module/test/widget_test.dart (created)
  flutter_module/flutter_module.iml (created)
  flutter_module/.gitignore (created)
  flutter_module/.metadata (created)
  flutter_module/pubspec.yaml (created)
  flutter_module/README.md (created)
  flutter_module/lib/main.dart (created)
  flutter_module/flutter_module_android.iml (created)
  flutter_module/.idea/libraries/Dart_SDK.xml (created)
  flutter_module/.idea/modules.xml (created)
  flutter_module/.idea/workspace.xml (created)
Running "flutter pub get" in flutter_module...                      2.7s
Wrote 11 files.

All done!
Your module code is in flutter_module/lib/main.dart.

flutter_module文件下所有文件

flutter_module % ls -al 
total 64
drwxr-xr-x  16   staff   512  3 13 10:17 .
drwxr-xr-x   3   staff    96  3 13 10:17 ..
drwxr-xr-x  12   staff   384  3 13 10:17 .android
drwxr-xr-x   3   staff    96  3 13 10:17 .dart_tool
-rw-r--r--   1   staff   446  3 13 10:17 .gitignore
drwxr-xr-x   5   staff   160  3 13 10:17 .idea
drwxr-xr-x   7   staff   224  3 13 10:17 .ios
-rw-r--r--   1   staff   309  3 13 10:17 .metadata
-rw-r--r--   1   staff  3207  3 13 10:17 .packages
-rw-r--r--   1   staff   325  3 13 10:17 README.md
-rw-r--r--   1   staff   896  3 13 10:17 flutter_module.iml
-rw-r--r--   1   staff  1465  3 13 10:17 flutter_module_android.iml
drwxr-xr-x   3   staff    96  3 13 10:17 lib
-rw-r--r--   1   staff  4079  3 13 10:17 pubspec.lock
-rw-r--r--   1   staff  3466  3 13 10:17 pubspec.yaml
drwxr-xr-x   3   staff    96  3 13 10:17 test

003 新建一个OC原生项目并放在和fluter_module同一个目录下

004 利用cocoaPods讲flutter 集成到NativeDemo中

关闭bitcode

新建一个Podfile文件便于集成flutter_module

 NativeDemo % cat Podfile
platform :ios, '9.0'
use_frameworks!
target 'NativeDemo' do
  flutter_application_path = '../flutter_module_2021'
  load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
  install_all_flutter_pods(flutter_application_path)
end

podhelper.rb 脚本会把你的 plugins, Flutter.framework,和 App.framework 集成到你的项目中。

二、OC调flutter页面

AppDelegate文件中

//
//  AppDelegate.h
//  NativeDemo
//
//  Created by maochengfang on 2021/3/13.
//

#import <UIKit/UIKit.h>

@import Flutter;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic,strong) FlutterEngine *flutterEngine;

@end
//
//  AppDelegate.m
//  NativeDemo
//
//  Created by maochengfang on 2021/3/13.
//

#import "AppDelegate.h"
#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h>

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    self.flutterEngine = [[FlutterEngine alloc] initWithName:@"my flutter engine"];
     // Runs the default Dart entrypoint with a default Flutter route.
     [self.flutterEngine run];
     // Used to connect plugins (only if you have plugins with iOS platform code).
     [GeneratedPluginRegistrant registerWithRegistry:self.flutterEngine];
    return YES;
}


#pragma mark - UISceneSession lifecycle


- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}


- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}


@end

ViewController中

//

//  ViewController.m

//  NativeDemo

//

//  Created by maochengfang on 2021/3/13.

//



#import "ViewController.h"

#import <Flutter/Flutter.h>

#import "AppDelegate.h"





@interface ViewController ()

@property (nonatomic,strong) FlutterEngine *flutterEngine;



@end



@implementation ViewController



- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    

    // Make a button to call the showFlutter function when pressed.

       UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

       [button addTarget:self

                  action:@selector(showFlutter)

        forControlEvents:UIControlEventTouchUpInside];

       [button setTitle:@"Show Flutter!" forState:UIControlStateNormal];

       button.backgroundColor = UIColor.blueColor;

       button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);

       [self.view addSubview:button];

}



- (void)showFlutter {

    FlutterEngine *flutterEngine =

        ((AppDelegate *)UIApplication.sharedApplication.delegate).flutterEngine;

    FlutterViewController *flutterViewController =

        [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];

    [self presentViewController:flutterViewController animated:YES completion:nil];

}



@end

三、flutter给OC发送消息

fluttr代码

import 'package:flutter/material.dart';

import 'dart:ui';

import 'package:flutter/services.dart';
import 'package:vector_math/vector_math_64.dart';
void main() => runApp(MyApp(pageIndex: window.defaultRouteName,));


class MyApp extends StatefulWidget {
  final String pageIndex;
  MyApp({Key key,this.pageIndex}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final MethodChannel _oneChannel = MethodChannel('one_page');
  final MethodChannel _twoChannel = MethodChannel('two_page');
  final BasicMessageChannel _messageChannel = BasicMessageChannel('messageChannel', StandardMessageCodec());

  String _pageIndex = 'one';

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _messageChannel.setMessageHandler((message) {
      print('收到来自IOS的:$message');
    });

    _oneChannel.setMethodCallHandler((MethodCall call){
      _pageIndex = call.method;

       print('收到来自IOS的:$_pageIndex');
      setState(() {
        
      });
    });

    _twoChannel.setMethodCallHandler((MethodCall call) {
      
      _pageIndex = call.method;
       print('收到来自IOS的:$_pageIndex');
      setState(() {
        
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
       child: MaterialApp(
         title: 'Flutter Page-Oliver',
         theme: ThemeData(
          //  primaryColor: Colors.greenAccent
         ),
         home: rootPage(_pageIndex),
       ),
    );
  }

  Widget rootPage(String index){

    switch(index){
      case 'one':
        return Scaffold(
          body: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              GestureDetector(
                onTap: (){
                  _oneChannel.invokeMethod('exit','arg');
                },
                child: Container(
                  width: 100,
                  height: 50,
                  // color: Colors.red,
                  child: Text('one'),
                ),
              ),
              TextField(
                onChanged: (String str){
                _messageChannel.send(str);
              },),
            ],
          ),
        );
     
      break;

    case 'two':
      return Center(
        child: GestureDetector(
          onTap: (){
            _twoChannel.invokeMethod('exit','arg');
          },
          child: Container(
            width: 100,
            height: 100,
            child: Text('Two',style: TextStyle(fontSize: 20),),
            // color: Colors.blue,
          ),
        ),
      );
    break;


      
    }

    
  }
}

OC代码

- (void)showFlutterOne {
    
    FlutterMethodChannel * methodChannel = [FlutterMethodChannel methodChannelWithName:@"one_page" binaryMessenger:self.vc];
    
    //监听退出
    [methodChannel invokeMethod:@"one" arguments:nil];
    [methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        if ([call.method isEqualToString:@"exit"]) {
            [self.vc dismissViewControllerAnimated:NO completion:nil];
        }
    }];
//    FlutterViewController *flutterViewController =
//        [[FlutterViewController alloc] initWithEngine:flutterEngine nibName:nil bundle:nil];
    
    [self presentViewController:self.vc animated:YES completion:nil];
}

四、总结

混合开发实质上就是通过一个桥接的模式进行数据交互

flutter和OC原生之间定义好方法通道 定义好对应的Key和参数 

flutter需要定义好MethodChannel

final MethodChannel _oneChannel = MethodChannel('one_page');

flutter MethodChannel 渠道传递给OC的参数,final MethodChannel _oneChannel = MethodChannel('one_page'); _oneChannel.invokeMethod('exit','arg');OC也要定义好FlutterMethodChannel 变量所代表的那个key 监听flutter传过来的Key做一些操作setMethodCallHandler

参考资料

示例图1:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值