読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Xamarin.FormsでPrism.Formsを使ってPCLに非対応なライブラリを使う方法

例えばMicrosoft.AzureのStorageのライブラリなんかがXamarin.AndroidとXamarin.iOSには対応してるけどPCLには対応してないといった感じです。

被害者がここに。

対応方法

ということで対応方法ですが、id:chomadoさんがちゃんと対応してました。

つまり、プラットフォーム固有機能を呼ぶときと同じ対応でOKということですね。

Prism.Formsでプラットフォーム固有処理を呼び出す方法はDependencyServiceを使うかIPlatformInitializerを使う方法の2通りがあります。

www.nuits.jp

特に理由がない限りは(例えば既存でDependencyServiceでガッツリ作ってるとか。まぁそれでも移行は楽ちんだからやった方がいいと思うけど)IPlatformInitializerを使うのがいいでしょう。柔軟ですし、早いですし。

ということで対応方法のステップ。

ステップ1

PCLのプロジェクトにインターフェースを切る。

public interface IHogeService
{
  Task<Hoge> HogeAsync();
}

ステップ2

NuGetからAndroidとiOSプロジェクトにライブラリを追加する。

ステップ3

AndroidかiOSプロジェクトのどちらかに、PCLに定義したインターフェースの実装を定義する。

public class HogeService : IHogeService
{
  public Task<Hoge> HogeAsync()
  {
    // ライブラリを使ったコード
  }
}

ステップ4

もう一方のプロジェクト(Androidにステップ3で実装したならiOS、iOSに実装したならAndroid)にリンクとしてステップ3で作ったファイルを追加。

これでソースコードの共有化を行います。

ステップ5

各プラットフォームのIPlatformInitializerの実装にサービスの登録を行う。Prism Template Packを使ってる場合は自動的にMainActivityAppDelegateに追加されています。

container.RegisterType<IHogeService, HogeService>(new ContainerControledLifetimeManager());

ステップ6

PCLで使いましょう。 ViewModelとかのコンストラクタにサービスを受け取るようにすることで、Androidで実行されたときはAndroid用のクラスが、iOSで実行されたときはiOS用のクラスがインジェクションされます。

まとめ

普通PCLか.NET Standard対応してるだろJKと思ってても、思わぬところで罠があったりするので頭の片隅に入れておきましょう。