专业的编程技术博客社区

网站首页 > 博客文章 正文

七爪源码:将 Flutter View 添加到原生 iOS 应用程序

baijin 2024-08-16 11:48:51 博客文章 6 ℃ 0 评论

让我们探索如何将 Flutter 视图添加到 iOS 原生视图(如 UIViewController)中。

今天,我们将在 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 文件中。

最后,我们将拥有一个像下面这样的应用程序。

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 项目的根目录中即可嵌入框架。

它看起来像这样,

现在我们必须检查所有添加的框架是否都嵌入到项目中。

为此,导航到目标的 Build Settings > General > Frameworks、Libraries 和 Embedded Content 部分,然后从下拉列表中选择 Embed & Sign 以添加框架。

但是,这还不够,我们还必须给出添加框架目录的搜索路径。

在目标的构建设置中,将“$(SRCROOT)/Debug”添加到框架搜索路径 (FRAMEWORK_SEARCH_PATHS),或者您可以简单地将目录拖放到该选项的值部分。

而已。 您现在应该能够构建项目而不会出现任何错误。


4.打开flutter view为UIViewController

要从现有的 iOS 启动 Flutter 屏幕,我们必须使用 FlutterEngine 和 FlutterViewController 类。

根据 Flutter Doc,-

FlutterEngine 充当 Dart VM 和 Flutter 运行时的宿主,FlutterViewController 附加到 FlutterEngine 以将 UIKit 输入事件传递给 Flutter 并显示由 FlutterEngine 渲染的帧。

让我们首先在主 viewController 中添加一个简单的按钮,这样我们就可以通过单击该按钮来打开 Flutter 视图。

现在让我们看看如何打开颤振视图。

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/小程序/网站源码资源!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表