天天看點

七爪源碼:将 Flutter View 添加到原生 iOS 應用程式

作者:莊志炎

讓我們探索如何将 Flutter 視圖添加到 iOS 原生視圖(如 UIViewController)中。

七爪源碼:将 Flutter View 添加到原生 iOS 應用程式

今天,我們将在 iOS 中實作一個簡單的示範應用程式,它将有兩個 Flutter 頁面,在第一個頁面上,我們将顯示使用者清單,第二個螢幕将是使用者詳細資訊螢幕。

我們将把 Flutter 子產品作為包庫嵌入到我們的原生 iOS 應用程式中。

為了便于了解,我将文章分為 4 個邏輯步驟。

  1. 建立 Flutter 子產品
  2. 從子產品生成 iOS 架構
  3. 将架構內建和嵌入到本機應用程式中
  4. 作為 UIViewController 打開顫動視圖

好吧,讓我們開始吧!

1.建立一個Flutter子產品

首先,如果您尚未在系統上安裝 Flutter SDK,那麼現在是安裝的好時機。繼續并按照此連結查找在您的機器上設定顫振的說明。

可以了,好了?偉大的 !!!

讓我們首先從現有的 Flutter 項目建立 Flutter 子產品。

從指令行界面,導航到您希望在 Flutter 項目中儲存 Flutter 子產品的目錄,然後使用 Flutter CLI 工具運作以下指令:

flutter create -template module --org com.demo flutter_lib           

此指令将建立一個帶有 .android 和 .ios 隐藏檔案夾的顫振子產品。這些檔案夾是自動生成的,是以不要進行任何更改。

然後在flutter_lib目錄下運作flutter pub get。

我們完成了設定。現在讓我們在子產品的 main.dart 中添加一個螢幕。

我們不打算介紹 Flutter 的實作。

這是我們的顫振子產品應用程式。完整的源代碼可在 GitHub 上找到。您可以将其從此處複制到您的 dart 檔案中。

最後,我們将擁有一個像下面這樣的應用程式。

七爪源碼:将 Flutter View 添加到原生 iOS 應用程式

2.從子產品生成iOS架構

現在,讓我們開始将 Flutter 子產品內建到我們的原生 iOS 應用程式中。

在 flutter_lib/lib 中的 main.dart 檔案中,我們已經定義了從 Native 子產品調用的入口點函數。

入口點函數是這樣的,

@pragma("vm:entry-point")
void nativeLoad() async {
    WidgetsFlutterBinding.ensureInitialized();
    runApp(MyApp());
}           

此函數将從 iOS 應用程式調用。 是以,調用此函數時啟動的任何 View 都将內建到 iOS 應用程式中。 我們将在下面進一步看到它的使用。

現在讓我們從 Flutter 子產品生成 iOS 架構。

根據 Flutter 文檔,我們有很多方法可以建立 iOS 架構并将其嵌入到原生項目中,但這裡我們将使用其第二個選項,即 Xcode 中的 Embed frameworks。

讓我們首先生成一個 iOS 架構。 從 flutter_lib 目錄運作此指令。

flutter build ios-framework           

它将建立 3 個單獨的架構目錄,如下所示。

some/path/MyApp/flutter_lib/build/ios
└── Flutter/
    ├── Debug/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework (only if you have plugins with iOS platform code)
    │   └── example_plugin.xcframework (each plugin is a separate framework)
    ├── Profile/
    │   ├── Flutter.xcframework
    │   ├── App.xcframework
    │   ├── FlutterPluginRegistrant.xcframework
    │   └── example_plugin.xcframework
    └── Release/
        ├── Flutter.xcframework
        ├── App.xcframework
        ├── FlutterPluginRegistrant.xcframework
        └── example_plugin.xcframework           

如果您隻想生成特定的單一建構類型,那麼它也是可能的。

假設我們隻想為調試應用程式生成一個架構,那麼指令将是這樣的,

flutter build ios-framework --no-release --no-profile           

或者

flutter build ios-framework --debug           

完畢? 現在,讓我們繼續吧。

3. 将架構內建并嵌入到原生應用程式中

生成的動态架構必須嵌入到您的應用程式中才能在運作時加載。

我們隻需将架構拖放到 iOS 項目的根目錄中即可嵌入架構。

它看起來像這樣,

七爪源碼:将 Flutter View 添加到原生 iOS 應用程式

現在我們必須檢查所有添加的架構是否都嵌入到項目中。

為此,導航到目标的 Build Settings > General > Frameworks、Libraries 和 Embedded Content 部分,然後從下拉清單中選擇 Embed & Sign 以添加架構。

七爪源碼:将 Flutter View 添加到原生 iOS 應用程式

但是,這還不夠,我們還必須給出添加架構目錄的搜尋路徑。

在目标的建構設定中,将“$(SRCROOT)/Debug”添加到架構搜尋路徑 (FRAMEWORK_SEARCH_PATHS),或者您可以簡單地将目錄拖放到該選項的值部分。

七爪源碼:将 Flutter View 添加到原生 iOS 應用程式

而已。 您現在應該能夠建構項目而不會出現任何錯誤。

4.打開flutter view為UIViewController

要從現有的 iOS 啟動 Flutter 螢幕,我們必須使用 FlutterEngine 和 FlutterViewController 類。

根據 Flutter Doc,-

FlutterEngine 充當 Dart VM 和 Flutter 運作時的宿主,FlutterViewController 附加到 FlutterEngine 以将 UIKit 輸入事件傳遞給 Flutter 并顯示由 FlutterEngine 渲染的幀。

讓我們首先在主 viewController 中添加一個簡單的按鈕,這樣我們就可以通過單擊該按鈕來打開 Flutter 視圖。

七爪源碼:将 Flutter View 添加到原生 iOS 應用程式

現在讓我們看看如何打開顫振視圖。

a。 建立 FlutterEngine

讓我們首先修改 AppDelegate.swift 檔案以進行所需的更改。

import UIKit
import Flutter

// Used to connect plugins (only if you have plugins with iOS platform code).
// import FlutterPluginRegistrant

@UIApplicationMain
class AppDelegate: FlutterAppDelegate { // More on the FlutterAppDelegate.
  lazy var flutterEngine = FlutterEngine(name: "my flutter engine")

  override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Runs the default Dart entrypoint with a default Flutter route.
    flutterEngine.run(withEntrypoint: "nativeLoad", libraryURI: "package:flutter_lib/main.dart")
    // Used to connect plugins (only if you have plugins with iOS platform code).
    // GeneratedPluginRegistrant.register(with: self.flutterEngine);
    return super.application(application, didFinishLaunchingWithOptions: launchOptions);
  }
}           

在這裡,我們做了以下更改——

  1. 根據 Flutter 的要求,我們必須遵守 AppDelegate 類中的 FlutterAppDelegate 協定。
  2. 之後,我們建立了一個 FlutterEngine 類的執行個體,name 參數可以是任何你喜歡的!
  3. 在這個項目中,我們隻打開了一個 Flutter 視圖,是以我們隻添加了一個 FlutterEngine,但是如果您必須打開多個 Flutter 視圖,則必須相應地建立單獨的引擎。
  4. 之後,我們添加了一個flutter run語句,這裡用于參數-withEntrypoint:我們必須傳遞我們在flutter子產品的main.dart檔案中配置的entryPoint函數名稱。

    libraryURI:傳遞子產品的 dart 檔案路徑。否則,它隻會打開一個空的模糊螢幕。

我們必須使用 package: 關鍵字來傳遞 dart 檔案位置,否則在少數情況下将無法正常工作。

b。作為 UIViewController 打開 Flutter 視圖

現在我們隻需要通過點選給定的登入按鈕來打開顫振視圖。

讓我們使用 Login 按鈕的 @IBAction 并添加代碼以在其塊中打開 Flutter 視圖,是以我們的 ViewController 将如下所示,

import UIKit
import Flutter

class ViewController: UIViewController {

    @IBOutlet weak var loginButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        loginButton.layer.cornerRadius = loginButton.frame.height / 2
    }

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

很容易了解,不是嗎?

它隻是從 AppDelegate 類中擷取 Flutter 引擎的對象,并使用它通過 FlutterViewController 打開視圖。

而已。 現在您可以運作應用程式了!

關注七爪網,擷取更多APP/小程式/網站源碼資源!

繼續閱讀