沒事千萬不要用最新的技術開發要真的上線的軟體,拿來把玩還可以啦~
這次是高中同學求救,因他公司產品是用 Flutter 來開發 App,想必是想要追求又快又狠又準的新技術,但是沒有考量到一些潛在的問題,其實早一點來找我諮詢,就可以避免掉要找我「救火」的狀況囉~
首先來了解我使用的開發環境與技術規格:
- MacOS Catalina 10.15.5
- Flutter 2.0.1
我急忙在短時間內寫好一個功能齊全的 ShopViewController,接著想辦法整合進對方的 Flutter 專案。
我問目前在博弈業的前同事,有無將 Swift 整合進 Flutter 的經驗,結果他跟我說是寫原生 Swift,真是誤會大了。
起初我當然會擔心時間不夠,畢竟我完全沒碰過 Flutter,不過只要稍加上網搜尋,還是找得到把 Swift 整合進 Flutter 的關鍵步驟!
幸運地,多虧我過往的開發經驗,Objective C 整合 Swift 或是 Swift 整合 Objective C,這兩者都要各自寫,才能做到互通有無,也就是彼此來來往往。
回到主題,想要在 MacOS 上開發 Flutter,先看這一篇 macOS install。
接著就來建立 Flutter 專案,步驟如:
Create and run a simple Flutter app
To create your first Flutter app and test your setup, follow these steps:
- Create a new Flutter app by running the following from the command line:
flutter create my_app
- A
my_app
directory is created, containing Flutter’s starter app. Enter this directory:cd my_app
- To launch the app in the Simulator, ensure that the Simulator is running and enter:
flutter run
然後就可以看裡頭的檔案分佈狀況,有 ios、android、lib、web,如果是想要把 iOS 整合進 Flutter,就點進 ios 資料夾,開啟專案 Runner.xcworkspace,即可進行編譯喔!
為了方便解說如何把我寫好的 Swift 相關檔案整合進去,剛開始的專案檔案結構如圖:
很簡單地放在 Runner 資料夾底下,若有圖的話就放在 Assets.xcassets 中。
此刻編譯看看,肯定能順利,除非你寫錯程式碼啦~
接著要怎麼在 Flutter 中呼叫我寫好的 ShopViewController 呢?
Swift 程式碼在 AppDelegate.swift 這麼寫~
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let methodChannel = FlutterMethodChannel(name: "com.nativeActivity/iosChannel", binaryMessenger:controller.binaryMessenger)
methodChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
if call.method == "StartNativeIOS" {
let shopVC = ShopViewController() // Your viewController
let navigationController = UINavigationController(rootViewController: shopVC)
self.window.rootViewController = navigationController
self.window.makeKeyAndVisible()
} else {
result(FlutterMethodNotImplemented)
return
}
})
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Flutter 程式碼要寫在哪呢?lib 裡的 main.dart。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
void _incrementCounter() async {
String info;
try {
var platform = const MethodChannel('com.nativeActivity/iosChannel');
info = await platform.invokeMethod('StartNativeIOS');
} on PlatformException {
info = "Failed to call sayHello";
}
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
這是個範例專案,在 Xcode 編譯到手機呈現如圖:
我將 Flutter 程式碼寫在按鈕觸發事件中 _incrementCounter()。
你將發現有兩處,要跟 Swift 程式碼對應:
- com.nativeActivity/iosChannel
- StartNativeIOS
於是點擊「+」就會導向 ShopViewController。
至此大功告成!我的任務就是讓 Flutter 導向 Swift,那如何反過來從 Swift 導向 Flutter,那就是另外一套寫法囉~
參考:
- macOS install
- How can I “push” a UIViewController from FlutterViewController
- [iOS] 混編Objective C、Swift、C/C++
Comments on: "[iOS] Flutter 開發 App 初體驗" (5)
[…] 年上半年,我因緣際會要協助一個 Flutter 專案,橋接 iOS 原生語言的 In App Purchase 功能,才接觸 Flutter […]
讚讚
[…] 由於 Flutter 是剛發展沒多久的程式語言,所以會遇到平台程式語言(Objective-C/Swift/Jave/Kotlin)有實作的功能,但 Flutter 還沒有的狀況,若我們不想要花時間開發,我們可以透過 Platform Channel,來直接使用平台的功能。🤪 […]
讚讚
有遇到轉場或是點擊不靈敏之類的問題嗎?
之前玩類似跨平台的 framework 都有這類的問題
讚Liked by 1 person
不會耶~效能可比擬原生開發。
你是用哪個跨平台開發?Ionic嗎?這個是以網頁程式語言來開發,就會有種像是在瀏覽網頁的感覺,也就是會有點擊不靈敏這類問題~
讚讚
嗯嗯 之前就是用類似網頁的做法
操作來很不順
讚Liked by 1 person