本系列同步發表在 個人部落格,歡迎大家關注~
好了,經歷了一天 Hacker News API 和四天 GitHub API ,藉著 hnpwa_client
和 github
兩大套件之力,可說是省了不少力。
為何會這麼說呢?因為接下來要進行對接的 GitHub Trending API 是沒有套件輔助的,也就是說我要自己建造輪子拉!
那麼廢話不多說,直接講解吧~
有寫程式的人應該不陌生,目前 JSON 是主流的資料格式之一,所以幾乎所有語言都有內建或有強大的第三方套件來作 JSON 序列化。
如 Python 的內建 json
函式庫、 Java 的 GSON
/ Jackson
/ Moshi
這些第三方套件。
那麼 Dart 有內建的函式庫嗎? 當然是有的,就在 dart:convert
裡;不過呢,因為 dart:convert
只提供簡單的 decode / encode function,所以這邊要介紹另一個套件: json_serializable
。
這也是 Flutter 官方網站提供的 JSON 序列化解決方案,甚至還有教學文章呢~
那就迅速地將套件加入進 pubspec.yaml
吧
dependencies:
...
# JSON Parsing
json_annotation: ^3.0.0
dev_dependencies:
...
# JSON Parsing
build_runner: ^1.0.0
json_serializable: ^3.2.0
咦~ 怎麼加入這麼多套件阿?
嘿嘿,稍微講解他們的功用:
json_serializable
: JSON 序列化的主體,提供主要的轉換功能,讓你可以自由的從 JSON 字串轉換成自定義的物件。json_annotation
: JSON 序列化的輔助之一,定義 JSON key-value 和物件屬性間的對應轉換,看到 @
這個符號開頭就是照套件提供的函數。build_runner
: JSON 序列化的輔助之一,自動生成程式碼的工具,第一點說到 json_serializable
提供主要的轉換功能,是需要透過此套件來自動生成函數,後面會進一步接觸到。看到講解後是不是有種好複雜的感覺...
沒錯,當然這套件也因此而強大喔~
小提醒:
json_serializable
其實有很多的依賴套件,見下圖紅框。
還滿多是有關自動生成程式的套件。- 自動生成(Source-code generation)的技術似乎是最近滿流行的寫法,不過本系列還是著重於實作部份,技術深入探討以後有空再做補充吧~
在 JSON 序列化過程中,第一步就是要定義物件模板(Object Model),
而在 App 對接 Web API 中,通常只需要定義回應 (Response) 的物件模板。
直接看實例
import "package:json_annotation/json_annotation.dart";
是引用自json_annotation
part "project.g.dart";
是自動生成程式後需要引入的檔案名稱,其中的 .g.
是指 generation 的意思@JsonSerializable
是 json_annotation
提供的裝飾子,用來標記這類別為 JSON 序列化的物件模板。Project
這類別是最重要的部份,裡頭的屬性對應 Response 的 key,參考下圖Project.fromJson
和 toJson
為 JSON 與物件之間轉換的方法,有點類似 decode 和 encode 的感覺。_$
開頭的函數是自動生成的,後續會談到。自動生成的方式很簡單,在 Terminal 中打入 flutter pub run build_runner build
就可以了
$ flutter pub run build_runner build
[INFO] Generating build script...
[INFO] Generating build script completed, took 262ms
[INFO] Creating build script snapshot......
[INFO] Creating build script snapshot... completed, took 11.0s
[INFO] Initializing inputs
[INFO] Building new asset graph...
[INFO] Building new asset graph completed, took 708ms
[INFO] Checking for unexpected pre-existing outputs....
[INFO] Checking for unexpected pre-existing outputs. completed, took 1ms
[INFO] Running build...
[INFO] 1.1s elapsed, 0/16 actions completed.
[INFO] 2.1s elapsed, 0/16 actions completed.
[INFO] 3.2s elapsed, 0/16 actions completed.
[INFO] 4.2s elapsed, 0/16 actions completed.
[INFO] 5.3s elapsed, 0/16 actions completed.
[INFO] 10.0s elapsed, 1/16 actions completed.
[INFO] 11.1s elapsed, 17/28 actions completed.
[INFO] Running build completed, took 11.3s
[INFO] Caching finalized dependency graph...
[INFO] Caching finalized dependency graph completed, took 76ms
[INFO] Succeeded after 11.4s with 2 outputs (57 actions)
看到 Succeeded 字眼後就能在 lib/services/models/project.dart
同層資料夾中找到自動產生的 project.g.dart
,而裡頭就會看到上一小節提到的 _$
開頭的函數: _$ProjectFromJson
和 _$ProjectToJson
lib/services/models/project.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'project.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
...
從 project.g.dart
最上面,可以看到這段,很明顯是自動生成的程式,而且還標明不要自行修改~
原則上 Developer
撰寫的方法跟 Project
概念是一樣的。
這邊就直接貼上 Commit 圖片
參考
--
因為新組了一台電腦,昨天都在處理它,結果準備好的文章就忘記發了...
哭阿~~ !!
哀,看來無緣拿獎了,總之 30 天還是會慢慢發完吧...