效率翻倍!大型Flutter專案快速實現JSON轉Model實戰

語言: CN / TW / HK

一、前言

在原生應用開發中,我們通常會使用YYModelSwiftyJSONGSON等庫實現JSON解析,並使用JSONConverter等類似工具實現JSON自動轉模型,極大的提高工作效率。 但在Flutter開發中,卻並沒有類似的解析庫給我們使用,因為這樣的庫需要使用執行時反射,這在 Flutter 中是禁用的。執行時反射會干擾 Dart 的 tree shaking,使用_tree shaking_,可以在 release 版中“去除”未使用的程式碼,這可以顯著優化應用程式的大小。由於反射會預設應用到所有程式碼,因此_tree shaking_會很難工作,因為在啟用反射時很難知道哪些程式碼未被使用,因此冗餘程式碼很難剝離,所以 Flutter 中禁用了 Dart 的反射功能,而正因如此也就無法實現動態轉化 Model 的功能。

二、json_serializable

雖然不能在Flutter中使用執行時反射,但官方提供了類似易於使用的API,它是基於程式碼生成庫實現,json_serializable package,它是一個自動化的原始碼生成器,可以生成JSON序列化模板,由於序列化程式碼無需手寫和維護,將執行時產生JSON序列化異常的風險降至最低,使用方法如下:

1. 在專案中新增json_serializable

要包含json_serializable到我們的專案中,需要一個常規和兩個開發依賴項。簡而言之,開發依賴項是不包含在我們的應用程式原始碼中的依賴項。 通過此連結可以檢視這些所需依賴項的最新版本 。

json_serializable.png

在您的專案根資料夾中執行 flutter packages get(或者在編輯器中點選 “Packages Get”) 以在專案中使用這些新的依賴項.

2. 以json_serializable的方式建立model類

讓我們看看如何將我們的User類轉換為一個json_serializable。為了簡單起見,我們使用前面示例中的簡化JSON model。

user.dart

``` import 'package:json_annotation/json_annotation.dart';

// user.g.dart 將在我們執行生成命令後自動生成 part 'user.g.dart';

///這個標註是告訴生成器,這個類是需要生成Model類的 @JsonSerializable() class User { String name; String email;

User(this.name, this.email);

factory User.fromJson(Map json) => $UserFromJson(json); Map toJson() => $UserToJson(this); } ```

有了這個設定,原始碼生成器將生成用於序列化name和email欄位的JSON程式碼。

如果需要,自定義命名策略也很容易。例如,如果我們正在使用的API返回帶有_snake_case_的物件,但我們想在我們的模型中使用_lowerCamelCase_, 那麼我們可以使用@JsonKey標註: @JsonKey(name: 'registration_date_millis') final int registrationDateMillis;

3. 執行程式碼生成程式

  • 一次性生成 通過在我們的專案根目錄下執行flutter packages pub run build_runner build,我們可以在需要時為我們的Model生成JSON序列化程式碼。 這觸發了一次性構建,它通過我們的原始檔,挑選相關的併為它們生成必要的序列化程式碼。

  • 持續生成 雖然這非常方便,但如果我們不需要每次在model類中進行更改時都要手動執行構建命令的話會更好。 使用_watcher_可以使我們的原始碼生成的過程更加方便。它會監視我們專案中檔案的變化,並在需要時自動構建必要的檔案。我們可以通過flutter packages pub run build_runner watch在專案根目錄下執行來啟動_watcher_。 只需啟動一次觀察器,然後並讓它在後臺執行,這是安全的

4. 使用json_serializable模型

要通過json_serializable方式反序列化JSON字串,我們不需要對先前的程式碼進行任何更改。

Map userMap = JSON.decode(json); var user = new User.fromJson(userMap); 序列化也一樣。呼叫API與之前相同。

String json = JSON.encode(user); 有了json_serializable,我們只需要編寫User類檔案 。原始碼生成器建立一個名為user.g.dart的檔案,它具有所有必需的序列化邏輯。 現在,我們不必編寫自動化測試來確保序列化的正常工作 - 這個庫會確保序列化工作正常。

三、 JSONConverter

如上面所寫,即便使用了json_serializable,仍然需要手動編寫模型類檔案並逐一編寫對應的模型屬性,生產工作中一個專案可能會有幾百個API, 如果全部手寫依舊浪費大量摸魚的時間,這裡我們可以使用JSONConverter, 它可根據後臺返回的JSON自動生成模型檔案,配合json_serializable,可以非常方便的實現介面對接,模型檔案一鍵生成,極大節省程式設計師的體力。

Flutter-JSONConverter.png 另外JSONConverter除了支援Flutter,還支援其他語言和第三方庫,功能可能說非常豐富了。

JSONConverter.png

四、總結

生產專案中推薦使用json_serializable + JSONConverter 完成服務端返回的JSON資料解析工作,效率翻倍!!