Flutter 集成到現有iOS工程


前沿

由於我司已經有自己的App,flutter屬於技術引進的一部分,也不太可能重新啟動一個項目,因此目前我們是將flutter模塊形式注入我們的App之中。即:將flutter模塊集成到現在有iOS工程之中。

 

目錄

  1. 創建flutter模塊工程
  2. 使用pod 將flutter 模塊工程添加到現有工程之中
  3. code 執行flutter 工程
  4. 運行熱更新

 

 

1. 創建flutter模塊工程

我這里是使用Android Studio 創建flutter工程,如下:

 

 

當然也可以使用flutter命令行進行創建,命令如下:

$ cd some/path/
$ flutter create -t module my_flutter
工程結構 和我們的iOS 工程保持相對目錄,結構如下:
some/path/
  my_flutter/
    lib/main.dart
    .ios/
  MyApp/
    MyApp/
      AppDelegate.h
      AppDelegate.m (or swift)
      :
 
        

2. 使用pod 將flutter 模塊工程添加到現有工程之中

2.1 podfile 文件之中引入 flutter模塊工程

####Flutter###
flutter_application_path = '../my_flutter' //目錄結構按照具體我們存儲的路徑進行
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)

2.2 然后執行pod install

2.3 ENABLE_BITCODE  設置為NO

2.4 Build Phares 添加 以下腳本(+ 號添加一個新的腳本,然后復制下面的內容)

"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed

執行編譯即可

 

 最新版本集成 (最新版本已經優化了很多東西,不需要配置sh)

####Flutter###
flutter_application_path = 'somepath/flutter_rokid'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')

target 'App' do

    install_all_flutter_pods(flutter_application_path)

     ....

 end

 

 

3.code 執行flutter 工程

1. AppDelete.h 配置

import FlutterPluginRegistrant // Only if you have Flutter Plugins.


@UIApplicationMain

class AppDelegate: FlutterAppDelegate {
  ...

        self.flutterEngine = FlutterEngine(name: "xxx.flutter", project: nil);

        self.flutterEngine?.run(withEntrypoint: nil);

        GeneratedPluginRegistrant.register(with: self.flutterEngine);

   ...
}

 

2. 業務方調用

import Foundation
import Flutter

class RKFlutterDemo : UIViewController {
    override func viewDidLoad() {
        title = "flutter "
        var button = UIButton(type:UIButtonType.custom)
        button.addTarget(self, action: #selector(handleButtonAction), for: .touchUpInside)
        button.setTitle("Press me", for: UIControlState.normal)
        button.frame = CGRect(x: 80.0, y: 210.0, width: 160.0, height: 40.0)
        button.backgroundColor = UIColor.blue
        self.view.addSubview(button)
        
        button = UIButton(type:UIButtonType.custom)
        button.addTarget(self, action: #selector(handleButtonAction1), for: .touchUpInside)
        button.setTitle("Press me v1", for: UIControlState.normal)
        button.frame = CGRect(x: 80.0, y: 270.0, width: 160.0, height: 40.0)
        button.backgroundColor = UIColor.blue
        self.view.addSubview(button)
        
        button = UIButton(type:UIButtonType.custom)
        button.addTarget(self, action: #selector(handleButtonAction2), for: .touchUpInside)
        button.setTitle("Press me v2", for: UIControlState.normal)
        button.frame = CGRect(x: 80.0, y: 330.0, width: 160.0, height: 40.0)
        button.backgroundColor = UIColor.blue
        self.view.addSubview(button)
        
    }
    
  //全局生命周期,即便是 VC 退出頁面下次打開還是會 停留在上一次操作結果(所以適合全局性頁面) @objc func handleButtonAction() { let flutterEngine
= (UIApplication.shared.delegate as? AppDelegate)?.flutterEngine; let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)!; self.navigationController?.pushViewController(flutterViewController, animated: true) }
//每次都會創建實例 @objc func handleButtonAction1(){ let flutterViewController
= FlutterViewController(); self.navigationController?.pushViewController(flutterViewController, animated: true) }
//如果一個模塊有多個 頁面導航,則需要設置路由進行跳轉 @objc func handleButtonAction2(){ let flutterViewController
= FlutterViewController(); flutterViewController.setInitialRoute("router1") //跳轉到路由 self.navigationController?.pushViewController(flutterViewController, animated: true) } }

 

 

4. 運行熱更新

其實在我們App 集成完成之后,我們還是可以在flutter工程之中直接運行到我們自己的工程之中

4.1  使用Xcode運行我們的App  Command+R 運行

4.2 cd 到 在flutter 工程下 執行命令行:

flutter attach

 

這樣我們直接編寫 ,然后在 命令行中 按住 r 就可以 直接更新 App 中的頁面了

備注:在3的打開方式之中 只能以下模式的頁面可以更新

   @objc func handleButtonAction() {
        let flutterEngine = (UIApplication.shared.delegate as? AppDelegate)?.flutterEngine; let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)!; self.navigationController?.pushViewController(flutterViewController, animated: true) }

 

 

參考文獻

https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps#experiment-turn-the-flutter-project-into-a-module


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM