還記得先前在練習《從 Xamarin.Forms 存取 RESTful API》時,曾說明底下這段讀取 REST API 的程式不太理想。
public async void OnNavigatedTo(NavigationParameters parameters)
{
if (Addresses == null)
{
try
{
var result = await _apiService.GetAddresses();
Addresses = new ObservableCollection<AddressModel>(result);
}
catch (System.Exception)
{
throw;
}
}
}
因為上述的程式當讀取失敗時並末做出任何處理,而是以 throw;
把例外擲出,當真正遇到讀取失敗時,這樣的寫法會造成應用程式發生閃退的情況。今天在試玩昨天就做的成品,想再往下發展時,很不幸的 Azure 免費點數用完了,造成 Azure Web App 被停用,果然發生閃退,所以今天就先來學習如何解決。
使用者應該有權發生什麼事
雖然把上述的程式把 throw;
拿掉,保持 catch () { }
區塊空白就不會發生閃退了,但這對使用者很不友善,使用者可能會癡癡地等資料送過來,雖然發生的例外使用者也無法自行解決(可能連程式設計人員也暫時無法解決),但是出現個訊息通知一下總是好的。
雖然 Xamarin.Forms 有自己的顯示訊息的方法,但是我們已採用了 MVVM 的開發模式,要將這些原本實作在 Page 上的,不經過一些苦工不太容易在 ViewModel 中使用,好在 Prism MVVM Framework 已經幫我們做好苦工了,有個 PageDialogService 可以將顯示訊息的方法包裝到 ViewModel 使得與 View 之間的耦合度切開。
PageDialogService 主要提供三揰型式的跳出對話框(Pop-ups Dialog):
- 用來顯示警告或是說明訊息
- 用來讓使用者作確認選擇(是/否)
- 用來讓使用者有多數選項的選擇
今天就先來學習在讀取 REST API 發生錯誤時,以訊息框通知使用者。
設定 PageDialogService
請在欲使用 PageDialogService 的 ViewModel (本例例是 MyFirstPageViewModel)的建構函式中加入設定,如下所示:
private IAddressService _apiService;
private INavigationService _navigationService;
private IPageDialogService _pageDialogService;
public MyFirstPageViewModel(
IAddressService apiService,
INavigationService navigationService,
IPageDialogService pageDialogService)
{
_apiService = apiService;
_navigationService = navigationService;
_pageDialogService = pageDialogService;
}
接著在原先的 catch 區塊加入 await _pageDialogService.DisplayAlertAsync("讀取錯誤", e.StatusCode.ToString(), "朕知道了"); 的顯示訊息方法,如下所示:
public async void OnNavigatedTo(NavigationParameters parameters)
{
if (Addresses == null)
{
try
{
var result = await _apiService.GetAddresses();
Addresses = new ObservableCollection<AddressModel>(result);
}
catch (DemaeApiException e)
{
if (e.Connection)
await _pageDialogService.DisplayAlertAsync("讀取錯誤", e.StatusCode.ToString(), "朕知道了");
else
await _pageDialogService.DisplayAlertAsync("連線錯誤", e.StatusCode.ToString(), "朕知道了");
}
}
}
還記得先前實作例外處理時,有提到例外的發生可能是連線問題,也有可能是 REST API 本身的問題,所以可以使用 if (e.Connection) 來區分,而 DisplayAlertAsync() 方法傳入三個字串型別的參數,這三個參數分別為:
- 對方框的抬頭文字
- 訊息內容
- 按鈕文字
完成後執行畫面如下,果然是 Azure Web App 被停用,造成連線錯誤:
好吧!今天就學習到這裡,明天在來學習要刪除地址資料時,先讓使用者確認,確認後才刪,否則不刪。