iOS舊工程集成Flutter最新教程

嘗試在原iOS工程里添加Flutter模塊,碰到問(wèn)題,發(fā)現(xiàn)網(wǎng)上的教程比較陳舊,所以寫一篇最新教程。 ##創(chuàng)建Flutter moudle 一般把Flutter moudle放在iOS工程同級(jí),然后執(zhí)行命令

cd 項(xiàng)目根目錄
flutter create --template module my_flutter

執(zhí)行完畢后,F(xiàn)lutter module將會(huì)創(chuàng)建在 ios項(xiàng)目/my_flutter目錄下,目錄結(jié)構(gòu)如下圖:


image.png

.ios 是隱藏目錄,可以單獨(dú)運(yùn)行Flutter module,測(cè)試此模塊的功能,iOS代碼添加到現(xiàn)有應(yīng)用程序的項(xiàng)目或插件中,而不是添加到模塊的.ios /目錄中。由于.ios /目錄是自動(dòng)生成的,因此請(qǐng)勿對(duì)其進(jìn)行源代碼控制。在新機(jī)器上構(gòu)建模塊之前,請(qǐng)先在my_flutter目錄中運(yùn)行flutter pub get來(lái)重新生成.ios /目錄,然后再使用Flutter模塊構(gòu)建iOS項(xiàng)目。

使用CocoaPods將Flutter模塊嵌入到現(xiàn)有應(yīng)用程序中
修改iOS應(yīng)用程序中 Podfile 文件,內(nèi)容如下:


image.png

需要注意的是,F(xiàn)lutter模塊和iOS工程位于同級(jí)目錄中,如果在不同的目錄中,需要調(diào)整相對(duì)路徑。 執(zhí)行pod install命令,執(zhí)行完畢后,再通過(guò)命令生成Frameworks:


image.png

Frameworks 已經(jīng)生成,然后將 App.framework 和 Flutter.framework 拖入Build Settings > Build Phases > Link Binary With Libraries:


image.png

此時(shí)在項(xiàng)目的左側(cè)增加 Frameworks 目錄:


image.png

然后開始運(yùn)行,發(fā)現(xiàn)報(bào)錯(cuò):
image.png

解決方法: 找到Build Phases > [CP-User],直接叉掉即可。
找到Build Phases > [CP-User],直接叉掉即可。
創(chuàng)建 FlutterEngine 和 FlutterViewController
將 Flutter 頁(yè)面嵌入 iOS 應(yīng)用程序需要?jiǎng)?chuàng)建 FlutterEngine(Flutter 引擎) 和 FlutterViewController,F(xiàn)lutterEngine 是Dart VM和Flutter運(yùn)行時(shí)的 host,F(xiàn)lutterViewController 附著于 FlutterEngine,作用是通信和顯示 Flutter UI。
創(chuàng)建 FlutterEngine:
import UIKit
import Flutter

@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
lazy var flutterEngine = FlutterEngine(name: "my flutter engine")

override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

flutterEngine.run();

return super.application(application, didFinishLaunchingWithOptions: launchOptions);

}
}
添加一個(gè)按鈕,跳轉(zhuǎn)到 Flutter 頁(yè)面:

import UIKit
import Flutter

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    let button = UIButton(type:UIButton.ButtonType.custom)
    button.addTarget(self, action: #selector(showFlutter), for: .touchUpInside)
    button.setTitle("顯示 Flutter", for: UIControl.State.normal)
    button.frame = CGRect(x: 80.0, y: 210.0, width: 160.0, height: 40.0)
    button.backgroundColor = UIColor.blue
    self.view.addSubview(button)
}

@objc func showFlutter() {
  let flutterEngine = (UIApplication.shared.delegate as! AppDelegate).flutterEngine
  let flutterViewController =
      FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
  present(flutterViewController, animated: true, completion: nil)
}

}

image.png

上面的代碼使用了緩存 FlutterEngine,當(dāng)然這也是推薦的一種方式。還有一種方式是是使用隱含的FlutterEngine,使用隱含的FlutterEngine會(huì)明顯增加顯示Flutter UI的時(shí)間,通常不建議這樣做,如果很少顯示 Flutter 屏幕,沒(méi)有好的方法來(lái)確定何時(shí)啟動(dòng)Dart VM以及何時(shí)Flutter不需要在視圖控制器之間保持狀態(tài),則這可能很有用。

func showFlutter() {
let flutterViewController = FlutterViewController(project: nil, nibName: nil, bundle: nil)
present(flutterViewController, animated: true, completion: nil)
}

指定入口點(diǎn)
默認(rèn)情況下 FlutterEngine 加載 lib/main.dart 文件中的 main() 方法,也可以指定其他文件的方法:
less復(fù)制代碼flutterEngine.run(withEntrypoint: "newEntrypoint", libraryURI: "main.dart")
初始化路由
從Flutter 1.22版開始,可以指定路由
less復(fù)制代碼let flutterEngine = FlutterEngine()
flutterEngine.run(
withEntrypoint: FlutterDefaultDartEntrypoint, initialRoute: "/one_page")

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容