/// <summary> /// SpacomicMainViewModelクラスの新しいインスタンスを生成します。 /// </summary> public SpacomicMainViewModel() { // AppオブジェクトからModelを取得します。 spacomicRSSCollectionModel = (App.Current as App)?.SpacomicRSSCollectionModel; // Modelの参照の取得に失敗したら、例外をスローします。 if (spacomicRSSCollectionModel == null) { throw new Exception($"Failed to get reference of Model's instance on {GetType().ToString()}"); } // プロパティの変更を通知します。 spacomicRSSCollectionModel.PropertyChanged += (sender, e) => PropertyChanged?.Invoke(sender, e); // RSSフィードの取得が完了したことをView側に通知します。 spacomicRSSCollectionModel.GetRSSCompleted += (sender, e) => { // RSSフィード取得中のフラグをオフにします。 IsProgress = false; NotifyPropertyChanged(nameof(CanSwitchComicView)); // RSSフィード取得完了したことをView側に通知します。 GetRSSCompleted?.Invoke(this, e); }; // すぱこーRSSフィードの最新話が見つかったことを通知します。 spacomicRSSCollectionModel.NewRSSContentsFound += (sender, e) => NewRSSContentsFound?.Invoke(sender, e); }
/// <summary> /// SpacoRSSCollectionViewModelの新しいインスタンスを生成します。 /// </summary> public SpacoRSSCollectionViewModel() { // AppオブジェクトからModelを取得します。 spacomicRSSCollectionModel = (App.Current as App)?.SpacomicRSSCollectionModel; // Modelの参照の取得に失敗したら、例外をスローします。 if (spacomicRSSCollectionModel == null) { throw new Exception($"Failed to get reference of Model's instance on {GetType().ToString()}"); } // プロパティの変更を通知します。 spacomicRSSCollectionModel.PropertyChanged += (sender, e) => PropertyChanged?.Invoke(sender, e); // RSSフィードの取得を開始したことをView側に通知します。 spacomicRSSCollectionModel.GetRSSStarted += (sender, e) => { IsProgress = true; Items = null; NotifyPropertyChanged(nameof(Items)); GetRSSStarted?.Invoke(this, e); }; // RSSフィードの取得が完了したことをView側に通知します。 spacomicRSSCollectionModel.GetRSSCompleted += (sender, e) => { // RSSフィード取得中のフラグをオフにします。 IsProgress = false; DivideItemsIntoTheGroupsOfMonth(); // RSSフィード取得完了したことをView側に通知します。 GetRSSCompleted?.Invoke(this, e); }; // 画像のキャッシュの削除が完了したことをView側に通知します。 spacomicRSSCollectionModel.ImageCachesDeleted += (sender, e) => { NotifyPropertyChanged(nameof(Items)); }; if (spacomicRSSCollectionModel.Items != null) { DivideItemsIntoTheGroupsOfMonth(); } }
// RSSフィードを取得します。(非同期メソッド) private async Task GetRSSAsync(String i_feedUrl) { Boolean result = false; try { var client = new HttpClient(); RssFeed latest; using (var reader = new StringReader(await client.GetStringAsync(i_feedUrl))) { var desirializer = new XmlSerializer(typeof(RssFeed)); latest = desirializer.Deserialize(reader) as RssFeed; } IsProgress = false; if (latest == null) { throw new Exception("取得したフィードがnull"); } // RSSフィードの配信元情報を取得します。 this.FeedTitle = latest.Channel.Title; this.FeedDescription = Regex.Replace(latest.Channel.Description, Define.PATTERN_STR, String.Empty, RegexOptions.Singleline); this.FeedLastUpdatedTime = latest.Channel.LastBuildDate; // RSSフィードのコンテンツを取得します。 foreach (var item in latest.Channel.Items) { // コンテンツ取得 RSSContent content = new RSSContent(); content.Title = item.Title; content.Description = Regex.Replace(item.Description, Define.PATTERN_STR, String.Empty, RegexOptions.Singleline); content.PubDate = item.PubDate; content.Link = item.Link; // サムネイル画像取得 var imgMatch = Regex.Match(item.Description, Define.PATTERN_IMGTAG, RegexOptions.Singleline); if (imgMatch.Success) { content.Thumbnail = ImageSource.FromUri(new Uri(imgMatch.Groups["uri"].Value)); } Device.BeginInvokeOnMainThread(() => FeedItems.Add(content)); //FeedItems.Add(new RSSContent //{ // Title = item.Title, // Description = Regex.Replace(item.Description, Define.PATTERN_STR, String.Empty, RegexOptions.Singleline), // PubDate = item.PubDate, // Link = item.Link //}); } // RSSフィードの取得が完了したことをView側に通知します。 // ※通知の引数にRSSフィード取得の結果を渡す GetRSSCompleted?.Invoke(this, new TaskResultEventArgs(result)); } catch (Exception ex) { // RSSフィードの取得中に例外が発生したら、失敗フラグを立てます。 result = false; } }
/// <summary> /// RSSフィードを取得(保存済みのローカルファイルから読み込み or Webから取得)します。 /// </summary> /// <param name="forceReload">強制的にWebから取得するフラグ</param> public async Task GetRSS(bool forceReload = false) { // 初期化 GetRSSResult result = GetRSSResult.Succeeded; SauseItems.Clear(); Items.Clear(); cancellationTokenSource = new CancellationTokenSource(); GetRSSStarted(this, null); try { // Webからの再取得をリクエストされた時 if (forceReload) { try { Items.AddRange((await GetRSSCore()).OrderByDescending(_ => _.PubDate)); // 取得したすぱこーRSSフィードのデータをローカルファイルに保存します。 await SpacomicLocalIO.SaveSpacoRSSSauseFile(SauseItems); await SpacomicLocalIO.SaveRSSCollectionFile(Items); } // Webからの再取得に失敗した場合、ローカルファイルからリストアします。 // Itemsが空であれば、保存済みのローカルファイルは、再取得する前のすぱこーRSSフィードのデータが残っています。 catch (Exception) when(!Items.Any()) { // 保存済みのローカルファイルからリストア var spacoRSSauseFromLocal = await SpacomicLocalIO.LoadSpacoRSSSauseFile(); var spacoRSSListFromLocal = await SpacomicLocalIO.LoadRSSCollectionFile(); // 保存済みのローカルファイルからのリストアが成功した時 if (spacoRSSauseFromLocal.ResultCode == GetRSSResult.Succeeded && spacoRSSListFromLocal.ResultCode == GetRSSResult.Succeeded) { foreach (var item in spacoRSSauseFromLocal.Items) { SauseItems[item.Key] = item.Value; } Items.AddRange(spacoRSSListFromLocal.Items); result = GetRSSResult.LocalDataRestored; } // リストアに失敗した場合、例外をリスローします。 else { throw; } } } else { // 保存済みのローカルファイルから読み込み var spacoRSSauseFromLocal = await SpacomicLocalIO.LoadSpacoRSSSauseFile(); var spacoRSSListFromLocal = await SpacomicLocalIO.LoadRSSCollectionFile(); // 保存済みのローカルファイルからの読み込みが成功した時 if (spacoRSSauseFromLocal.ResultCode == GetRSSResult.Succeeded && spacoRSSListFromLocal.ResultCode == GetRSSResult.Succeeded) { foreach (var item in spacoRSSauseFromLocal.Items) { SauseItems[item.Key] = item.Value; } Items.AddRange(spacoRSSListFromLocal.Items); // Web上に最新話があるかどうかチェックします。 CheckNewContents(); } // ローカルファイルからの読み込みに失敗した場合、Webから取得します else { Items.AddRange((await GetRSSCore()).OrderByDescending(_ => _.PubDate)); await SpacomicLocalIO.SaveSpacoRSSSauseFile(SauseItems); await SpacomicLocalIO.SaveRSSCollectionFile(Items); } } } catch (OperationCanceledException) { SauseItems.Clear(); Items.Clear(); result = GetRSSResult.Canceled; } catch (Exception) { SauseItems.Clear(); Items.Clear(); result = GetRSSResult.Failed; } finally { cancellationTokenSource.Dispose(); } // すぱこーRSSフィードの取得が完了したことをViewModel側に通知します。 GetRSSCompleted?.Invoke(this, result); }