0%

【文章內容使用 Gemini 1.5 Pro 自動產生】

加入我們,一起參與 #30DaysOfFlutter

30 天 Flutter 活動的標語

新年快樂各位!現在正是學習新事物的好時機!您是否在假期裡想過要開發一個應用程式?如果是的話,我們有一個絕佳的機會等著您!從 2 月 1 日開始,在我們於 3 月 3 日舉行的盛大 活動 之前,加入我們參與 #30DaysOfFlutter,開啟您的學習旅程,並結識社群中的 Flutter 專家。無論您是正在開發您的第一個 Flutter 應用程式,還是在尋找提升 Flutter 技能的方法,我們都準備了精心策劃的內容、程式碼實驗室和示範!

Flutter 是 Google 的開源 UI 工具包,用於從單一程式碼庫建立精美的原生編譯應用程式,適用於行動、網頁和桌面。它是成長最快速、需求量最大的跨平台框架之一,被全球的自由接案開發員和大型組織使用。Flutter 使用 Dart 語言,因此對於熟悉面向物件語言的許多人來說,它會感覺很自然。

跳進來吧,水很溫和!

除了精心策劃的內容,我們還將舉辦四場現場 問我任何問題 (#AMA) 討論會,您可以在其中與 Google 的 Flutter 團隊和社群成員見面。您也可以加入我們在 FlutterDev Discord 頻道 上,在那裡您可以結識社群中的其他成員,提出和回答問題,甚至還可以交到新的 Flutter 朋友!

聽起來很令人興奮嗎?請訪問 30 天 Flutter 網站 了解更多資訊,並註冊加入。註冊截止日期為 2021 年 1 月 31 日太平洋時間晚上 11:30。

#30DaysOfFlutter 議程

您在本月的 Flutter 學習旅程將如下所示:

第 1 週

收到精心策劃的內容到您的收件匣。在 Discord 上結識其他 Flutter 開發人員。參加 2 月 1 日的啟動網路研討會。

第 2 週

收到更多內容。開始開發您的第一個 Flutter 應用程式。加入網路研討會並提出您的問題。

第 3 週

繼續開發您的應用程式,並參加第 3 場網路研討會,提出您的問題。

第 4 週

完成您的專案,學習如何與 Flutter 社群分享您的作品。

您是否準備好學習世界上最熱門的開發者技能之一?

註冊 加入這個旅程,並務必在 Twitter 上關注 FlutterDev (@FlutterDev),以獲得有關 #30DaysOfFlutter 的最新更新。


加入我們,一起參與 #30DaysOfFlutter 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動產生】

大規模提供作業系統相容性

使用 Flutter 編寫的應用程式可以在 Android、iOS、網頁和桌面作業系統上運行。由於我們在支援多個平台方面的投入,Flutter 應用程式可以在任何具有應用程式編寫時所用作業系統版本(或更高版本)的設備上運行,而無需進行任何修改,這擴展了 Flutter 的跨平台吸引力。

在本文中,Flutter 的核心開發團隊(我們)想要分享我們為何投資於支援多個平台,我們如何才能繼續支援多個平台,以及在需要新增對新平台的支援或停止支援舊平台時,我們如何做出決定。

展望未來:Android 和 iOS 的版本

Flutter 致力於為 Android 和 iOS 的最新功能提供完全支援。我們始終監控著 Apple 和 Google 發布的有關其平台 API、工具使用和授權條款變更的定期指南。對新作業系統版本的支援是我們定期產品規劃的一部分,我們會盡量將我們的版本與 Google 和 Apple 的最新指南保持一致,以確保我們的穩定版本始終與兩者的最新指南相容。

我們承諾對您提供多個平台和 Android 和 iOS 的軟體版本(例如 Android 11 或 iOS 14)以及其小版本更新的支援。對於目標平台的主要修訂,我們會在了解到所需內容後立即開始開發必要的功能和更改。這通常發生在春季後期,Google 公佈了其即將發佈的 Android 版本的計劃,而 Apple 在其全球開發者大會 (WWDC) 上發布了最新公告。在發布公告之後,我們會評估 Flutter 程式碼庫中必要的更改,例如由於可能已棄用的 API 導致的引擎更改,工具更改如何影響 flutter 工具和開發人員體驗,以及兩者的設計語言更改。我們還會評估工作範圍,預期這兩個平台都将在秋季初提供給客戶。

我們會針對 Android 和 iOS 的測試版進行這項工作,並會透過我們的 master、dev 和 beta 頻道定期提供這些更改。master 頻道的版本是持續性的。我們計劃每週發佈兩到三個 dev 頻道版本(針對 Google 內部應用程式和測試套件進行測試的 master 頻道版本)。beta 頻道通常在每月的第一週發佈。我們會使用 GitHub 問題追蹤我們的進度。若要查看問題清單,您可以根據 platform-iosplatform-android 搜尋。

將我們的穩定版本發佈時間表與 iOS 保持一致尤其具有挑戰性,因為從新聞發佈到我們獲得有關作業系統更改的指南之間的時間通常非常短。我們會透過在秋季規劃我們的其中一個版本,並準備好針對 iOS 或甚至 Android 上出現的任何阻礙性錯誤對我們目前的穩定版本進行熱修復來減輕這一挑戰。(這發生在 Flutter 1.20 和 iOS 14 上,我們在 iOS 14 發佈的同一天發布了 熱修復)。

無論支援新平台版本需要做多少工作,我們的目標都是支援目標平台的新版本,而不棄用舊版本。

向後相容性和 Flutter 的價值主張

Flutter 是 Google 的可移植 UI 工具包,用於從單一程式碼庫建立針對行動、網頁和桌面的精美的原生編譯應用程式。為此,我們希望支援我們可以支援的最廣泛的設備集合,而不仅仅是特定類型的平台。我們還希望支援最多數量的平台版本。

以 Android 為例:根據 statcounter,截至 2020 年 6 月,市面上的 Android 版本如下所示:

從數字來看,Android KitKat (Android 4.x) 的市場佔有率不到 2%。絕大多數 Android 設備 (54%) 正在運行 Android Pie (Android 9.0) 或 Android 10。支援每個版本的 Android 都需要投資。您知道我們為何要投資於像 KitKat 這樣市場佔有率低於 2% 的平台嗎?

答案很簡單:淨數字。由於超過 10 億台 Android 設備沒有運行 Android Pi 或更高版本,我們希望確保 Flutter 尽可能广泛地得到使用。我們還希望支援多元的全球使用者群。而且,由於 Android 和 iOS 的舊版本經常被開發中國家的使用者使用,我們希望在尽可能長的時間內避免停止支援舊版本。

透過 Flutter 的核心引擎、框架和 Plugin 中的工作,Flutter 為作業系統平台和作業系統版本的各種問題提供了抽象。例如,Material 應用程式可以在舊版本的 iOS 或 Android 上運行,而无需進行任何修改。事實上,開發人員已發佈在與第一個版本同時推出的硬體上運行的商業 Material 應用程式,而使用這些設備附帶的 Widget 集,則無法在這些設備上執行 。Plugin 也有類似的案例。Plugin 會抽象化平台和版本差異,讓您可以專注於重要的部分:您的應用程式。

Flutter 如何支援如此多的目標

Flutter 為多目標支援帶來了兩大優勢。首先,Flutter 對底層作業系統的依賴性很小。Flutter 的引擎直接與圖形 API 互動,Plugin 為其他功能提供了大部分的設備特定實作。

我們的持續整合 (CI) 系統會為 macOS、Linux 和 Windows 建立 Flutter 及其工具,並部署到一系列 Android 和 iOS 設備(實體設備和模擬設備)。部分 CI 是使用 Google 辦公室中的實驗室進行的;其他 CI 測試是在 Firebase 測試實驗室 上進行的,這是 Google 為 Google 和第三方開發人員運營的雲端託管測試解決方案。

以下是一張我們測試實驗室中其中一個機架的照片:

我們在設備實驗室中運行相對低端的行動設備,因為我們會在那裡進行 效能測試。在測試時,我們希望從代表大多數使用者擁有的設備中獲取效能指標。這樣做可以讓我們獲得最糟糕的情況、真實世界的效能。這種理念也適用於核心工程團隊使用的設備。核心工程團隊的大部分成員並沒有在最新的 Google Pixel 或 Apple iPhone 上進行 Flutter 除錯。

由於我們想要測試許多類型的行動設備,因此我們會保留一個設備庫,核心工程團隊的成員可以在其中檢出特定設備以進行測試和除錯。(在新冠肺炎疫情期間,我們充分利用了美國郵政服務!)

由於實驗室只能測試少數幾種設備類型和版本,我們如何確保我們正在提供我們聲稱提供的支援?請繼續閱讀以瞭解。

對平台版本支援做出一般性斷言

首先也是最重要的是,我們會針對每個程式碼提交在各種平台上進行測試。

在我們目前的實驗室中,我們正在以下 Android 平台上進行測試:

  • Android API 24 (Android N)
  • Android API 28 (Android P)
  • Android API 29 (Android 10)

這涵蓋了已部署 Android 版本市場的 57%;稍後,我們會說明如何透過使用 Firebase 測試實驗室來涵蓋剩餘的設備。

我們的實驗室還會針對每個提交在運行以下作業系統的設備上測試 iOS:

  • iOS 9.3.6
  • iOS 12.4
  • iOS 12.4.1
  • iOS 13.1.3
  • iOS 13.2

最後,對於桌面和網頁,我們會針對每個提交在以下設備上進行測試:

  • Chrome 84
  • Firefox 72.0
  • Catalina 上的 Safari
  • Edge 1.2.0.0
  • Windows 10
  • macOS El Capitan
  • Debian 10

很明顯,Android 方面需要進行更多測試。我們依賴於 Firebase 測試實驗室 完成這項工作,測試以下額外的 Android 和 iOS 組態:

  • Android API 19 (Android K)
  • Android API 21 和 22 (Android L)
  • Android API 23 (Android M)
  • Android API 26 和 27 (Android O)
  • Android API 30 (Android 11)
  • iOS 11
  • iOS 13.0
  • iOS 13.1
  • iOS 13.3–13.7
  • iOS 14

總體而言,我們對 Android 和 iOS 平台的測試涵蓋了目前發佈版本中的 95% 以上。

對於其他作業系統版本,我們透過 您的 支援,也就是 Flutter 開發社群,提供向後相容性。這對特定的設備/作業系統組合尤其適用。你們中許多人使用我們無法使用到的設備:可能是因為你們的作業系統版本我們沒有,或是因為這些設備在美國無法取得。在某些情況下,我們可以減輕這種情況。例如,我們可以在一些 Google Pixel 硬體上刷入較舊的 Android 版本,購買較舊的翻新 iOS 設備,或在模擬器中運行 Android 版本。在許多情況下,你們中的一個人提交的報告會觸發我們對特定平台問題的調查。

這對許多 Android 設備的原始設備製造商 (OEM) 尤其適用。OEM 通常會對 Android 的某些方面進行自訂,例如鍵盤支援。過去,由於你們的幫助,我們能夠修復許多僅在某些市場的某些設備上發生的文字輸入問題。

我們感謝您的幫助,因為我們不可能自己找到所有問題,但我們會努力降低注入問題的風險。在進行程式碼更改時,我們會謹慎行事,並注意作業系統的最早版本支援哪些功能。在需要支援不連貫的組態時,我們會提供選項。這就是為什麼您可以使用 OpenGL 或 Metal 建立 iOS 應用程式,Flutter 會在運行時自動選擇其中之一。

由於這些原因,儘管我們會盡力支援作業系統版本上的測試,但我們支援的一些設備是基於「盡力而為」的基礎支援的。我們會嘗試撰寫支援我們聲稱支援的平台的程式碼,我們會依賴團隊對設備多樣性的隨機使用承諾,然後會尋求社群的回饋,以了解我們在實際使用中表現如何。

我們需要您幫助測試屬於「盡力而為」類別的設備。此類別中有數萬(甚至更多!)個 SKU。我們會盡可能地進行測試,有時候我們會從拍賣網站取得較舊的設備,以方便我們測試和修復在無法複製問題時通報的設備問題。如果您發現特定設備的問題,請在 GitHub 上提交問題。

最後,一些平台,例如 iOS 7,已被棄用。也許它們可以正常工作,但我們不會在已被棄用的平台上進行測試,也不提供任何保證。但是,如果我們可以在修補程式生效後測試時充分支援這些平台,我們會根據具體情況考慮針對已被棄用的平台的修補程式。

Flutter 會維護一個 網頁,列出我們會在其中進行測試的設備以及我們會尋求社群幫助的設備。

決定停止支援

儘管我們致力於在尽可能長的時間內支援每個平台版本,但支援舊平台(或平台組態,例如 Apple A7 上的 OpenGL)需要付出代價,並且會遵循我們上游合作夥伴(包括 Skia)的指南。Flutter 的核心工程團隊規模相對較小,我們會不斷做出權衡,以確保我們所做的事情對使用者來說最有利。在某些時候,工程方面、CI 實驗室中測試的頻寬以及隨機測試的頻寬,以及技術限制(例如作業系統供應商停止支援平台版本中的工具)的成本可能會讓繼續支援目標平台變得困難或不可能。

在我們決定停止支援之前,我們會考慮以下一些問題:

  • 這將會減少我們開發人員的多少終端使用者?
  • 這對 Flutter 開發人員有何影響?是否有主要合作夥伴的業務運營會受到重大影響?
  • 我們可能會節省多少工程成本?例如,透過支援多個作業系統版本,使用 Flutter 建立的應用程式數量是否會增加?(例如,在 iOS 版本中支援 OpenGL 和 Metal 就是這樣的案例。)
  • 這個決定是否符合我們廣泛採用和包容性的目標?
  • 停止支援是否是由外部原因引起的,例如平台供應商在其建置工具中停止支援平台版本?如果是,是否有可能減輕這種停止支援的影響?

在評估是否停止支援時,我們會先透過在 GitHub 中開啟一個議題來詢問您的意見,並發布一份相關的 Flutter 設計文件,該文件會提出停止支援的建議,說明我們為何考慮停止支援,以及可能可用的緩解措施。這是一個向社群徵求意見的請求 (RFC);公共設計文件會透過我們的討論清單 ([email protected]) 和我們的 Discord 推廣。

若要開始停止支援,我們會在發佈穩定版本時,作為穩定版本公告的一部分,啟動 RFC 流程。然後,我們會留出時間供公眾發表意見,然後在後續平台版本中減少對平台或功能的支援。RFC 是您提供回饋的機會。根據我們收到的回饋,我們將繼續停止支援,或對提議進行修改,將平台版本的支援時間延長。我們會認真对待這些前瞻性決定的回饋意见,因為我們認識到我們對您和您的產品使用者負有責任。

徵求意見:停止支援 iOS 8

我們正在考慮停止支援 iOS 8。所有 iOS 8 設備都可以升級到 iOS 9。根據 Google 和第三方分析,運行 iOS 8 的設備數量非常少(一些報告顯示「0.0%」),而 Apple 正在逐步停止支援其工具中的 iOS 8。

我們已發布了 有關停止支援 iOS 8 的徵求意見請求,我們請求您審閱並參與討論。我們的目的是使 Flutter 1.22(我們最新的穩定版本)成為最後一個支援 iOS 8 的穩定版本。RFC 包含理由以及如果您受到影響,該如何操作。

徵求意見:停止支援 Android Jelly Bean

我們正在考慮停止支援 Android Jelly Bean,因為我們不再在實驗室中測試運行該版本的 Android 設備,而為實驗室取得可靠的設備也越來越困難。目前運行 Android Jelly Bean 的設備約佔 Android 使用者群體的 0.46%。

我們已發布了 有關停止支援 Android Jelly Bean 的徵求意見請求,我們請求您審閱並參與討論。我們的目的是使 Flutter 1.22(我們最新的穩定版本)成為最後一個支援 Android Jelly Bean 的穩定版本。RFC 包含理由以及如果您受到影響,該如何操作。

您可以如何幫助

最簡單的幫助方式是參與!我們感謝您提交有關我們尚未遇到的各種設備的邊緣案例的問題。在許多情況下,這些問題出現在我們從未擁有的硬體上,即使我們將硬體測試的支出增加一倍或四倍。報告這些問題,並提供可重現的情況和有關軟體版本和硬體型號的詳細資訊,對我們追蹤問題的根源至關重要。

此外,我們希望您在需要減少對特定平台的支援時,參與決策過程。當我們考慮 Flutter 的未來時,您的見解非常寶貴。請在您看到 RFC 時參與我們公開的 RFC。您是您特定市場的專家,也是離您的客戶最近的人。

我們非常感謝您對我們使用者和讓我們成為您產品一部分的信任。我們仍然致力於幫助您將您的願景呈現在尽可能多的螢幕上。


大規模提供作業系統相容性 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

\n

【文章內容使用 Gemini 1.5 Pro 自動產生】

更新整合測試,支援行動端的 Firebase Test Lab;同時也支援網頁和桌面端的獨立支援!

Flutter 的目標是提供一個開放的框架,用於在多個平台上快速構建精美的原生應用程式。實現這個目標的很大一部分是能夠輕鬆地測試您的 Flutter 應用程式,以確保它們按您的意願工作,並在您所針對的平台上以您想要的方式呈現。一些測試可以透過使用 內建於 Dart 的單元測試框架 編寫的單元測試來處理。Dart 單元測試對於非 UI 測試非常有效;它在您的開發機器上執行,並且不依賴於 Flutter 應用程式的 GUI。

整合測試(也稱為端到端測試或 GUI 測試)比單元測試更進一步,因為整合測試嘗試透過按下按鈕、選擇項目和在鍵盤上輸入等方式模擬使用者與您的應用程式互動。這種測試是自動的,以避免讓人類做這種重複性的工作,因為坦白說,我們不擅長這種事情。我們最初避免人類互動的解決方案是一種編寫 Flutter 測試的特殊方式。這些測試從主機執行,就像 Dart 單元測試一樣,並驅動在真實或虛擬設備上運行的應用程式,就像一個人一樣。這些測試稱為 Flutter 驅動測試,因為您使用 flutter_driver 套件和 flutter drive 命令列來驅動應用程式的 GUI。

不幸的是,Flutter 驅動測試存在一些問題。一個問題是測試從開發機器執行並與設備上的應用程式通訊,這意味著測試不適合在像 Firebase Test Lab 這樣的設備池上執行。另一個問題是,為您的測試單獨使用一個程序會讓您很難檢查應用程式的狀態。您可以檢查輸出,但是您如何知道,例如,應用程式的內部狀態。最後,flutter_driver API 比它需要的要複雜,特別是在編寫程式碼以找到螢幕上適當的 Widget 來進行測試時。

因此,為了解決這些問題並繼續改進 Flutter 測試體驗,使其涵蓋越來越多目標,我們很高興宣布 integration_test Plugin 的 1.0 版,這是一種更簡單的方式來測試您的 Flutter 應用程式,並且也支援 Firebase Test Lab。

開始使用 integration_test

使用 integration_test Plugin 需要兩個步驟。首先,將 Plugin 添加到您的 pubspec.yaml 檔案中,作為開發相依,並使用 flutter pub get 將 plugin 拉到您的專案中:

1
2
3
4
5
6
7
# pubspec.yaml

dev_dependencies:
flutter_test:
sdk: flutter
integration_test: ^1.0.0

然後,在測試程式碼中使用 integration_test 套件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:my_app/main.dart' as app;

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('end-to-end', () {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
app.main();
await tester.pumpAndSettle();

// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);

// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pumpAndSettle();

// Verify the counter increments by 1.
expect(find.text('1'), findsOneWidget);
});
});
}

請注意 integration_test 套件的匯入和對 IntegrationTestWidgetsFlutterBinding.ensureInitialized() 的呼叫,這將確保套件正確初始化。還要注意標準 WidgetTester 測試程式碼。這是在 flutter create 期間由預設的 Counter 應用程式範本生成的相同測試程式碼。

雖然 integration_test 使您的測試能夠以獨立的方式捆绑到您的應用程式中(這是像 Firebase Test Lab 這樣的設備池的要求),但它需要一些我們將在下面介紹的構建技巧。但是,在測試開發過程中,能夠透過命令列互動式執行您的測試非常方便,为此,您需要一個新的入口點:

1
2
3
4
5
6
import 'package:integration_test/integration_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
integrationDriver();
}

integrationDriver 的呼叫是 integrationDriver Plugin 的便捷包裝函數,使您能夠使用 flutter drive 命令執行新的測試:

1
2
3
$ flutter drive 
--driver=test_driver/integration_test.dart
--target=test/widget_integration_test.dart

此命令會將您的應用程式部署到模擬器,執行您的測試,並向您顯示結果。

Flutter integration_test in action

此特定測試在 iOS 上執行,但 integration_test Plugin 也適用於 Android,只需更改 --device-id 選項,就像適用於其他平台一樣。此外,您也可以針對網頁和桌面目標執行整合測試,但此功能仍處於預發佈階段。

在 Firebase Test Lab 上執行

當您知道測試可以使用虛擬或實體硬體在本地執行後,就可以將應用程式在 Firebase Test Lab 提供的大量設備上執行。

Firebase Test Lab console

Firebase Test Lab 是一個基於雲端的應用程式測試基礎設施。透過一項操作,您可以在各種設備和設備配置上測試您的 Android 或 iOS 應用程式,並在 Firebase 主控台中查看結果 - 包括日誌、影片和螢幕截圖。integration_test Plugin 的一大進步是能夠在 Firebase Test Lab 上執行針對 Android 和 iOS 的 Flutter 應用程式,讓您能夠在發佈應用程式之前,在數百台設備上同時測試,以查找平台、外觀因素或設備特定的問題。

若要在 Firebase Test Lab 上執行測試,您需要進行一些配置,並使用 Gradle 命令為 Android 和 iOS 構建測試工具,這取決於您選擇的平台。有關這些詳細資訊,請查看 flutter.dev 上最新的整合測試文件

從 Flutter 驅動測試遷移

對於使用現有的 flutter_driver 測試的使用者,遷移到新的 API 並不困難。除了前面提到的適當初始化之外,您還需要遷移到新的 WidgetTester API。

flutter_driver API (left) vs. WidgetTesting API (right)

flutter_driver API(左邊顯示)和 WidgetTester API(右邊顯示)在概念上非常相似,但您可以看到許多細節是不同的。例如,您不是在 flutter_driver 上呼叫 waitFor 方法,而是在 WidgetTester 上呼叫 pumpAndSettle 方法。前者等待特定 Widget 出現,後者等待應用程式 UI 渲染階段穩定。獲得特定 Widget 後,您可以使用兩個 API 類似地對其進行操作,但您使用的是不同的物件。WidgetTest API 更符合您在 Dart 單元測試中看到的內容。如您所見,expect 方法用於確保 Widget 的內容符合您的預期。

有關如何將測試从 flutter_driver 遷移到 integration_test 和 WidgetTester 的詳細資訊,請查看 flutter.dev 上的遷移文件

原生 UI 測試

如果您有一個現有的 Android 或 iOS 應用程式,您使用 Add-to-App 為其添加 Flutter,那麼您可能已經為這些原生應用程式有了現有的整合測試,您想要利用這些測試。在這種情況下,將 Flutter 螢幕的測試添加到這些現有的測試中。對於 Android,如果您使用 Espresso 框架編寫測試,可以使用 espresso Plugin,它為 Espresso 對 Flutter Android 應用程式的測試提供了綁定。我們很快就會有類似的 Plugin 來支援使用 Earl Grey 建立的原生 iOS 測試。

總結

本公告介紹了使用適用於 Flutter 的新 integration_test Plugin 的整合測試的新基礎。不僅 API 更簡單,而且更一致,使用 integration_test 編寫的測試可以使用 Firebase Test Lab 在數百台不同的設備上執行。Flutter 團隊計劃透過將 flutter create 範本來使用 integration_test 作為預設值,更新測試輸出以支援使用 JUnit 格式的現有測試工具,添加在測試期間為黃金測試比較截取螢幕截圖的功能等等,來進一步發展這個新基礎。有關針對 Flutter 應用程式和 Plugin 的整合測試新建議的完整詳細資訊,請查看 flutter.dev 上的測試文件


Flutter 測試更新 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

開始將套件遷移到更健全、更安全的狀態

此文章同時發布於 Dart 部落格 上。

今天,我們宣佈 Dart 和 Flutter 的健全空安全功能已進入 Beta 階段。空安全是我們最新的主要生產力功能,旨在 幫助您避免空錯誤,這是一種通常難以發現的錯誤。如果您想快速了解為什麼我們對空安全感到兴奋,請查看這部新影片:

隨著空安全功能升級到 Beta 階段, 是時候開始對數千個在 pub.dev 上提供的套件進行社群遷移了。我們已經遷移了 Dart 核心函式庫、Flutter 框架以及 超過 40 個 Dart 和 Flutter 套件。我們希望看到社群透過遷移他們的套件來擁抱空安全性。

Timeline of Dart sound null safety support, from Technical Preview 1 to Stable in early 2021

隨著 Beta 版本的发布,我們也開始了在發佈穩定版空安全功能之前的最後衝刺。我們希望您能使用此功能,並告訴我們哪些部分可以改進,哪些 UI 訊息可以變得更容易理解,或者哪些文件可以變得更清晰。我們 **非常期待 您的回饋**。

選擇加入空安全功能

在我們討論空安全功能的遷移之前,重要的是要重申(如我们在空安全原则 中所述),您可以控制何时开始采用空安全功能。應用程式和套件只有在它们的最小 Dart SDK 约束 至少为 Dart 2.12 预览版本时才会使用空安全功能:

1
2
environment:
sdk: ">=2.12.0-0 <3.0.0"

要体验这一点,请尝试创建一个小的空安全版 hello 应用程序(例如,使用 dart create),其中包含如下所示的代码。然后,您可以尝试在更改SDK约束之前和之后运行该应用程序,以及运行 dart pub get,并体验程序行为的變化。(请确保使用在 dart –version 中报告 2.12 的 SDK。)

1
2
3
4
5
6
7
8
9
**bin/hello.dart:**
...
void main() {
var hello = 'Hello Dart developers';
if (someCondition) {
hello = null;
}
print(hello);
}
1
2
**在更改 SDK 约束之前:**
$ dart run
1
null
1
2
**在更改 SDK 约束之后(并运行 dart pub get):**
$ dart run
1
2
3
bin/hello.dart:6:13: Error: Null can't be assigned to a variable of type 'String' because 'String' is not nullable.
hello = null;
^

遷移到空安全功能

要將套件(或簡單的應用程式)遷移到空安全功能,請遵循以下五个步骤,这些步骤在 dart.dev 上的 遷移指南 中有完整的說明。

第 1 步:檢查您的相依性是否已準備好

我們強烈建議您按照順序遷移程式碼,先遷移相依性圖的葉子节点。例如,如果 C 相依於 B,而 B 相依於 A,請先將 A 遷移到空安全功能,然后是 B,最后是 C。此顺序适用于 A、B 和 C 是函式庫、套件还是应用程序。

Illustration of dependency order vs. migration order

為什麼順序很重要?雖然您可以在相依性遷移之前取得一些遷移程式碼的進展,但如果您在相依性遷移期間更改其 API,您可能會冒著需要進行第二次遷移的風險。如果您的幾個相依性不是空安全的,請考慮使用在 pub.dev 上列出的每個套件的聯絡資訊來聯繫套件發佈者。

驗證相依性是否已準備好

若要驗證您的應用程式或套件是否已準備好開始遷移,您可以在空安全模式下使用 dart pub outdated。以下範例顯示,如果此應用程式將其相依性升級到如 可解析 欄位中列出的路徑、進程和 pedantic 的預覽版本,則它已準備好進行遷移。

Screenshot of `dart pub outdated` output

如果空安全支援在次要新版本中可用,您將在 可升級 欄位中看到它們。通常,空安全支援將在主要新版本中可用;在这种情况下,您将看到在 outdated 输出的 可解析 下列出的版本。若要升級到這些版本,請編輯您的 pubspec.yaml 檔案以允許這些主要版本。例如,您可能會將 process: ^3.0.13 更改為 process: ^4.0.0-nullsafety。

您還可以在 pub.dev 上使用套件頁面上的新 空安全 標籤(例如 collection 1.15)和新的 進階搜尋 空安全搜尋選項 來查找具有空安全支援的套件。

Screenshot of pub.dev search

第 2 步:使用遷移工具進行遷移

如果您的相依性已準備好,您可以繼續使用遷移工具 dart migrate 來遷移您的應用程式或套件。

遷移工具是互動式的,因此您可以審查工具推斷出的可空性屬性。如果您不同意工具的任何結論,您可以加入可空性提示以更改推斷。加入幾個遷移提示可能會對遷移品質產生重大影響。

Screenshot of the migration tool UI

少數 Dart 套件作者已經使用空安全功能的早期預覽版本測試了遷移,他們的回饋令人鼓舞。遷移指南中提供有關如何使用遷移工具的額外提示。

第 3 步:靜態分析您的遷移程式碼

在您的 IDE 或命令列中使用 pub get 更新您的套件。然後使用您的 IDE 或命令列對您的 Dart 程式碼執行靜態分析:

1
2
$ dart pub get
$ dart analyze

或在您的 Flutter 程式碼上:

1
2
$ flutter pub get
$ flutter analyze

第 4 步:確保測試通過

運行您的測試,并确保它们通过。您可能需要更新預期為空值的測試,以防您更改了套件程式碼,使其不再允許為空。

第 5 步:發佈您的空安全套件

遷移完成且測試通過後,您可以將套件作為預覽版本發佈。以下是最佳實務的簡要摘要:

  • 將您的版本號碼增量到下一個主要版本(例如,從 2.3.x 到 3.0.0)。此最佳實務可確保您的套件使用者不會在他們準備好使用空安全功能本身之前升級到它,並且它讓您能夠自由地重構 API 以最佳地利用空安全功能。
  • 將套件的版本設定為 pub.dev 上的預覽版本。(例如,使用 3.0.0-nullsafety.0,而不是 3.0.0。)

有關遷移和版本控制的完整詳細資訊,請參閱 遷移指南

健全空安全的優點

我們之前關於空安全功能技術預覽的部落格文章 在 Dart 中在 Flutter 中 已經透過許多範例討論了空安全的優點。現在,空安全功能即將完成,我們看到了這種好处的几个实际例子。

更安全的程式碼

就在最近,我們 發現了 Flutter 主頻道中的一个錯誤,其中各種 flutter 工具命令在某些機器設定上會因空錯誤而崩潰:方法 ‘>=’ 被調用於 null 上。潜在问题是最近的一个添加了对检测 Android Studio 4.1 的支持的拉取请求。该 PR 添加了类似于以下内容的代码:

1
2
3
4
5
6
final int major = version?.major;
final int minor = version?.minor;
if (globals.platform.isMacOS) {
/// Android Studio 的插件路径在 4.1 版本之后发生了变化。
if (major >= 4 && minor >= 1) {
...

你能找到错误吗?由于 version 可能会为 null,major 和 minor 也可能会为 null。这个错误在孤立情况下似乎很容易发现,但在实践中,即使是像 Flutter 存储库中使用的严格代码审查流程,也会经常出现类似的代码。使用空安全功能,静态分析 会立即发现这个问题

Screenshot of analysis output in an IDE

这是一个非常简单的错误。在 Google 内部早期使用空安全功能的代码中,我们已经看到更多复杂的错误被发现,然后通过空安全功能解决。以下是几个例子:

  • 一个内部团队发现,他们经常检查代码中的空值,而空安全功能知道这些空值永远不会为 null。这个问题最常出现在使用 protobuf 的代码中,其中可选字段在未设置时返回默认值,而不会返回 null。这导致代码错误地检查默认条件,因为混淆了默认值和 null 值。
  • Google Pay 团队发现他们的 Flutter 代码中的错误,这些错误在尝试在 Widget 上下文之外访问 Flutter State 对象时会导致失败。在空安全功能之前,它们会返回 null 并隐藏错误;使用空安全功能,健全的分析确定这些属性永远不会为空,并抛出一个分析错误。
  • Flutter 团队发现一个错误,如果将 null 传递给 Window.render() 中的 scene 参数,Flutter 引擎可能会崩溃。在空安全功能迁移期间,他们添加了一个提示,以 将 Scene 标记为不可为空,并且能够轻松地防止潜在的应用程序崩溃,如果传递了 null,这些崩溃可能会被触发。

在編譯過程中利用健全的空安全功能

Dart 空安全功能的健全性還有一個令人歡迎的含義:這意味著 Dart 編譯器可以利用可空性資訊。這可能會使您的程式更小、更快。我們還沒有很多實際應用程式完全遷移到健全的空安全功能(因為我們現在才開始進行這些應用程式相依的套件的生態系統遷移),但我們從核心框架中看到了非常令人鼓舞的結果。

我們最近對 hello_world 範例進行了測試重新編譯,以測量空安全功能對應用程式大小的影響。這是一個最簡單的範例,它只會顯示「hello world」。在 比較 編譯後程式碼的總體大小時,未壓縮的(安裝在設備上的)程式碼大小縮小了 3.5%,而沒有做任何其他事情,只是使用健全的空安全功能重新編譯。這有可能實現,儘管這個應用程式只有 10 行程式碼,因為所有包含的函式庫的程式碼大小都縮小了;例如,Flutter 框架本身(套件:flutter)縮小了 3.9%。

至於程式碼速度,強制執行健全的類型系統可能會增加開銷。但是,減少空檢查也可能會使程式碼執行得更快。我們對基准測試的初步分析表明,效能與以前的版本相當,並且新的額外類型資訊為我們在未來進行新的效能改進提供了潛力。我們計劃在未來的部落格文章中更多地介紹我們的效能工作。

在某些情况下,我们已经看到空安全功能带来了性能提升,通常是在迁移到空安全功能时发现了代码逻辑中的缺陷。例如,我们在 Flutter 网页文字布局缓存中发现了一个问题。这个缓存使用了一个可为空的键,然后使用了一些逻辑来在为空时使用 TextAlign.start。这种逻辑导致缓存出现缺陷,即使元素仍然具有默认值,它们看起来也会像改变了一样。因此,经常出现缓存未命中。添加一个不可为空的 textAlign getter 有助于修复缓存缺陷,从而在文字被缓存的情况下,使文字渲染性能 提高了 14 倍

立即開始吧!

包含空安全功能的 Dart 和 Flutter 的 Beta 版本今天已準備就緒。如果您使用 Flutter 開發,您可以使用 flutter channel beta 然後 flutter upgrade 切換到 Beta 版本。否則,您可以從 Dart SDK 檔案 中獲取獨立的 Dart SDK。

如果您開發套件,我們鼓勵您閱讀我們的 遷移指南 並規劃您的遷移。請 告知我們 您遇到的任何問題或建議。

如果您是應用程式開發人員,您可能更希望延遲遷移,直到該功能出现在我們的穩定通道中。我們計劃快速解决 Beta 版本的回饋,修复任何剩余的问题。很难确定空安全功能将在稳定版中发布的确切时间,但我们预计将在明年年初。

感謝您在我們努力使 Dart 變得更加健壯,以及使 Flutter 變得更加强大的過程中提供支持和回饋!


宣佈 Dart 空安全功能 Beta 版本 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

Flutter 中的棄用生命週期

新的一年即將到來,Flutter 團隊正在為 2021 年的全新開始做好準備。

為此,我們將從 Flutter 架構中移除一些已棄用的 API。

在 Flutter 架構中移除棄用並非新鮮事。我過去也曾經 自己處理過快速搜尋 結果顯示,過去移除棄用沒有定義的時間軸或排程,因為我們的 棄用策略 並沒有規定何時移除它們。由於我們希望為使用者提供一致且可靠的體驗,因此我們決定為棄用建立標準生命週期。

本文將討論我們目前針對重大變更和棄用的策略,以及這些策略如何付諸實行,以及如何發展以為使用者提供更好的體驗。

Flutter 中的重大變更

Photo by CHUTTERSNAP on Unsplash

在 Flutter 中棄用程式碼的流程始於我們的 重大變更策略。棄用被視為重大變更,這意味著它們必須遵循 公開設計文件 指南,該指南要求一段時間用於討論。(此提案的設計文件為 實作棄用生命週期。) 除了提供設計文件外,我們還會在 Flutter 貢獻者 Discord 和受歡迎的社群,例如 flutter-announceflutter-dev 上發佈訊息,所有這些都在進行任何變更之前。這是我作為工程師最喜歡的流程之一:我能夠聽到您的意見。我們很棒的社群在這個流程中非常活躍,這也讓我們變得更好。在多次場合中,我看到一個功能的設計在透過這些管道發佈後有了很大的改進,這全都是因為社群的回饋。

重大變更的作者會遷移受重大變更影響的客戶程式碼。在我們重大變更策略的最後一次更新中,我們 邀請 您將測試提交到我們的 客戶測試儲存庫。這些測試是我們標誌著變更會造成中斷的訊號,我們承諾會在進行變更之前與測試作者合作遷移他們的程式碼。

我們還為我們的重大變更提供 遷移指南。這些指南旨在幫助使用者在更新到最新版本的 Flutter 後遷移他們的程式碼。如果您看過我們的 發行公告 之一,我們也會在特定版本中指出中斷,並引導使用者到有用的資源,幫助他們更新應用程式。

過去的調查 中,我們詢問使用者他們對重大變更的偏好。我們了解到使用者認為重大變更使程式碼更乾淨,對他們很有價值,這就是為什麼我們通常更喜歡重大變更而不是棄用的原因。根據研究:

總體而言,78% 的人表示他們更喜歡導致最乾淨的 API 的重大變更;這也使 API 更易於學習和使用。

我們的重大變更策略基於此研究。與所有規則一樣,總是會有例外。我最近 棄用了一些非常受歡迎的方法,改用新的 Widget。如果我們知道特定變更會造成重大中斷,影響許多使用者,我們就會棄用。棄用允許遷移緩衝期,同時仍然提供重大變更策略所產生所有工具。

日漸老舊的棄用

Photo by Dilyara Garifullina on Unsplash

遷移緩衝期從棄用在 穩定頻道 上發佈時開始。緩衝期結束的時間軸為 1 個日曆年或 4 個穩定版本,取較長者。為了制定出我們認為舒適的時間軸,我們查看了我們的成長率和採用率,並評估了一些已公開發佈的 Flutter 應用程式和套件。

我們希望使用者能夠預期這個排程,而不是擔心下一個版本是否會因為棄用消失而帶來意外的升級障礙。我們還希望確保我們提前通知這些變更,並且我們承諾在開始移除棄用之前,會宣布棄用即將結束生命週期。本著這種精神,我想要與您分享 第一批即將結束生命週期的棄用,現在 Flutter 1.22 已推出。

由於這是我們第一次實施這項策略,因此有很多棄用,其中有些甚至早於 Flutter 1.0!其中一些棄用也早於我們的重大變更策略。我們將會為所有這些棄用努力建立遷移工具和指南。預計在我們下一個穩定版本推出之前,這些棄用將從 Flutter 架構中移除,並會在移除時透過我們通常的管道發布公告。

在我們開始實施這些變更的同時,我們希望聽到您的意見!我們始終歡迎您將測試提交到我們的客戶測試儲存庫,我們會在進行中斷之前與您合作遷移您的程式碼。若要進一步了解測試儲存庫以及如何提交測試,請查看 Flutter 測試 README。在進行這些變更時,我們將透過 Flutter 貢獻者 Discordflutter-announceflutter-dev 頻道通知您並徵求您的回饋。因此,如果您尚未加入其中一個社群,請務必加入!我們期待收到您的訊息,並與您合作。


Flutter 中的棄用生命週期 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動產生】

為 Flutter 行動廣告 Plugin 開放嵌入式橫幅和原生廣告的 Beta 程式

有許多方法可以讓行動應用程式開發人員獲得工作的報酬。透過廣告變現應用程式是許多行動開發人員(包括使用 Flutter 的開發人員)的熱門選擇之一。

原生廣告格式支援,特別是 Flutter 的前五名熱門功能請求之一。Flutter 團隊先前提供的 Google 廣告 Plugin(也稱為 firebase_admob Plugin)支援覆蓋橫幅、插頁式和獎勵影片,但無法渲染嵌入式橫幅或原生廣告等格式。

嵌入式橫幅和原生廣告

顧名思義,嵌入式橫幅廣告讓您將廣告單元整合為 Flutter 視圖的一部分,而不是將橫幅覆蓋在 UI 上。同樣地,原生廣告允許您設計一種感覺像是您應用程式內容自然一部分的廣告體驗。一些開發人員告訴我們,缺少嵌入式橫幅和原生廣告會阻礙他們建立美麗自然的廣告體驗的能力,而另一些開發人員則表示,沒有這些功能可能會阻止他們將 Flutter 採用到他們的應用程式中。

為了響應您的請求,我們一直在開發對這些格式的支援。一年前,我們開始與 Google Ads 密切合作,為 Flutter 實作健全且值得信賴的嵌入式廣告解決方案。我們還完全重構了 Plugin 程式碼,以提高效能和穩定性。今天,在完成實作和一系列 Alpha 測試後,我們很高兴地宣布,此更新的 Plugin 的 beta 版本將提供僅限邀請的存取權。

藉由這個 beta 測試,我們在現有 Plugin 上進行了建置,並為 AdMob 和 Ad Manager 新增了對新格式的支援。與所有 beta 版本一樣,仍然存在一些需要解決的問題,而且功能支援可能會在未經通知的情況下發生變化。如果被選為參與 beta 測試,我們強烈建議您在將應用程式發佈給使用者之前,在您的應用程式中徹底測試整合。

立即申請

若要申請參與我們的 beta 測試,請填寫 我們的申請表。我們特別尋找已有應用程式上架且願意與我們團隊合作,在他們的生產應用程式中使用我們的 beta 版本的客戶。如果您被選為參與 beta 測試,您將收到一封包含更多說明的電子郵件。

根據此 beta 測試的結果,我們預計在 2021 年初向更廣泛的受眾開放使用。

我們希望嵌入式橫幅和原生廣告能幫助您為您的 Flutter 應用程式解鎖更多收入增長。

祝您程式設計和廣告愉快!


Flutter 的新廣告格式 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動產生】

使用 Material Icons 和 Flutter 打造可存取的表達力

Material Design 和 Flutter 都能幫助開發人員打造出靈活、可存取且富於表現力的體驗,同時提供出色的效能和效率。現在,我們很高興為您提供更多方法來使用改進的 Material Icons 支援在 Flutter 中建立獨特的 UI。

Material Icons 是為常見動作和項目精心設計的圖示,包括從用於導航的簡單箭頭和指示器,到代表可存取性、錯誤回報,甚至洗手等概念的圖示。

Flutter 現在支援所有四種圖示樣式——填滿、描邊、銳利和圓形——幫助您讓您的應用程式或網站對使用者來說熟悉且易於存取,同時讓您以獨特的方式傳達您的品牌。而且,透過對樹狀搖動的支援,Flutter 會優化您的應用程式建構,只包含您正在使用的圖示,從而使載入時間和記憶體使用更加有效率。

以下是一些展示您在 Material 目錄中找到的選項範圍的圖示。您可以在 Material.io 上瀏覽完整的圖示集並下載位圖或向量版本以供在您喜愛的設計工具中使用,或在 Icons API 頁面上查看 Flutter 版本。

Sample of 4 icons: shopping_cart, chat, masks, wash shown in the 4 supported styles: filled, outlined, rounded, sharp.
Sample of 4 icons: shopping_cart, chat, masks, wash. Displayed in the 4 supported styles: filled, outlined, rounded, sharp.

入門

若要開始使用 Icon 類別,請確保在您專案的 pubspec.yaml 檔案中設定 uses-material-design: true。這會告訴 Flutter 將圖示資產包含在您的應用程式中。

Flutter 中的圖示透過圖示字體以向量形式提供,因此您可以無限調整大小和顏色,而無需擔心影像品質下降。在 GitHub 上查看用於生成上述圖示集的程式碼。

不要跳過語義標籤!

為了讓使用螢幕閱讀器等輔助科技的使用者能夠有效地導航您的應用程式或網站,提供有意義且上下文適當的語義標籤非常重要。

預設情況下,螢幕閱讀器會朗讀螢幕上顯示的任何文字。為了將圖示等視覺元素準確地轉換為基於文字的 UI,您需要仔細標記這些元素。

例如,當圖示與動作元素(如按鈕)結合使用時,您應該始終將語義標籤設定為描述使用者點擊該圖示時會發生什麼的字串。

Material.io 提供指南 來指示透過動作來表示 UI 元素。常見的錯誤是將語義標籤預設為圖示的名稱,而不是選擇該圖示時執行的動作。

an example of what to do: a Pencil icon with the label “edit” and what not to do: a Pencil icon with the label “Pencil”

若要進一步了解建立可存取的數位體驗的重要性,請參閱 flutter.dev 上的 可存取性

只發佈您使用的內容!

當您為發佈建構應用程式時,Flutter 編譯器會執行「樹狀搖動」,移除未使用的程式碼和資產(包括圖示),以優化應用程式的佔用空間,並幫助最大限度地減少下載和載入時間。可以使用您想要的任何圖示!在編譯期間,會生成一個自訂圖示字體,其中只包含專案中使用的圖示子集。這可以大幅減少二進制檔案的大小——所有人都能受益!

除了樹狀搖動之外,這裡還有一篇關於 縮減 Flutter 應用程式大小的最佳實務 的很棒社群文章。

向我們展示您的傑作!

全世界的開發人員都在使用 Material Icons 來確保在大型和小尺寸條件下都能保持可讀性和清晰度;這些圖示已針對在所有 Flutter 支援的平台和顯示解析度上美麗顯示而進行優化。

在 @MaterialDesign 和 @@FlutterDev 上關注我們,並展示您如何使用 Material Design 和 Flutter 打造出美麗、可存取的數位體驗!


使用 Material Icons 和 Flutter 打造可存取的表達力 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

本篇文章主要介紹在2020年 Goolge 改版後的 Play Store Console 如何上架 Android App

首先到 Play Store Console 右邊點擊新增應用程式

填寫以下應用程式詳細資訊

  • 應用程式名稱:會顯示在商店的App名稱
  • 預設語言:預設App使用的語言,作為商店一開始提供的預設語言
  • 應用程式類型:分類只有遊戲與應用程式,目的是要把遊戲區分出來,日後可更改
  • 是否收費:設定App是否下載時需要費用,勾選收費後,需要至 付費應用程式 修改設定

最後同意 開發人員計畫政策美國出口法律 後,即可完成初始設定

接著進入到 資訊主頁

第一次設定時會出現 初始設定 提示,可依序點擊設定,該步驟都是必須完成的步驟,否則無法完成審查上架

應用程式存取權

設定 App 是否開放給全部使用者

或是部分功能有使用限制,需設定:

  • 名稱
  • 使用者名稱/電話號碼
  • 密碼
  • 任何操作說明

透過此可限制使用者下載應用程式

廣告

設定App中是否有廣告,若有勾選廣告則會在Play商店上顯示 含廣告內容 的標籤

內容分級

根據國際年齡分級聯盟(英語:International Age Rating Coalition,縮寫IARC)設計的簡化各國分級的內容分級問卷,降低產品評比的過程,參考資料

填寫內容分級問卷,讓使用者了解App的分類,及是否會有不宜兒童的內容

首先填寫電子郵件,問卷完成會寄送一份結果至該信箱

選擇 App 的類別,以 文藻校務通 為例,選擇 參考資訊、新聞或教育內容

根據選擇的類型,需填寫相關內容是否有未成年暴力色情訊息

完成後會顯示基本的報表,點擊右下角提交完成問卷

完成後,若日後想在修改問卷內容,需至右上角 點擊 Start new questionaire 重新提交問卷

目標對象

填寫詳細的App發布目標對象

首先點選 目標年齡層,主要是確認目標對象是不是兒童,若對象未滿13歲則需要新增隱私權政策

勾選 是否會引起兒童興趣,若上者點擊13歲以下,可勾選 宣稱適合兒童

最後點擊 儲存 完成目標對象和內容

接著就完成一半了~~

應用程式類別及詳細資料

應用程式分類,區分應用程式或遊戲的類別,在Play 商店中,也會有類別排名

接著設定商店的聯絡詳細資訊,分別為

  • 電子郵件地址 (必填)
  • 電話號碼
  • 網站

以上訊息皆會在Play商店上顯示

並勾選是否要在Play商店外行銷,讓外部網站可搜尋到你的App

完成後就只剩下最後一個步驟

商店資訊

首先會根據一開始設定的主要語言,設定 App 在 Play 商店的資訊,可根據不同語言,設定不同的商店資訊,可點擊 管理其他語言版本的翻譯內容 管理其他語言的內容

應用程式詳細資料

首先可設定

  • 應用程式名稱:App名稱,作為可供搜尋的關鍵字,上限50字
  • 簡短說明:可在App頁面首要看到簡短說明,上限80字
  • 完整說明:在點擊關於這個應用程式後顯示的完整說明

可參照 Play 商店對應位置

接著設定 應用程式圖示 會顯示在 Play 商店的圖示,限定尺寸為 512*512 的解析度,上傳後都會以橢圓裁剪顯示

主要圖片顯示於商店資訊的最頂端,可用於宣傳應用程式,大小限制 1024*500 解析度的圖片

螢幕截圖主要分為

  • 手機
  • 七吋平板電腦
  • 十吋平板電腦

基本上,對應類型的裝置截圖都適用,也可自行製作符合規定的尺寸的圖片,皆為使用 JPEG 或 24 位元 PNG 圖片,長寬比建議16:9

加入影片也會顯示於商店上

商店資訊設定完成後,若未來要修改都可直接修改,但修改後都需要等商店部署時間,通常都會為半天左右時間

上傳App至商店

發佈 的目錄下,選擇App目前要發布的方式,有分成

  • 正式版:會發布給商店中所有設置的地區
  • 公開測試:任何使用者可至 Play 商店點擊測試計畫,即可使用此版本
  • 封閉測試:由開發人員建立電子郵件清單,或是可透過連結加入測試計畫 https://play.google.com/apps/testing/{app id}
  • 內部測試:由開發人員建立電子郵件清單,或是可透過內部邀請測試連結:https://play.google.com/apps/internaltest/{test group id} 加入
  • 搶先註冊:若還沒發佈正式版時,可利用此功能,在Play商店中顯示搶先體驗的字樣,並提供測試人員特殊獎勵

不管利用哪種測試方式,接下來上傳App的方式都會相同,例如選擇 正式版 發布,並點擊右上方的 建立新版本

接著第一次上架時需點擊 同意使用 Google Play 應用程式簽署,Google 會管理你簽署所使用的金鑰,並且該金鑰只能提供給該 App 使用

若今天金鑰遺失,可請帳戶擁有者聯絡支援小組重新上傳金鑰

將利用 Android Studio 等等的 Android 編譯工具,將原生Android 的 Apk 或是 App Bundle 上傳至此頁面

每次新上傳的 版本號碼(version code) 皆需大於先前上傳的

關於金鑰使用詳細 可參考

版本詳細資訊

版本名稱會根據上傳的 ApkApp Bundle 命名

版本資訊會根據商店可提供的語言,以 XML 格式撰寫,將這次更新內容寫至 語言碼(language code)

完成後點擊儲存,並點擊檢查版本

接著會發現沒有設定提供地區

返回至上一頁的最上方,選擇 國家與地區 編輯針對正式版的發布國家/地區

若沒勾選,Play商店就不會發佈至此國家/地區

接著回到剛剛編輯的版本資訊,點擊 開始發布(正式版)

最後會跳回正式版的頁面,並顯示審查中

自 2019 年開始,Play 商店在第一次審查時,最久大約會至七天,爾後提交大約都是一下子就完成審查,並都是半天會完全部署至商店(所有使用者都可以看到更新)

本篇文章主要介紹在2020年 Apple 改版後的 App Store Connect 如何上架 iOS App

新增 App

App Store Connect 點擊 我的App

點擊 App 旁邊邊的 + 選擇 新的 App

註冊Identifier

憑證、識別碼及描述檔 註冊App的 Identifier

選擇 App IDs

選擇 App

Discription 填寫可以識別的名稱

App ID Prefix 選擇 Explicit 並填上與 Xcode 中的 Bundle Indentifier 相同的 ID

App ID Prefix 的 Bundle ID 上架後就不可修改

最後點擊 Continue 然後 Register 完成註冊

或是

懶人方法

使用 XcodeTarget 中的 Runner 選擇 Signing & Capabilities

選擇想要上架的Apple開發者帳號

並點擊 + Capability 隨意新增一個 Capability

此動作 Xcode 會自動註冊 Indentifier 至 App Store Connect

完成後再將其取消

沒取消的話審查時會納入審查範圍 要特別注意

接著填寫App基本資訊

  • 平台:選擇你的App會在哪些平台提供,若沒勾選可事後新增
  • 名稱:在Apple Store的名稱,無法跟已上架App相同,命名上需要先搶先贏,除非對方把App刪除或修改名稱,也是使用者搜尋時能找到你的App的首要途徑
  • 主要語言:首先可在商店提供的語言,若有發佈不同國家語系,可事後新增
  • 套件識別碼:選擇剛才新增的 Indentifier,選擇後就不能修改,對應到原生的 Bundle Indentifier
  • SKU:App ID 為獨一無二,可任意命名,填寫後不能修改,但不會公開顯示

App 資訊

新增 App 後,可先來 一般資訊 -> App 資訊,填寫 App 基本資訊,這邊會分兩個區塊,一個是可本地化資訊及一般資訊

可本地化資訊

  • 名稱:必填,為一開始輸入的 App 名稱
  • 副標題:必填,商店中會位於 App 名稱下方,建議使用簡短語句說明 App
  • 隱私權政策:必填,聲明你的 App 隱私權政策的網址,不限制格式

一般資訊

  • Apple ID:由 Apple 產生,作為網頁上的編號,可至 https://apps.apple.com/tw/app/id`${你的 Apple ID}`,找到你的App
  • 內容版權:聲明你的 App 是否有第三方內容,像是以校務通來說,資料來源於學校,就可以視為第三方內容
  • 年齡分級:必填,根據填寫 年齡分級問卷 的結果
  • 許可協議:必填,預設使用 《Apple 標準終端使用者許可協議》(EULA),可點擊自訂許可協議
  • 類別:必填,在商店的分類,可選擇兩個,也作為與同類型App排名的分類

定價與供應狀況

  • 價格排程:選擇你的App定價方式,最低免費到最高 32900元,使用者付費購買後90天內都可以反悔
  • 預定:第一次上架前會顯示,自訂日期在App成功發布後,會通知預定的使用者
  • 供應狀況:需先填寫供應國家與地區,若選擇停止供應,會從商店下架,直到重新供應為止
  • Mac 上的 iOS App:如果你的iOS App有使用到 Mac Catalyst (Flutter 目前不支援),會將你的iOS App發佈至 Mac App Store,若有發佈macOS App,則優先發布 macOS App
  • App發布方式:根據你的開發者帳號,若個人開發者帳號只能選擇公開在Apple Store,若是企業開發者帳號,則可以發布到私人的商店發布

App版本資訊

進入 App 版本資訊

首先設定 App預覽與截圖 可參考以下規格 每個至少三張

12.9 吋 iPad Pro 第三代 及 第二代 尺寸是可以相容的 故截圖第三代 可直接上傳到第二代

建議使用模擬器截圖 上傳完可用滑鼠拖曳改變顯示順序

螢幕尺寸說明 平台 截圖尺寸
iPhone 6.5 吋 iPhone 11 Pro Max、iPhone 11、iPhone X S Max、iPhone XR 1242 x 2688 像素(直向) 2688 x 1242 像素(橫向)
iPhone 5.5 吋 iPhone 8 Plus、iPhone 7 Plus、iPhone 6s Plus 1242 x 2208 像素(直向) 2208 x 1242 像素(橫向)
12.9 吋 iPad Pro(第三代) iPad Pro 2018、iPad Pro 2020 2048 x 2732 像素(直向) 2732 x 2048 像素(橫向)
12.9 吋 iPad Pro(第二代) iPad Pro 2017 2048 x 2732 像素(直向) 2732 x 2048 像素(橫向)

更多詳細資訊 可參考

接著填寫

  • 行銷宣傳文字:作為 App 行銷宣傳標語,建議簡短的文字,也要符合App的性質
  • 關鍵字:在商店搜尋時,透過關鍵字加強找到App,並使用逗點隔開
  • 描述:詳細介紹App的功能與特色
  • 支援URL:對應商店開發者網頁
  • 行銷URL:待補充
  • 版本:可參考 語意化版本,不限定兩碼或三碼,不能與先前定義的相同
  • 版權:宣告App版權的註解
  • 年齡分級:根據填寫 年齡分級問卷 的結果(需點擊編輯填寫)

對應在商店的位置可參考

年齡分級問卷

針對App的內容填寫是否有兒童不宜的

App審查資訊

蘋果在審查時都是採用 人工審查,審查過程都須填寫完整的資料

  • 登入資訊:若你的App有設計登入功能,需提供測試帳號給審查人員
  • 聯絡人資訊:當審查有問題時的聯絡人資訊,電話號碼需要加入國際冠碼
  • 備註:資訊則提供其他資訊供審查人員了解你的App,像是之前就被問過這幾個問題,爾後我都在新的App加入這些回答
    • Who is the target audience?
    • How do users obtain an account?
    • Is this app meant for internal distribution in your own company, in the company of one target client, or in multiple target clients’ companies?
    • In which countries will this app primarily be distributed?
    • If this app is meant for internal distribution, will the app be accessible by both internal and external partners? Or will it be exclusive to in-house employees?
      • 附件:可附上App操作影片,若你的App無法提供帳號測試,或是有些功能需要提供範例影片操作(ex.何時會使用到讀取wifi連線資訊的功能),都需要附上影片

建制版本

接著選擇要送至審查的App版本,需先透過Xcode Archive 後上傳至App Store Connect,點擊藍色按鈕

選擇對應想提交的版本,通常上傳完會需要一段時間處理,當完成處理都會email通知

屆時才會出現在這邊

接著選擇這次提交的出口合規資訊,點擊是否有使用加密功能,若點擊是的話,需要另外填寫出口法律資訊

廣告識別碼

最後是填寫是否有使用到 廣告識別碼,像是 Firebase Analytics 或是 Ad Mod 等第三方的廣告或分析工具,就需要聲明有使用到,若審查後發現錯誤,則需要重新上傳新的App版本

最後回到最上方點擊完成,並點擊審查,結著就會進入正在等待審查

通常審查時間已台灣都是晚上開始到半夜,對應到美國的白天時間,第一次審查都會比較久,大約2~3天,要耐心等待

但有時候會審查失敗,也會寄送 email 通知,可至連結查詢問題,並回覆審查人員

iOS Resolve Center : https://appstoreconnect.apple.com/apps/{apple id}/appstore/platform/ios/resolutioncenter?m=

macOS Resolve Center : https://appstoreconnect.apple.com/apps/{apple id}/appstore/platform/osx/resolutioncenter?m=

若審查成功,則會通知 Ready for Sale,完成這次版本審查

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter 架構的空安全支援

Dart 在 Flutter 中扮演著特殊的角色,為開發人員功能(如熱重載)提供動力,並透過 Dart 的靈活編譯器技術,為行動、桌面和網頁實現跨平台應用程式。我們致力於使 Dart 語言成為 Flutter 應用程式開發人員最具生產力的語言;例如,我們加入了 UI-as-code 語言結構,以優化 Dart 語法,用於編寫 Flutter Widget 樹。

在 6 月份,我們提供了 Dart 空安全的首個技術預覽。今天是另一個重要的里程碑,我們已經 期待已久:我們宣布 健全的空安全 的第二個技術預覽,包括對 Flutter 架構的支援。

空安全是一個主要的生產力功能,可以幫助您避免空引用錯誤,這種類型的錯誤通常很難發現。作為額外的優點,此功能還可以實現一系列效能改進。我們非常期待您的回饋。

為什麼要使用空安全?

Dart 是一種類型安全的語言。這表示當您獲得某種類型的變數時,編譯器可以保證它屬於該類型。但是,類型安全本身不能保證變數不是空引用。

空引用錯誤非常普遍。在 GitHub 上搜尋會發現由於 Dart 程式碼中出現意外的空引用而導致的數千個問題,以及數千個嘗試解決這些問題的提交。試著看看您是否能在下面的 Flutter 應用程式中發現可空性問題,想像 Config 和 WeatherService 是應用程式使用的後端服務:

如果 getAppName() 返回空引用,這個應用程式肯定會失敗;在這種情況下,我們將傳遞空引用給 AppBar 標題中使用的 Text Widget。

但是,還有更多微妙的情況需要考慮:getTemperatures() 也可能返回空引用。在這種情況下,for 迴圈會失敗。或者 getTemperatures() 可以像預期一樣返回一個列表,但該列表可能包含空值,在這種情況下,我們將呼叫 round() 到空引用上,應用程式將會失敗。

空安全功能透過 驗證您的程式碼 來解決這些問題,就像您在輸入時一樣:

Screenshot of the preceding code with null errors.
利用空安全,Dart 會在您的程式碼中找到潛在的空引用錯誤。

利用空安全,您可以更有信心地推論您的程式碼。部署的應用程式中不再有惱人的運行時空引用解除引用錯誤。相反,您在編寫程式碼時會出現靜態錯誤。

空安全原則

Dart 空安全支援基於以下三個核心設計原則:

  1. 預設不可空引用。除非您明確告訴 Dart 變數可以為空引用,否則它將被視為不可空引用。我們選擇這一點作為預設值,因為我們發現不可空引用是 API 中最常見的選擇。
  2. 可遞增採用。有很多 Dart 程式碼。您可以選擇在您想要的時候遞增地逐漸遷移到空安全,然後逐部分地進行遷移。可以在同一個專案中使用空安全的程式碼和非空安全的程式碼。我們還將提供工具來幫助您進行遷移。
  3. 完全健全。Dart 的空安全是 健全 的。這表示我們可以信任類型系統:如果它確定某個東西不是空引用,那麼它 永遠 不會是空引用。這可以實現編譯器最佳化. 當您將整個專案和相依項目遷移到空安全後,您將完全享受到健全性帶來的優勢 - 不僅是更少的錯誤,而且還包括更小的二進位檔案和更快的執行速度。

讓我們更詳細地回顧一下這些設計原則。

1. 預設不可空引用

核心語法非常簡單。以下是一些以不同方式宣告的不可空引用變數。請記住,不可空引用是預設值,所以這些宣告看起來與今天一樣,但它們的含義發生了變化。

Dart 會確保您永遠不會將空引用指派給上述任何變數。如果您嘗試執行 widget = null,幾千行程式碼之後,您將得到一個靜態分析錯誤和紅色的波浪線,您的程式將拒絕編譯。

可空引用變數

如果您想要您的變數可以為空引用,您可以使用 ?,比如這樣:

您可以在函數參數和返回值中使用 ? 語法,也是如此:

但是,再次強調,夢想是您很少需要使用 ?。您的絕大多數類型將是不可空引用。

使用空安全提高生產力

空安全不僅僅是關於安全。我們還希望您在使用此功能時能夠提高生產力,這表示此功能必須易於使用。例如,請看以下程式碼,它使用 if 來檢查空引用值:

請注意,Dart 工具如何檢測到當我們通過該 if 語句時,loudness 變數不可能為空引用。因此,Dart 讓我們可以呼叫 clamp() 方法,而無需跳躍障礙。這種便利性是由一種稱為流程分析的功能實現的:Dart 分析器會像執行程式一樣遍歷您的程式碼,自動找出有關程式碼的更多資訊。

以下是一個示例,它顯示了一個情況,即 Dart 可以確定變數為不可空引用,因為我們始終將不可空引用值指派給它:

如果您移除上述任何指派(例如,透過刪除 statusText = 'Update failed'; 這行程式碼),Dart 無法保證 statusText 為不可空引用:您將得到一個靜態錯誤,您的程式碼將無法編譯。您可以 在 DartPad 中嘗試一下

2. 可遞增採用

由於空安全對我們的類型系統來說是一個如此基礎性的改變,如果我們堅持強制採用,這將是極其破壞性的。我們希望讓您自行決定何時是適當的時間,因此空安全是一個選擇性功能:您將能夠使用最新的 Dart 和 Flutter 版本,而無需在您準備好之前強制您啟用空安全。您甚至可以從尚未啟用空安全的應用程式或套件中相依於已經啟用空安全的套件。

一旦您選擇採用,我們強烈建議您按照順序遷移程式碼,相依關係圖的葉節點優先遷移。例如,如果 C 相依於 B,而 B 相依於 A,則先將 A 遷移到空安全,然後是 B,最後是 C。此順序適用於 A、B 和 C 是函式庫、套件還是應用程式。

為什麼順序很重要?儘管您可以在相依項目遷移之前進行一些程式碼遷移,但如果相依項目在遷移期間更改了它們的 API,您可能會冒著需要進行第二次遷移的風險。當我們到達 beta 版本時,我們將提供工具來幫助您找出哪些相依項目已經遷移。如果您是套件作者,為了避免 API 斷裂的風險,請在發佈空安全的版本之前,等待所有相依項目都完成遷移。

當您的相依項目準備就緒時,您可以使用我們的遷移工具。該工具透過分析您所有現有的程式碼來工作。遷移工具是互動式的,因此您可以審查工具推斷出的可空性屬性。如果您不同意工具的任何結論,您可以添加可空性提示來更改推斷。添加幾個遷移提示會對遷移品質產生巨大的影响。

Screenshot of the migration tool
遷移工具有助於您以互動方式將程式碼遷移到空安全。

3. 完全健全

一旦您完全完成遷移,Dart 的空安全就是 健全 的。這表示 Dart 100% 確定在上面的示例中,返回值、列表和元素不可能為空引用。當 Dart 分析您的程式碼並確定變數為不可空引用時,該變數 始終 為不可空引用:如果您在偵錯工具中檢查正在執行的程式碼,您將看到不可空引用性在運行時被保留。相反,其他一些實作是非健全的,在許多情況下仍然需要執行運行時空引用檢查。Dart 與 Swift 共享 健全的空安全,但其他程式語言卻很少。

Dart 空安全的健全性還有另一個令人欣慰的含義:這表示您的程式可以更小更快。由於 Dart 非常確定不可空引用變數永遠不會為空引用,因此 Dart 可以進行最佳化。例如,Dart 的提前編譯 (AOT) 編譯器可以生成更小更快 Native 程式碼,因為它不需要在知道變數不是空引用時添加空引用檢查。

請注意,要獲得健全的空安全,您需要將整個專案和所有相依項目遷移到空安全。如果您的應用程式或相依項目的一部分尚未遷移,您將獲得部分空安全,它保留了大部分檢查,但沒有完全最佳化,也無法保證應用程式完全安全。

空安全路線圖

空安全何時才能準備好投入生產使用?以下是目前的時間表:

  1. Flutter 進行 技術預覽 2 嘗試:這就是今天。由於我們已成功將核心 Flutter 架構遷移到空安全,因此您可以嘗試使用空安全來學習新的語言功能併嘗試 一個小型 Flutter 樣本。如果您是套件作者,您也可以嘗試遷移,如果您有一個小型相依項目集已經被我們遷移了。您需要傳遞一個 實驗標誌,不應該在生產環境中使用它,也不應該發佈任何遷移的套件。
  2. 使用 beta 版本進行早期套件遷移:今年晚些時候,我們將完成效能調整,並擁有足夠的測試覆蓋率,讓我們有信心相信此功能按預期工作,並且向後相容性穩定。在那時,我們將發佈該功能的 beta 版本,您將不再需要傳遞實驗標誌。我們希望看到套件擁有者開始將他們的套件遷移到空安全,這將為我們提供最後一輪驗證,證明該功能已準備好發佈穩定版本。
  3. 使用 stable 版本投入生產:接下來,我們將解決 beta 版本中收到的回饋,修復任何剩餘的問題,然後發佈到 stable channel。很難為此設定一個具體的時間表,但我們認為是明年年初。一旦該功能穩定,我們希望看到空安全被廣泛採用,會有空安全的應用程式發佈到商店,以及許多空安全的套件在 stable channel 上發佈到 pub.dev。

立即嘗試

您今天就可以開始嘗試使用空安全!若要快速上手,請查看 附帶空安全的 DartPad 特殊版本

如果您想在 VS Code、Android Studio 或終端機中嘗試使用空安全,請查看 Flutter 空安全樣本應用程式。這個應用程式包含執行說明和一個小型氣象應用程式的兩個版本:一個不使用空安全,其中包含一些零散的空引用錯誤,另一個使用空安全來確保這些問題得到處理。如果您更願意嘗試使用一個新的 Flutter 應用程式,您可以運行 flutter create,然後按照 實驗說明 來啟用空安全。請注意,您將需要一個 dev channel 的 Flutter SDK(版本 1.24.0–3.0.pre 或更高版本),因為目前的穩定版本和 beta 版本的 Flutter 不支援空安全。

若要進一步了解功能設計,請閱讀我們最新的 了解空安全 文件。如果您更喜歡觀看簡短的影片,請查看幾個月前 Flutter Day 活動 中的 空安全影片

我們很高興將健全的空安全帶到 Dart。健全的空安全是 Dart 的一個特色功能,可以幫助您編寫更不易出錯的程式碼,並獲得更好的效能。我們希望您會 嘗試 在技術預覽中使用此功能,並透過我們的議題追蹤器 提供回饋。祝您編碼愉快!


Dart 健全的空安全:技術預覽 2 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/