JXUGC #23 Xamarin 無料化一周年記念勉強会! で話をしてきました

 先日開催された

JXUGC #23 Xamarin 無料化一周年記念勉強会!
https://jxug.connpass.com/event/53767/

 にて
 F# で Welcome to Xamarin Forms!
 といタイトルで話をしました。[資料]
 
 内容は F# + PCL + Forms + Visual Studio (Windows) 環境で Android エミュレーターでデバッグ実行するまでの地雷処理です。
 この情報の共有で F# 目当てで Xamarin 始めようとした方が一人でも多く実際に活用するところまで進んでくれたらうれしいです。
 
 余談ですが、今回登壇にあたって一番怖かったのは同日に別の地域で F# の勉強会が開催されていたため、間違った場合にも訂正フォーローのマサカリをもらえないことでした。
 
 次回は登壇初心者特集らしいので、皆さん是非挑戦してください。きっと良い経験になります。

広告

Xamarin.Android で 配置に失敗する場合

 実際のところ配置に失敗するパターンはいくつもあると思います。その内の1パターンです。
 

■ 現象


 Xamarin.Android アプリ開発時に、特にビルドエラーもなくデバッグ用の実機もしくはエミュレーターにも問題がないが、deploy に失敗する。
 

■ 原因


 AndroidService の実装時、ServiceName (パッケージ名) の先頭が大文字だと配置に失敗します。
 

■ 対策


 Name の先頭を小文字にしてください。
 

■ 再現コード


[Service(Name = "Com.SampleApp.SampleService")]
public class SampleService : Service
{
    public override IBinder OnBind(Intent intent)
    {
        throw new NotImplementedException();
    }
}

 

■ 対策済みコード


[Service(Name = "com.SampleApp.SampleService")]
public class SampleService : Service
{
    public override IBinder OnBind(Intent intent)
    {
        throw new NotImplementedException();
    }
}

[Xamarin] Android の設定画面を開く

Android でアプリから設定画面を開くには、Xamarin.Forms.Forms.Context.StartActivity メソッドを使用します。
次のコードでは PCL から DependencyService で呼び出しています。
 

■ コード説明

一つ目のクラスは .Android プロジェクトに、二つ目のクラスとインタフェースは PCL プロジェクトに作成します。
二つ目のクラスで、Intent クラスのコンストラクタに渡している引数でどの設定の画面化を指定し、ここでは言語と入力の設定を開いています。
引数として渡す値は、Android.Provider.Settings クラスに定数として定義されています。
 

■ コード

[assembly: Xamarin.Forms.Dependency(typeof(Settings.Droid.OpenSettings))]
namespace Settings.Droid
{
    internal class OpenSettings : IOpenSettings
    {
        public void StartInputMethodSettings()
        {
            Xamarin.Forms.Forms.Context.StartActivity(new Android.Content.Intent(Android.Provider.Settings.ActionInputMethodSettings));
        }
    }
}

 

using System;
using Xamarin.Forms;

namespace Settings
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void Button_Clicked(object sender, EventArgs e)
        {
            Xamarin.Forms.DependencyService.Get<IOpenSettings>().StartInputMethodSettings();
        }
    }

    public interface IOpenSettings
    {
        void StartInputMethodSettings();
    }
}

[Xamarin] iOS の設定画面を開く

iOS でアプリから設定画面を開くには、UIKit.UIApplication.SharedApplication.OpenUrl メソッドを魔法のワードを引数にして呼び出せば開きます。
次のコードでは PCL から DependencyService で呼び出しています。
 

■ コード説明

一つ目のクラスは .iOS プロジェクトに、二つ目のクラスとインタフェースは PCL プロジェクトに作成します。
二つ目のクラスで、OpenUrl に渡している引数が魔法のワードで、ここではキーボードの設定を開いています。
魔法のワードは 「iOS Prefs」 などで Bing ってください。
https://www.bing.com/search?q=ios+prefs
 

■ コード

using Foundation;
using UIKit;
using Xamarin.Forms;

[assembly: Dependency(typeof(Settings.iOS.OpenSettings))]
namespace Settings.iOS
{
    public class OpenSettings:IOpenSettings
    {
        public void OpenUrl(string url)
        {
            UIKit.UIApplication.SharedApplication.OpenUrl(new NSUrl(url), new NSDictionary(), null);
        }
    }
}

 

using Xamarin.Forms;

namespace Settings
{
    public partial class SettingsPage : ContentPage
    {
        public SettingsPage()
        {
            InitializeComponent();
        }

        void Button_Clicked(object sender, System.EventArgs e)
        {
            DependencyService.Get<IOpenSettings>().OpenUrl("App-Prefs:root=General&path=Keyboard");
        }
    }

    public interface IOpenSettings
    {
        void OpenUrl(string url);
    }
}

[Xamarin.Android] F# と C# で生成されるクラス名が違う

 F#C#リソース ID を保持するクラスのクラス名/ネームスペースが異なります。
 C# では Resource クラスの public な内部クラスとして Drawable クラスや String クラスが作成されました。
 F# では Resource_Drawable クラスや Resource_String クラスが作成されます。
 
 使用する際は、C#. だった部分を F# では _ に置き換えるだけです。

Visaul Studio Emulator for Android で電話機能をデバッグしようとするとメッセージが表示される

 Visual Studio Emulator for Android で電話機能をデバッグしようとすると、次のエラーが発生します。

To Place a call, first turn off Airplane mode.

または

機内モードをOFFにしてから発信してください。

 メッセージの内容に従って機内モードをOFFにしても変わりませんし、そもそもOFFが初期状態です。
 これは、エミュレーターで実行できない機能のためこうなっているようです。
 

■ 対処

 そもそもエミュレーターで実行できない機能です。
 デバッグが必要であれば実機を使用するのが良いでしょう。

Visual Studio で F# プロジェクトがエラーで開けなくなった

 Visual StudioF#Xamarin.Android プロジェクトを扱っている際に、次のエラーが表示され、プロジェクトが開けなくなることがありました。

プロジェクト ‘XXXXXXXXXX.fsproj’ を開くと、ソリューション エクスプローラー内でフォルダーが複数回表示されるため、このプロジェクトを開けませんでした。この問題がある項目の 1 つは ‘XXXXXXXXXX\XXXXXXXXXX\XXXXXXXXXX.XXX’ です。このプロジェクトを Visual Studio で開くには、プロジェクト ファイルを編集して問題を解決してください。

または

The project ‘XXXXXXXXXX.fsproj’ could not be opened because opening it would cause a folder to be rendered multiple times in the solution explorer. One such problematic item is ‘XXXXXXXXXX\XXXXXXXXXX\XXXXXXXXXX.XXX’. To open this project in Visual Studio, first edit the project file and fix the problem.

 これは、.fsproj ファイルが正しく設定されなかった場合に発生します。
 ソリューションにファイルを追加した際に発生しました。

■ 対処

 .fsproj を開いて編集します。
 同じフォルダ内のファイルは、間に別のフォルダのファイルをはさむことなく続けて書かれているようにします。

  <ItemGroup>
    <AndroidResource Include="Resources\layout\Tabbar.axml" />
    <AndroidResource Include="Resources\values\styles.xml" />
    <AndroidResource Include="Resources\layout\Toolbar.axml" />

 のようになっている場合、次のようにします。

  <ItemGroup>
    <AndroidResource Include="Resources\values\styles.xml" />
    <AndroidResource Include="Resources\layout\Tabbar.axml" />
    <AndroidResource Include="Resources\layout\Toolbar.axml" />

 これでプロジェクトを開けるようになりました。