美文网首页
【Flutter】OC集成Flutter

【Flutter】OC集成Flutter

作者: 在这蓝色天空下 | 来源:发表于2020-04-01 20:32 被阅读0次

    项目地址:https://github.com/tianzhilan0/OCFlutter
    注:项目比较大600多兆

    最终效果图如下

    m0007-1fvip.gif

    1、创建OC项目

    image.png
    image.png

    2、添加cocoapods

    cd /Users/lc/Desktop/Test/OCFlutter 
    pod init
    pod install
    
    image.png

    3、创建Flutter 工程

    在OCFlutter项目的相同路径上创建module

    cd /Users/lc/Desktop/Test
    flutter create -t module flutter_module
    
    image.png

    4、在OCFlutter项目新建Config目录,在这个目录下新建3个配置文件

    • Flutter.xccofig,内容如下:

    #include "../flutter_module/.ios/Flutter/Generated.xcconfig"
    ENABLE_BITCODE=NO
    
    • Debug.xccofig,内容如下:

    #include "Flutter.xcconfig"
    #include "Pods/Target Support Files/Pods-iOS项目名称/Pods-iOS项目名称.debug.xcconfig"
    
    • Release.xccofig,内容如下:

    #include "Flutter.xcconfig"
    #include "Pods/Target Support Files/Pods-iOS项目名称/Pods-iOS项目名称.debug.xcconfig"
    FLUTTER_BUILD_MODE=release
    
    image.png
    image.png image.png image.png

    5、修改OCFlutter配置

    • 关闭Bitcode

    image.png
    • 修改运行环境

    image.png
    • 添加Run Script

    "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
    "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed
    
    image.png
    image.png
    • 修改Podfile内容,添加如下内容,添加完成之后再执行一次pod install

    flutter_application_path = '../flutter_module'
    eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
    
    image.png
    image.png

    6、运行一下flutter_module,生成一些文件,运行成功之后,关闭就行

    image.png

    7、在OCFlutter项目下添加Flutter目录

    • command+shift+。显示隐藏文件

    image.png
    • 在Flutter文件下添加flutter_assets

    将此处的flutter_assets拷贝至Flutter目录下,导入到项目

    image.png
    image.png
    • 在Flutter文件下添加App.framework

    将此处的App.framework拷贝至Flutter目录下,导入到项目

    image.png
    image.png
    • 在Flutter文件下添加engine

    将此处的engine拷贝至Flutter目录下,导入到项目

    image.png
    image.png
    • 最终显示如下样式

    image.png

    在此处编译一下OCFlutter项目,如不报错,则已准备完成,接下来就是撸代码了。

    8、撸代码

    • 修改AppDelegate.h代码

    #import <UIKit/UIKit.h>
    #import <Flutter/Flutter.h>
    
    
    @interface AppDelegate : FlutterAppDelegate <UIApplicationDelegate, FlutterAppLifeCycleProvider>
    
    @property (strong, nonatomic) UIWindow *window;
    
    
    @end
    
    • 修改AppDelegate.m代码

    
    #import "AppDelegate.h"
    
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    {
        FlutterPluginAppLifeCycleDelegate *_lifeCycleDelegate;
    }
    
    - (instancetype)init {
        if (self = [super init]) {
            _lifeCycleDelegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
        }
        return self;
    }
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        return [_lifeCycleDelegate application:application didFinishLaunchingWithOptions:launchOptions];
    }
    
    - (void)application:(UIApplication*)application
    didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings {
        [_lifeCycleDelegate application:application
    didRegisterUserNotificationSettings:notificationSettings];
    }
    
    - (void)application:(UIApplication*)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
        [_lifeCycleDelegate application:application
    didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
    }
    
    - (void)application:(UIApplication*)application
    didReceiveRemoteNotification:(NSDictionary*)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
        [_lifeCycleDelegate application:application
           didReceiveRemoteNotification:userInfo
                 fetchCompletionHandler:completionHandler];
    }
    
    - (BOOL)application:(UIApplication*)application
                openURL:(NSURL*)url
                options:(NSDictionary<UIApplicationOpenURLOptionsKey, id>*)options {
        return [_lifeCycleDelegate application:application openURL:url options:options];
    }
    
    - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url {
        return [_lifeCycleDelegate application:application handleOpenURL:url];
    }
    
    - (BOOL)application:(UIApplication*)application
                openURL:(NSURL*)url
      sourceApplication:(NSString*)sourceApplication
             annotation:(id)annotation {
        return [_lifeCycleDelegate application:application
                                       openURL:url
                             sourceApplication:sourceApplication
                                    annotation:annotation];
    }
    
    - (void)application:(UIApplication*)application
    performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem
      completionHandler:(void (^)(BOOL succeeded))completionHandler NS_AVAILABLE_IOS(9_0) {
        [_lifeCycleDelegate application:application
           performActionForShortcutItem:shortcutItem
                      completionHandler:completionHandler];
    }
    
    - (void)application:(UIApplication*)application
    handleEventsForBackgroundURLSession:(nonnull NSString*)identifier
      completionHandler:(nonnull void (^)(void))completionHandler {
        [_lifeCycleDelegate application:application
    handleEventsForBackgroundURLSession:identifier
                      completionHandler:completionHandler];
    }
    
    - (void)application:(UIApplication*)application
    performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
        [_lifeCycleDelegate application:application performFetchWithCompletionHandler:completionHandler];
    }
    
    - (void)addApplicationLifeCycleDelegate:(NSObject<FlutterPlugin>*)delegate {
        [_lifeCycleDelegate addDelegate:delegate];
    }
    
    #pragma mark - UISceneSession lifecycle
    - (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options  API_AVAILABLE(ios(13.0)){
        // 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  API_AVAILABLE(ios(13.0)){
        // 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.m中代码如下

    
    #import "ViewController.h"
    #import <Flutter/FlutterViewController.h>
    #import "LoginViewController.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }
    
    - (IBAction)jumpToFlutter:(id)sender {
        FlutterViewController* flutterViewController = [[FlutterViewController alloc]init];
        [flutterViewController setInitialRoute:@"pag1"];
        
        FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"com.pages.your/native_get" binaryMessenger:(NSObject<FlutterBinaryMessenger> *)flutterViewController];
        [channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
            NSString *method = [call method];
            if ([method isEqualToString:@"FlutterPopIOS"]) {
                NSLog(@"FlutterPopIOS:获取Flutter返回时传的值 == %@",[call arguments]);
                [self.navigationController popViewControllerAnimated:true];
            }
            if ([method isEqualToString:@"FlutterCickedActionPushIOSNewVC"]) {
                NSLog(@"FlutterCickedActionPushIOSNewVC:返回来传的参数是 == %@",[call arguments]);
                LoginViewController *loginCV = [[LoginViewController alloc] init];
                [self.navigationController pushViewController:loginCV animated:true];
            }
            if ([method isEqualToString:@"FlutterGetIOSArguments"]) {
                NSDictionary *dic = @{@"name":@"名字"};
                result(dic);
            }
            
        }];
        [self.navigationController pushViewController:flutterViewController animated:YES];
    }
    
    @end
    
    
    • flutter_modulemain.dart代码如下

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      // 创建一个给native的channel (类似iOS的通知)
      static const methodChannel = const MethodChannel('com.pages.your/native_get');
    
      String _textString = "null";
    
      void _backAction() {
        _iOSPushToVC();
      }
    
      _iOSPushToVC() async {
        await methodChannel.invokeMethod('FlutterPopIOS', '我是返回数据');
      }
    
      void _pushIOSNewVC() async {
        Map<String, dynamic> map = {
          "code": "200",
          "data": [1, 2, 3]
        };
    
        await methodChannel.invokeMethod('FlutterCickedActionPushIOSNewVC', map);
      }
    
      // 给客户端发送一些东东 , 并且拿到一些东东
      Future<Null> _flutterGetIOSArguments(para) async {
        dynamic result;
        try {
          result = await methodChannel.invokeMethod('FlutterGetIOSArguments', para);
          _textString = result["name"];
        } on PlatformException {
          result = 100000;
        }
        setState(() {});
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new Center(
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                RaisedButton(
                  onPressed: _backAction,
                  child: Text("返回原生"),
                ),
                RaisedButton(
                  onPressed: _pushIOSNewVC,
                  child: Text("跳转进入一个新的原生页面"),
                ),
                RaisedButton(
                  onPressed: () {
                    _flutterGetIOSArguments("flutter传值");
                  },
                  child: Text("从原生页面获取数据"),
                ),
                Text("从原生获取的内容:$_textString"),
              ],
            ),
          ),
        );
      }
    }
    
    

    相关文章

      网友评论

          本文标题:【Flutter】OC集成Flutter

          本文链接:https://www.haomeiwen.com/subject/nqzauhtx.html