美文网首页
Flutter与Xcode那些事

Flutter与Xcode那些事

作者: 大王叫我来巡山丨 | 来源:发表于2022-01-08 17:41 被阅读0次

Hi, 各位看官, 里边请! 😁
最近在搞Flutter, 来跟各位随便唠唠! 今天我们不说语法, 也不说 widget 哈! 有兴趣的小伙伴可以点击链接去查看Flutter相关内容!

今天跟看官们说说, Flutter 与 iOS交互的那些事! 由于我的本没有安装 Android Studio, 则用VS Code来说, 本期主要围绕着 Xcode 来讲!
关于安卓其结构都一样, 后期会推出!

在iOS 原有的项目中集成Flutter

原有的项目我就不做展示了哈, 我用一个Demo 来演示! 其效果是一样

  • 首先打开终端, 输入 flutter create --template module my_flutter, 创建 module, 命名为my_flutter

    然后打开module, ( Tip: 在集成进 Xcode之前, model 最好先运行起来)

  • 我相信身为iOS开发者对CocoaPods都不陌生吧, 本期将通过CocoaPods管理, 把刚刚创建的 Flutter module 集成到项目中

1.打开 Podfile 文件, 在其中添加 module 本地路径:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

# 添加模块所在路径
flutter_application_path = '../my_flutter'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')


target 'useFlutter' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  # 安装Flutter模块
  install_all_flutter_pods(flutter_application_path)

end
  1. 添加完成后,保存退出! 然后 pod install

3.打开Xcode项目, 在AppDelegate中创建引擎

class AppDelegate: UIResponder, UIApplicationDelegate {

    // 1. 创建 flutterEngine  name: 引擎名称
    lazy var flutterEngine = FlutterEngine(name: "Evan_Engine")

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // 2.启动引擎
        flutterEngine.run()
        
        return true
    }
}

4.来到 ViewController中来使用 Flutter module

// 该函数为Button点击事件
@IBAction func flutterPush(_ sender: Any) {
        // 3. 创建FlutterViewController对象(需要先获取flutterEngine)
        let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine;
        let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil);
        flutterViewController.modalPresentationStyle = .fullScreen
        self.present(flutterViewController, animated: true, completion: nil)
  }

我们也可以省略预先创建的 FlutterEngine :
但不推荐这样来做,因为在第一针图像渲染完成之前,可能会出现明显的延迟。

@IBAction func flutterPush(_ sender: Any) {
  let flutterViewController = FlutterViewController(project: nil, nibName: nil, bundle: nil)
  present(flutterViewController, animated: true, completion: nil)
}
  1. 把项目运行起来, 点击Button, 来看看效果


哈哈, 是不是感觉好简单!

Tip: 不要把 widget 作为 view 来与原生的同一个页面上混用, 可能会有不可预知行为! 切记切记

  • 虽说是用Xcode在运行, 但我们还是可以继续来使用 Hot Reload


  1. 打开 module, 在终端执行 flutter attach, 链接成功后, 如下图


2.此时我们就可以去修改代码, 将 Text 字体颜色改为red, 修改完后先保存, 然后在VS Code 终端中输入 r, 则执行了Hot reload, 此时屏幕也随之发生了改变, 大功告成! 😁


注意: 目前一些场景依然是有限制的:
  • 运行多个Flutter实例,或在屏幕局部上运行Flutter可能会导致不可以预测的行为;
  • 在后台模式使用Flutter的能力还在开发中(目前不支持);
  • 将Flutter库打包到另一个可共享的库或将多个Flutter库打包到同一个应用中,都不支持;
  • 添加到应用在Android平台的实现基于 FlutterPlugin 的 API,一些不支持FlutterPlugin 的插件可能会有不可预知的行为。
Flutter 与 iOS 交互
  • 打开Flutter 项目, 创建 StatefulWidget,
    1. 创建通信对象 MethodChannel
    2. 调用原生的函数 getOriginalContent
class MyInteractionBody extends StatefulWidget {
  @override
  _MyInteractionBodyState createState() => _MyInteractionBodyState();
}

class _MyInteractionBodyState extends State<MyInteractionBody> {

// 1.创建通信对象  MethodChannel 
static const platForm = MethodChannel('Evan_channel');

  var _content = '文案';

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
      Text(_content),
      SizedBox(height: 10,),
      TextButton(
      child: Text('调用原生函数'), 
      onPressed: getContent)
    ],
    ),
    );
  }

  void getContent() async {
    // 2. 调用原生的函数 getOriginalContent, 等待回调
    final result = await platForm.invokeMethod('getOriginalContent');
    setState(() {
      _content = result;
    });
  }
}

  1. 使用Xcode打开Flutter 中 ios文件中的项目, 在需要处添加以下代码
// 1.获取 FlutterViewController
    if let controller: FlutterViewController = window.rootViewController as? FlutterViewController {
        
        // 2. FlutterMethodChannel
        let channel = FlutterMethodChannel(name: "Evan_channel", binaryMessenger: controller.binaryMessenger)
        
        // 3.监听 channel 调用方法
        channel.setMethodCallHandler { (call: FlutterMethodCall, result:  @escaping FlutterResult) in
            // 函数名称
            if call.method == "getOriginalContent" {

                // 如果没有获取到,那么返回给Flutter端一个异常
                // result(FlutterError(code: "0", message: "错误", details: nil))
            
                // 通过result将结果回调给Flutter端
                result(self.getOriginalContent())
            } else {
                // 未找到
               result(FlutterMethodNotImplemented)
            }
        }
    }

func getOriginalContent() -> String { "已经与原生成功交互" }

到此交互就可以使用了!

好了, Flutter 与 Xcode 交互这点事, 大体上也都跟各位看官唠完了, 以上只是一些基本简单用法, 更多的技能还需要用各位去探索, 研究哦!

相关文章

网友评论

      本文标题:Flutter与Xcode那些事

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