ディーバ Blog

大阪発 C#の会社、株式会社ディーバの Blog です。

Xamarin.iOS で psd ファイルを表示

Visual Studio (Xamarin.iOS)の iOS アプリで Photoshop ファイル(.psd ファイル)を、できるだけお手軽に表示する方法です。

UIWebView

iOS 10 から UIWevView で psd ファイルが表示できるようになっています! JPEG 画像と同じように表示するだけで psd ファイルが描画されます。

webView.LoadRequest(new NSUrlRequest("file://***"));

PSD Plugin for Paint.NET

C# によるライブラリでは、Paint.NET で psd ファイルを読み込み・保存可能にするプラグイン「PSD Plugin for Paint.NET」を開発されている方がいます。

Xamarin.iOS プロジェクトに組み込んでみたところ、少しの修正で使えました。コードは割愛。

プラグインのソースコードは、CodePlex にあります(MIT ライセンス)。現在のバージョンは、Version 2.5.0 (Sep 11, 2016)。

特徴は、レイヤー情報も読み込めます。ただし、各レイヤーの合成は Paint.NET 本体の仕事です。合成しようとすると、また別に自力で処理が必要なため、使いどころは難しそうです。。

Magick.NET

最後は参考情報です。

C# 製の画像ライブラリ「Magick.NET」では、psd ファイルも扱えます。ただし Windows 専用です。

.NET Core 版も開発されていますが、現在(Version 7.0.5.502)は、Windows でのみしか動きません。今後、Xamarin.iOS 等と組み合わせて使えるようになるかもしれません。

例外 Foundation.You_Should_Not_Call_base_In_This_Method

Xamarin で開発していると「Foundation.You_Should_Not_Call_base_In_This_Method: Exception of type ‘Foundation.You_Should_Not_Call_base_In_This_Method’ was thrown.」という例外とメッセージが出ることがあります。

名前の通り、base クラスのメソッドを呼び出してはいけません。UITableViewSource など override して使っているメソッドで、エディターが自動挿入した base クラスへの呼び出しがないか確認してみてください。

Xamarin + MvvmCross などの環境の場合、ピンポイントで例外発生場所を示してくれないときがあります。TableViewSource の場合、CanEditRow メソッドなどが base クラスのメソッドをつかえません。

Android カメラ API でフロント/バックカメラ画像を同時に表示

Android のフロント/バックカメラを同時にアクセスする方法です。結論は Android 4 ではできたようで 5.0 (Lollipop) からできなくなっている(?)ようです。

Android の カメラ API は、新旧2種類あります。

Camera

旧 Camera API では、実際にされている方がいて、同時に両方のカメラ映像を表示するデモとソースコードが公開されています。

www.youtube.com

bitbucket.org

ただし、Android 5 で実行すると Camera.Open のところで Fail to connect to camera service の例外が出ます。Bitbucket のプロジェクトの Issue にそのような コメント もあります。

Camera2

新しい camera2 API で試してみると、CmeraManage.openCamera で2台目にアクセスすると MAX_CAMERAS_IN_USE エラーが発生します。

複数の Android 端末で試しましたが同じ結果。もしかすると機種によっては可能なものもあるかもしれませんが、Android OS で拒否されているのかも。

Galaxy シリーズには、デュアルカメラアプリがあり、標準カメラアプリではもちろん同時撮影できますが、試したコードは同様にエラーとなりました。

操作ガイド

MvvmCross + Xamarin.iOS で NavigationBar 付きの modal 画面を使う

MvvmCross で画面遷移は ViewModel 側で ShowViewModel<SecondViewModel>() のように ShowViewModel メソッドを使います。

github.com

このとき iOS アプリで modal 画面として表示する方法です。

IMvxModalIosView の実装

View 側のクラスは IMvxModalIosView を実装します。

public partial class SecondView : MvxViewController<SecondViewModel>, IMvxModalIosView<SecondViewModel>
{
    public SecondView(IntPtr handle) : base(handle)
    {
    }
}

MvxIosViewPresenter のカスタマイズ

デフォルトの Presenter クラスを override することで、iOS の画面遷移・表示をカスタマイズできます。modal 表示をサポートするクラスが用意されているので、これを使います。

AppDelegate.cs にある次の部分を修正します。

var setup = new Setup(this, Window);
setup.Initialize();

単に modal を使う場合は、MvxModalSupportIosViewPresenter クラスを使います。この場合は modal 画面の NavigationController は null になります。

var presenter = new MvxModalSupportIosViewPresenter(this, Window);
var setup = new Setup(this, presenter);
setup.Initialize();

NavigationBar を付けて modal 画面を表示したい場合は、MvxModalNavSupportIosViewPresenter クラスを使います。

var presenter = new MvxModalNavSupportIosViewPresenter(this, Window);
var setup = new Setup(this, presenter);
setup.Initialize();

何をしているかはソースコードを読むしかありません。

github.com

Xamarin.Android で interface を実装するとき Handle と Dispose の実装

Xamarin.Android で Listener などの interface を実装しようとしたとき、Handle プロパティと Dispose メソッドを実装する必要があります。

class SampleListener : AppBarLayout.IOnOffsetChangedListener
{
    public IntPtr Handle => throw new NotImplementedException();

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    public void OnOffsetChanged(AppBarLayout appBarLayout, int verticalOffset)
    {
        throw new NotImplementedException();
    }
}

これは Java.Lang.Object を継承すれば解決します。

class SampleListener : Java.Lang.Object, AppBarLayout.IOnOffsetChangedListener
{
    public void OnOffsetChanged(AppBarLayout appBarLayout, int verticalOffset)
    {
        throw new NotImplementedException();
    }
}

「エラー: error MT1108: Could not find developer tools for this 10.2.1 (14D27) device.」でアプリが起動しない

Xamarin (Visual Studio) で次のようなエラーが出る場合の対処です。

起動に失敗しました。アプリ ‘AppName’‘DeviceName’ で起動できませんでした。 エラー: error MT1108: Could not find developer tools for this 10.2.1 (14D27) device. Please ensure you are using a compatible Xcode version and then connect this device to Xcode to install the development support files.

  • アプリの SDK バージョンが iOS 10.1
  • デバッグ対象のデバイスが iOS 10.2
  • Xcode のサポートしているバージョンが iOS 10.1

というように、アプリの配置先の方が新しいバージョンだと起こるようです。

対処は、最新の Xcode をインストールして、アプリの SDK バージョンを対象のデバイスと合わせます。

※ このエラーは Xcode によるもので Xamarin とは直接関係しません。

Azure Web App で ASP.NET MVC Web アプリの初回アクセスが遅い

ASP.NET MVC Web アプリケーションを Azure Web App へ発行した場合、初回の表示が非常に遅い場合、次の設定を見直すと高速化できます。

常時接続をオン

Azure ポータルで、Web App の「アプリケーション設定」にある「常時接続」をオンにします。

f:id:jz5_diva:20170227140040p:plain

「Web アプリを毎回読み込む必要があることを示します。既定では、Web アプリはアイドルになった後でアンロードされます。この Web アプリで実行されている継続的な Web ジョブがある場合は、このオプションを有効にすることをお勧めします」とのこと。

IIS の開始モード (startMode) 設定の “AlwaysRunning” が、この常時接続 (Always On) にあたるようです。

ファイル発行オプションでプリコンパイルする

Visual Studio の発行の「設定」で、ファイル発行オプションの「発行中にプリコンパイルする」にチェックします。また、「構成」ウィンドウの「プリコンパイル済みサイトを更新可能にする」のチェックを外します。

f:id:jz5_diva:20170227135911p:plain

f:id:jz5_diva:20170227135914p:plain

以上で、発行時に少し時間がかかりますが、初回アクセスの時間が早くなっているはずです。ただし、View のみの更新(cshtml ファイルのみを差し替え)などはできなくなります。

※ 「App_Dataフォルダーのファイルを除外する」は、発行時に App_Data フォルダーの内容を追加や更新したりしません。必要に応じてオン・オフしてください。

発行先の追加ファイルを削除する

プリコンパイルせず発行したことがある場合、プリコンパイルしたアプリの実行に不要なフォルダーがサーバーに残っているため「The directory ‘/App_GlobalResources/’ is not allowed because the application is precompiled」といったエラーが発生するかもしれません。

その場合、ファイル発行オプションの「発行先の追加ファイルを削除する」をチェックして発行すれば、プロジェクトにないファイル等は削除され、エラーが起きません。アプリでサーバーに直接ファイルを作っている場合は、それらのファイルも削除されるので注意してください。