Makopy'5 La6

スマホアプリ開発とかその周辺のこととか関係ないこと。または恋は言ってみりゃボディー・ブロー

(Xamarin.Forms)MFractor for Visual Studio Mac

前回記事で、MFractorについて書きました。
makopy5la6.hatenadiary.jp

前回記事の中で、

今のところXamarin Studio用の無償版しかありませんが、Visual Studio For Mac向けに有償版が出る予定っぽいです。

と書きましたが、 正式にそのアナウンスがありました!

forums.xamarin.com www.mfractor.com

MFractor Visual Studio for Mac

無償版と有償版(Premium)の違い

About MFractor Premium - mfractor docs

Feature Free Premium
Configuration Support
MFracor Code Annotations
Xamarin.Forms Features
Xaml Analysis
Navigation Tools
Xaml Refactoring
Xaml To C# Code Generation
Xamarin.Forms C# Refactorings
Xamarin.Forms C# Code Diagnostics
Xamarin.Android Features
Android Resource IntelliSense
Android Resource Navigation Suite
Android C# Code Diagnostics
C# Features
C# Code Actions
C# Code Diagnostics

Premiumは、年額$199audです。
仕事で使うツールとしての有用性と出来から見れば、
個人的にはこれくらい出しても構わないかなと思います。

ただ筆者の場合、
MacでXamarin.Formsやってるのは個人的な取り組みで、実戦ではWindowsを使っているので微妙なところではありますが…。
実戦でMacを使ってXamarin.Formsやるなら、迷わずPremiumを導入したいです。

インストー

下記ページ通りの手順でOK!

Installation And Setup - mfractor docs

とりあえず無償版だけでも使ってみることをオススメします☆

(Xamarin.Forms)MFractor

MFractorとは?

@ytabuchi 氏のTweetで知ったのですが…。

Xamarin Studio用のReSharperみたいなやつ。

筆者のようにMac OS上でXamarin Studioを使っている人には非常にありがたいツールです。
今のところXamarin Studio用の無償版しかありませんが、Visual Studio For Mac向けに有償版が出る予定っぽいです。

何ができるの?

基本的にはMFractorの公式ドキュメントを読むのが一番です。

docs.mfractor.com

概要(和訳)

あまり英語は得意ではないですが…。
覚え書きとして要点を和訳して書き留めておきます。

Code Actions

Using Code Actions - mfractor docs

  • Fixes(問題の修正)
    • XAML分析により検出された問題の修正
  • Generate(コード生成)
    • 共通のXAMLおよびC#コードの生成
  • Refactor(リファクタリング)
    • XAMLからC#XAML内のシンボルをリネーム
  • Organise(整理)

Code Issue Fixes(問題の修正)

XAML分析エンジンの分析により検出された問題の該当箇所が黄色の下線でマークされる。
マークされた箇所で右クリックして[修正]メニューから実施したい修正を選択することで修正可能。

http://docs.mfractor.com/img/forms/refactoring-fix.gif

Code Generation(コード生成)

本来手作業で書くべき定型のコードを素早く作成できる。
例えば、
- ビュー要素のリソースディクショナリを生成 - 不足しているBindingをすべて一括して実装

http://docs.mfractor.com/img/forms/refactoring-generate.gif

Code Refactoring(リファクタリング)

XAMLドキュメント内でXAMLと.NETのシンボルを操作できる。
ユーザー入力に基づいて、XAMLおよび(または)C#の変更を行う。
例えば、

  • XAML上で値指定している箇所をBindingとして、Binding ContextのC#プロパティを生成
  • カラーピッカーダイアログを使った色の変更

http://docs.mfractor.com/img/forms/refactoring-refactor.gif

Code Organisation(コード整理)

XAMLコードを素早くフォーマットし、XAMLをキレイにわかりやすくできる。
例えば、

  • ノード上のすべての属性を名前と名前空間で並べ替え
  • ノード上の属性を別の行または同じ行に縮小/展開
  • ノードの終了タグを展開/折りたたみ

http://docs.mfractor.com/img/forms/refactoring-organise.gif

Xamarin.Forms Quick Start

Xamarin.Forms Quickstart - mfractor docs

Configuring A Binding Context(Binding Contextの構成)

BindingContextプロパティがXAML上で明示的に設定されている場合、MFractorはBinding式を解析し、XAMLからBinding Contextへのリファクタリングを実行できる。

ViewModelLocatorを使用して、Binding Contextを明示的に構成する。

Mvvm Naming Conventions(MVVM命名規則)

以下の命名規則により、ViewをViewModelに暗黙的に関連づける。

  • ViewModel, PageModel, Modelで終わるクラスは、XAML(View)に対応するViewModelと見なされる
  • PageまたはViewで終わるXAMLファイルは、ViewModelに対応するXAML(View)と見なされる
  • ViewとViewModelがPage, ViewまたはViewModelなしで同じ名前を共有する場合、MFractorは暗黙的な関連付けを行う

LoginPage.xaml , LoginPage.xaml.cs , LoginViewMode.cs で考えてみると…。

  • LoginPage.xaml は、XAML(View)と見なされる
  • LoginPage.xaml.cs は、コードビハインドクラスと見なされる
  • LoginViewModel.cs は、ViewModelと見なされる

Using Mvvm Navigation(MVVMナビゲーションの使用)

MVVM命名規則を適用することにより、View, コードビハインドクラス, ViewModel間を素早く移動できる。

右クリックして選択:

  • Go-To ViewModel
  • Go-To Code Behind Class
  • Go-To Xaml View

Xaml Analysis(XAML分析)

XAML分析は、XAMLファイルのコードの問題を検査し、問題箇所を赤/黄/青の下線で示す。

  • 問題箇所にカーソルを置くと、コードの問題に関する詳細情報が表示される
  • 赤い下線は、コンパイルエラーまたは実行時エラーを示す
  • 黄色い下線はコンパイルの警告を示す
  • 青い下線はコードの改善を示す
  • 問題を修正するには、問題箇所を右クリックし、修正を参照して適用する修正を選択する

(Xamarin.Forms)WebViewについて -その2- Webブラウザで開く

以前、WebViewに関してごちゃごちゃと書きました。

以前の記事はコチラ↓
(Xamarin.Forms)WebViewについて - Makopy'5 La6

今後、WebView周りの実装について何度かに分けて覚書しておく予定です。
今回は直接WebViewのトピックではありませんが、Webブラウザでページを開く制御について書きます。

Webブラウザで開く

Device.OpenUriを用います。

サンプルプロジェクトはこちら

github.com

WebやWebView周りの諸々については、このプロジェクトに組み込んでいく予定です。

スマホアプリにおけるWebページ表示

ケースバイケースですが。
スマホアプリにおけるWebページ表示については、概ね下記のような要望のパターンがあります。

  • WebViewを用いて内部で開く
  • Webブラウザで開く
  • 内部コンテンツはWebViewで、WebページはWebブラウザで開く
  • 内部コンテンツと一部WebページをWebViewで、それ以外はブラウザで開く

オンライン/オフラインに関わらずユーザに一読してもらいたい文書や、原則的に変更がないコンテンツなどを内部コンテンツとして持っておくことがあります。
そのようなコンテンツをHTML/CSSで作成してWebViewで表示するということがよくあります。

逆に、閲覧を強制する必要のないコンテンツや既存のWebページをそのまま利用したい場合は、Web上のページにアクセスすることが多いです。
この場合、WebViewを用いるかWebブラウザで開くかはケースバイケースです。 既存のWebページをWebViewで開く場合、アプリとは関係のない先へのリンクなどが存在することもあり、

  • WebView上の戻り遷移をサポートする
  • WebView上のリンクを制限する

といったような、何かしらの制御が必要になります。

アプリ上の画面遷移の整合性なども考えると、一難去ってまた一難的に、あれこれと考えなければならないことが多いです。
特殊な事情やアプリ内部に閉じ込める必要がない場合には、Webブラウザで開く方向に調整をした方が楽だと思います。

一番危険なのは、
「WebViewにURL設定するだけ」
という前提から入ってしまうことです。

ブラウザアプリやハイブリッドアプリを除けば、WebViewがメインに来ることはあまりないと思います。
それゆえにWebView周辺のことに関しては見積もりが甘くなることもしばしばです。
WebViewやその制御自体の問題ではありませんが、こういったこともWebViewの怖いところです…。

(Xamarin.Forms)端末の画面サイズの取得

基本的に意識すべきではない

じゃあ、こんな記事書くなよ…。
と、思われてしまうかもしれませんが。

端末の画面サイズを取得して、それを元に計算するようなシーンはない方がいいです。
画面サイズやOSによらず、共通のレイアウトを適用できるように作るべきだし、それがXamarin.Formsのいいところだからです。

しかしながら、

  • 回転
  • キーボード表示

などの要因により、
Pageのサイズが動的に変わってしまうような状況もありえます。
そのような場合においては、
固定値として基準になるサイズ
が欲しくなることがあります。

そんな時の為に、その方法を記しておこうと思います。

実装

  • インタフェース部

  • .Droid

  • .iOS

  • 使い方

サンプルプロジェクトはこちら↓
github.com

ポイント

Androidでは、下記の点に注意です。

  • ステータスバーの高さを別途取得して引いておく必要がある
  • 取得できるサイズの単位はPixel
    • Xamarin.Formsで扱うサイズの単位はDIPなので、PixelDIPへの変換が必要
      • Density-independent Pixels = 密度に非依存のピクセル

(Xamarin.Forms)SVProgressHUDを使う

SVProgressHUDとは?

“SVProgressHUD is a clean and easy-to-use HUD meant to display the progress of an ongoing task on iOS and tvOS.”

github.com

dev.classmethod.jp

iOSのネイティブ開発ではよくお世話になっています!

SVProgressHUDのいいところ

☆とにかく便利☆

  • UIがシンプルで標準UIとの親和性が高く、組み込みやすい
  • コード上での使い方もシンプル
  • UIActivityIndicatorViewを使った面倒な実装とサヨウナラ
    • これはこれで必要な場合もあるのでケースバイケース

Xamarin.FormsでSVProgressHUDを使いたい!

非常に便利なので、
Xamarin.Formsでも使いたいなぁ…

と調べてみると、
iOS/Androidについては、Xamarin用にポーティングされたものが存在します。

これらのパッケージを追加して、DependencyServiceから使えばよさそうです。

実装例

ここでは自分が好んでよく使う形式に丸め込んで単純な形で共通I/F化しています。

  • インタフェース部

  • .Droid

  • .iOS

  • 使い方

サンプルプロジェクトはこちら↓

github.com

(Xamarin.Forms)WebViewについて

WebViewの用途

例えば、下記のような用途があります。

  • 内部HTMLコンテンツの表示
  • 外部ページの表示
  • Web APIレスポンスパース

WebViewは楽じゃない…

実戦のスマホアプリ開発において、WebViewの存在はまぁまぁ欠かせないものだと思います。
WebViewは単純に配置して使ってみるだけであれば、割と簡単なコンポーネントです。

しかしながら、実戦の開発においては、
単純にWebページやコンテンツを表示して終わり
というパターンは少なく、

  • 表示ページからのリンク先を制限する
  • 内部HTMLから外のページへリンクする場合は外部ブラウザで表示する
  • HTML上のボタンタップでネイティブの画面に遷移する

と言ったような要求や仕様と隣り合わせになることが多いです。
その実現のためには、

  • 各種イベントの捕捉(フック)
  • JavaScript連携

といった制御が必要になります。

WebViewで上記のような対応をする場合、
本来サーバサイドやWebページ側が対応すべきだったり、その方が楽な場合も多いのですが。
「アプリのWebViewの制御で可能な限り何とかする」
という、Web周りの面倒を吸収するような役割を期待されていることもあります。

Xamarin.FormsにおけるWebView

例によって、公式のDevelopers Guidesです。
WebView - Xamarin

Webページやコンテンツの表示だけであれば問題なさそうです。
しかしながら、イベントを捕捉したりJavaScriptと連携するような込み入った制御はできそうにありません。
込み入ったことをしたい場合は、Custom RendererでOSごとの実装が必要になります。
OSごとの実装をする一方、UI層との連携には統一のI/Fを準備する必要があります。

この辺りは別記事で、後日改めて記事にしたいと思います。

実は…。
現在進行形で実戦の開発でぼちぼち大変な思いをしています。
大変なのは業務上の経緯や都合も多分に含んではいますがw
業務的なお話は除いた技術的なトピックの部分で、自身が苦労したことを覚書としてしたためる予定です。

(Xamarin.Forms)Warningを無効化する

Warningの無効化

Warningの取り扱いについては、個人やプロジェクトの単位でいろんなポリシーがあると思います。
WarningをErrorと見なすような厳しいポリシーもあれば、100以上ものWarningが放置されているプロジェクトを見かけることもあります。
それらの是非についてはここでは触れません。
どれにもそれなりの理由や背景があると思います。
是非はともかく、Warning無効化の方法について触れたいと思います。

Xamarin.FormsでのWarning無効化

以下、CS0618というWarningを例とします。
いずれの方法も、コード CS0618から、「CS」を除いた番号の部分を使用します。
0618でもよいし、618でもOKです。

CS0618については、こちら。
Compiler Warning (level 2) CS0618

プロジェクト全体で無効化

  • コンパイラ設定で警告無視対象に含める
    • (Visual StudioとXamarin Studioでは具体的な画面や設定項目名が異なります)

ファイル単位で無効化

  • ファイル冒頭でdisable

局所的に無効化

  • Warningを回避したい箇所をdisableとrestoreで囲む

Xamarin Studioでの困りごと

筆者の個人的な開発環境はMac OS上のXamarin Studioです。
この記事を書いている時点では、
Xamarin Studio Community 6.2.1(build 3)
を使用しています。

上記環境では、以下のような困りごとがあります。

  • エラー出力のWarning表示はリアルタイムではない
    • エディタ上はリアルタイムにWarning箇所に波線でアンダーライン表示される
    • エラー出力でのWarning表示はビルド完了時に反映される
      • ここまでこないとコードが分からない…。
  • コンパイラの[警告を無視]のリストに番号を設定した場合、エディタ上の表示はWarningとして表示されたまま

Xamarin.FormsでのWarning

Xamarin.Formsでの開発は、スマホアプリ開発です。
スマホアプリの開発となると避けられない問題として、
「どこまで古いOSバージョンに対応するか?」
というのがあります。

古いOSをサポート対象に含めている場合、どうしてもOSバージョン分岐して古い形式での実装を残さざるを得ないことがあります。
今回例に出したCS0618を引き起こすケースのひとつです。
Warning無効化に安易に頼らずに解決するの努力は必要ですが…。
どうしてもの場合はあれこれ考えるよりは、「局所的に」潰してしまうのがいいと思っています。
もちろん、動作的に問題がないことの確認が取れていることは大前提になります。

個人的なWarningに対するポリシー

個人的なWarningに対するポリシーは、
「不必要なWarningは出すべきでないし、Warningは放置しない」
です。

何か込み入った問題が起きた時に、Warningがあれば疑ってみたくなります。
その時に100も200もWarningが放置されていると困りますね…。
また、そのような状態からでは、新たなWarningが埋もれやすくなるなど、見通しの悪さを生み出します。
簡単に潰せるWarningはもちろん放置せず、どうしても消えないWarningは無効化で対応できれば対応するのが、個人的な流儀です。