Xamarin.iOS(storybaord)+MvvmCross+Xamarin.Forms を混在させたアプリを作る

ちょうど Xamarin.iOS のアップデートがあって、Xamarin.iOS10 と monotouch が混乱している状態で苦労したのですが、一応動くところまでできたので記事を書いておきます。

目標

Xamarin.iOS(storyboard) と MvvmCross と Xamarin.Froms を混在させたアプリを作ります。単純に混在させるというよりも、アプリの歴史的な経緯から、

  1. Xamarin.iOS で storyboard で作っているアプリがあって、
  2. 去年あたりに MvvmCross を使って、MVVM 対応したアプリになって、
  3. 今年ぐらいから、Xamarin.Forms に対応したいけどどうしようか?

のようなストーリーを考えています。まあ、MVVM 対応するのは MvvmCross でもよいし、MvvmLight でも Prism でも良いわけですが、そこに Xamarin.Froms の XAML をどうねじ込むか、ってのが問題になりますよね。最初から、Xamarin.Forms で作り直してしまう方法もあるけど労力的に大変だし、そもそも Xamarin.Forms のコントロールは非力なので、そのまま移植できないパターンも多い。DepnencyService とか作ればいいけど、面倒だったら、もともと storyboard と Xamarin.iOS の組み合わせで数ページだけ作るのが簡単ではないか?というパターンです。

アプリの想定

こんな風に、Master-Detail で作っていたアプリに対して、MvvvmCross や Xamarin.Forms のページを追加していきます。

これによって、既存のページはそのままにして、新しいページを MvvmCross や Xamarin.Forms で作れればよいかなと。

プロジェクト構成

storyboard を含むのが、MvxXForms.UI.Touch プロジェクトで Detail ページ用にそれぞれのクラスを設定しています。Mater-Detail の Master がリストの場合は詳細ページは同じページを使うことが多いのですが、Mater が固定ページ(メニューページの代わり)に使っている場合には、項目をクリックしたときにそれぞれの詳細ページが表示されるので、こういう構成にしてあります。Master ページにボタンを並べて画面遷移する場合も似た感じになります。

Xamarin.iOS+storybardのみ場合

最初は、MvxXForms.UI.Touch プロジェクト のようなプロジェクトがあって、まだ MVVM 化されていない状態を考えます。

storyboard は、

– Navigation Controller
– Master ページ
– オレンジ色の Detail ページ

だけの状態になります。Master から Detail へ遷移させる場合は、

Creating an Unwind Segue | Xamarin
http://developer.xamarin.com/recipes/ios/general/storyboard/unwind_segue/

な感じで Ctrl キーを押しながらマウスのドラッグで線が引けます。
サンプルコードでは、RowSelected 内でデータを引き渡すために小細工をしていますが、storyboard segue を使えば画面遷移だけならばノンコーディングでいけます。

MvvmCross のページを追加する

MVVM 化するために、MvxXForms.Core プロジェクトを追加します。ViewModel 自体は、先の MvxXForms.UI.Touch に追加してしまってもよいのですが、先行き Android と共有させることを考えて PCL プロジェクトで作っておきます。

int と string を持つ TipViewModel クラスを定義して、

public class TipViewModel : MvxViewModel
{
	public TipViewModel()
	{
	}

	int _pageNum;
	public int PageNum
	{
		get { return _pageNum; }
		set { _pageNum = value; RaisePropertyChanged(() => PageNum); }
	}
	string _Name;
	public string Name
	{
		get { return _Name; }
		set { _Name = value; RaisePropertyChanged(() => Name); }
	}
}

中身が空っぽな App クラスを作っておきます。App クラスを MvxXForms.UI.Touch プロジェクトから参照しなければよいのですが、まあ、これは初期化のためのお約束コードということで。

public class App : MvxApplication
{
	public App()
	{
	}
}

MvxXForms.UI.Touch プロジェクトに戻って、UIApplicationDelegate を MvxApplicationDelegate に変更。
FinishedLaunching メソッドをオーバーライドして、MvvmCross の初期化を行います。

public partial class AppDelegate : MvxApplicationDelegate
{
	// class-level declarations

	public override UIWindow Window
	{
		get;
		set;
	}

	public override bool FinishedLaunching(UIApplication app, NSDictionary options)
	{
		var presenter = new MvxTouchViewPresenter(this, Window);
		var setup = new Setup(this, presenter);
		setup.Initialize();
		return true;
	}
}

あとは、Detail ページに対応する ViewController を MvxViewController から継承させて、set.Bind 等でバインドを行えば ok です。

public partial class Detail2ViewController : MvxViewController
{
	public Detail2ViewController(IntPtr handle)
		: base(handle)
	{
	}

	public new TipViewModel ViewModel
	{
		get { return (TipViewModel)base.ViewModel; }
		set { base.ViewModel = value; }
	}

	public override void DidReceiveMemoryWarning()
	{
		// Releases the view if it doesn't have a superview.
		base.DidReceiveMemoryWarning();

		// Release any cached data, images, etc that aren't in use.
	}

	public override void ViewDidLoad()
	{
		this.Request = new MvxViewModelRequest(typeof(TipViewModel), null, null, new MvxRequestedBy());
		base.ViewDidLoad();
		// Perform any additional setup after loading the view, typically from a nib.
		var set = this.CreateBindingSet<Detail2ViewController, TipViewModel>();
		set.Bind(labelPageNum).To(vm => vm.PageNum);
		set.Bind(labelName).To(vm => vm.Name);
		set.Apply();

		// マスターからのデータ引き渡し
		this.ViewModel = MasterViewController._datavm;
	}
}

storyboard の Detail ページと Detail2ViewController の結び付けは、プロパティウィンドウで Class を変更します。このあたりは Xcode と同じですね。

MasterViewController._datavm なところは、storyboard segue を使うと、内部的に一気に ViewController が作られてまうので、ViewModel プロパティを設定するタイミングがないため、こうやっています。Master ページで Cell をクリックしたときに、下記な方法でグローバル変数で渡します。ちょっとダサいんですが、仕方がありません。

public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
	var data = new MyData();
	switch ( indexPath.Row )
	{
...
		case 1:
			/// MvvmCross を使って vm 経由でデータを渡す
			/// 本来は data 経由のほうがいいけど、これはサンプルで
			/// あらかじめ storyboard segue でつなげておく
			_datavm = new TipViewModel()
			{
				PageNum = 2,
				Name = "use MvvmCross"
			};
			break;
...
}

storyboard segue を使わずに画面遷移をする

じゃあ、明示的に遷移先の ViewController を作って ViewModel を設定する方法でもよいだろう、というのが次の方法です。
目的の ViewController の「storyboard id」に、あらかじめ「Detail3ViewController」という名前を付けておいて(これはクラス名と異なっていても構いません)、Storyboard.InstantiateViewController メソッドで作成します。これを、NavigationController.ShowViewController メソッドで表示すれば ok です。

/// <summary>
/// 行をクリックしたとき
/// </summary>
/// <param name=&quot;tableView&quot;></param>
/// <param name=&quot;indexPath&quot;></param>
public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
	var data = new MyData();
	switch ( indexPath.Row )
	{
...
		case 2:
            /// storyboard のページを直接開く
			/// Storyboard ID を ViewController に設定しておく
			/// storyboard segue を使わないパターン
			var vc = (Detail3ViewController)Storyboard.InstantiateViewController(&quot;Detail3ViewController&quot;);
			this.NavigationController.ShowViewController(vc, this);
			_datavm2 = new TipViewModel2()
			{
				PageNum = 3,
				Name = &quot;Mvx + direct storyboard&quot;
			};
			break;

遷移先の ViewController を MvxViewController を継承するようにして、ViewModel に対応させてもそのまま使えます。
ちょっと注意しなければいけないのは、MvvmCross では ViewModel と ViewController が 1対1 じゃないと駄目なようです。実行時に TipViewModel が二つ以上の ViewController に設定されている、とエラーがでます。なので、仕方がないので TipViewModel2 という同じ中身のクラス(継承しているだけ)を使っているのですが。同じ ViewModel を複数の View に対応しても良いと思うのですが、ちょっとこの動きはよくわかりません。

Xamrin.Forms のページを呼び出す

Xamarin.Forms の XAML ページを Master ページから呼び出せるようにします。
MvxXForms.Form プロジェクトを別に作っていますが、たぶん、MvxXForms.UI.Touch に含ませてしまっても大丈夫だと思います。

DetailXFPage.xaml の中身を手書きします(Xamarin Studio を使うと、少しだけコード補完が効いて楽です)。

<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?>
<ContentPage xmlns=&quot;http://xamarin.com/schemas/2014/forms&quot;
					   xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
					   x:Class=&quot;MvxXForms.Form.DetailXFPage&quot;
					   Title=&quot;xamarin.forms page&quot;
					   BackgroundColor=&quot;Yellow&quot;
					   >
  <StackLayout Padding=&quot;10,80,10,10&quot;>
    <Label x:Name=&quot;label1&quot; Text=&quot;Xamarin.Forms page&quot;  />
    <Label Text=&quot;PageNum&quot; />
    <Label Text=&quot;{Binding PageNum, StringFormat='{0}'}&quot; BackgroundColor=&quot;Lime&quot; />
    <Label Text=&quot;Name&quot; />
    <Label Text=&quot;{Binding Name}&quot;  BackgroundColor=&quot;Lime&quot;/>
  </StackLayout>
</ContentPage>

Binding が XAML の中に記述できます。

Xamarin.Forms のプロジェクトでも App クラスがあるのですが、これは GetMainPage メソッドのように PCL プロジェクト内で作成した Page オブジェクトを返すための static メソッドです。なので、同じように、DetailXFPage を new して返すだけのメソッドを作っておきます。

public class App
{
	public static Page GetDetailPage()
	{
		return new DetailXFPage();
	}
}

Xamarin.Forms のページを呼び出すときは、先の storyboard segue を使わない方法と同じように、NavigationController.ShowViewController メソッドを使います。

public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
{
	var data = new MyData();
	switch ( indexPath.Row )
	{
...
		case 3:
			// Xamarin.Forms ページを開く
			var page = MvxXForms.Form.App.GetDetailPage();
			var vc2 = page.CreateViewController();
			var vm = new TipViewModel()
			{
				PageNum = 4,
				Name = "xamarin froms page"
			};
			page.BindingContext = vm;
			this.NavigationController.ShowViewController(vc2, this);
			break;

ContentPage の BindingContext プロパティに ViewModel のデータを設定すればバインドが完了します。

Xamarin.Forms の初期化のために、AppDelegate クラスに Forms.Init() を追加しておきます。
これで、Xamarin.Forms と MvvmCross が混在できます。

public partial class AppDelegate : MvxApplicationDelegate
{
	// class-level declarations

	public override UIWindow Window
	{
		get;
		set;
	}

	public override bool FinishedLaunching(UIApplication app, NSDictionary options)
	{
		Forms.Init();
		var presenter = new MvxTouchViewPresenter(this, Window);
		var setup = new Setup(this, presenter);
		setup.Initialize();
		return true;
	}
}

実行してみる

こんな風に、Master のページから各種のページに遷移ができます。

サンプルコード

MxSingleApp の中の MixMvxForms
https://github.com/moonmile/MxSingleApp

参考先

Xamarin.iOS ナビゲーションコントローラ – SIN@SAPPOROWORKSの覚書
http://furuya02.hatenablog.com/entry/2014/07/03/035352
Xamarin.iOSでStoryboardとXamarin.Formsを併用するには? – Build Insider
http://www.buildinsider.net/mobile/xamarintips/0006

カテゴリー: C#, Xamarin, iOS | Xamarin.iOS(storybaord)+MvvmCross+Xamarin.Forms を混在させたアプリを作る はコメントを受け付けていません

C# の Dictionary と F# の map

ちょっと気になったのでメモ書き

C# の Dictonary は referencesource/mscorlib/system/collections/generic/dictionary.cs にあって、buckets[hashCode % buckets.Length] な形でハッシュ値で計算。

F# の map は fsharp/src/fsharp/FSharp.Core/map.fs にあって、comparer を使って二分木

ちなみに C# の SortedDictionary は referencesource/System/compmod/system/collections/generic/sorteddictionary.cs にあって、TreeSet<KeyValuePair<TKey, TValue>> な二分木で計算。

ReadOnlyDictonary ってのもある。 ここ にソースがあるので見ると、dictonary を渡しているだけなので、中身は一緒。追加用のメソッドがないだけ。同じように ReadOnlyCollection があるけど、内部的には IList と同じ。なので、非同期に特化しているとか、分散されているとか、という訳ではないらしい。逆に言えば、初期化するときに分散に特化させたリストを渡せば、表面上は ReadOnlyCollection として扱える。Add メソッドなどを呼び出すと、実行時にエラーが発生する(メソッド自体をなくしてしまって、コンパイル時にエラーにする、ってのでもいいかもしれない)。

 

 

カテゴリー: 開発 | C# の Dictionary と F# の map はコメントを受け付けていません

Xamarin.iOS+MvvmCrossでstoryboardを使う方法(MvvmCross v3.2.2 対応)

Xamarin.iOS+MvvmCrossでstoryboardを使う方法 | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/5814

以前、書いたのですが、バージョンが上がって微妙に動きが異なっているので、メモ書きしておきます。
サンプルコードは http://1drv.ms/1CeHWYp からダウンロードができます。

MvvmCross のサンプルコードを storyboard 対応にする

Tip Calc The Core Project
https://github.com/MvvmCross/MvvmCross/wiki/Tip-Calc—The-Core-Project
Tip Calc A Xamarin.iOS UI project ・ MvvmCross/MvvmCross Wiki
https://github.com/MvvmCross/MvvmCross/wiki/Tip-Calc-A-Xamarin.iOS-UI-project

TipCalc.Core の中身

ViewModel は MvxViewModel クラスを継承して作ります。ここのバインドは、INotiryPropertyChanged を実装していればよいので、何で作っても良いはずです。
プロパティの変更時に、RaisePropertyChanged で変更通知をします。

public class TipViewModel : MvxViewModel
{
	private readonly ICalculation _calculation;
	public TipViewModel(ICalculation calculation)
	{
		_calculation = calculation;
	}

	public override void Start()
	{
		_subTotal = 100;
		_generosity = 10;
		Recalcuate();
		base.Start();
	}

	private double _subTotal;

	public double SubTotal
	{
		get { return _subTotal; }
		set { _subTotal = value; RaisePropertyChanged(() => SubTotal); Recalcuate(); }
	}

App.cs の中身は、空っぽでも動きます…と思ったけど、Calculation のインスタンスだけ作らないとダメです。この部分は、Calc 部分を ICalc で作っているので、こうなっているので、特に作らなければ App() の中身は空でも大丈夫です。

public App()
{
	Mvx.RegisterType<ICalculation, Calculation>();
	// Mvx.RegisterSingleton<IMvxAppStart>(new MvxAppStart<TipViewModel>());
}

RegisterSingleton を使うとシングルトンで作られてしまい、都合が悪いことが多いので、UI プロジェクトのほうで作ります。

TipCalc.UI.Touch の中身

Setup.cs の中身はほとんど空っぽです。

public class Setup : MvxTouchSetup
{
	public Setup(MvxApplicationDelegate appDelegate, IMvxTouchViewPresenter presenter)
		: base(appDelegate, presenter)
	{
	}

	protected override Cirrious.MvvmCross.ViewModels.IMvxApplication CreateApp()
	{
		return new App();
	}
}

AppDelegate.cs の中身は、Window プロパティを残して、FinishedLaunching だけオーバーライドします。
内部で window を作っているサンプルコードもあるのですが、別のところから Window プロパティを参照することができるので、元の状態で残したほうがベターです。
以前と違って、Setup の引数が変わっているので、MvxTouchViewPresenter オブジェクトを作って引き渡します。
まあ、Setup 自体を変えてしまってもいいのですが。

 [Register("AppDelegate")]
public partial class AppDelegate : MvxApplicationDelegate
{
	// class-level declarations
	public override UIWindow Window
	{
		get;
		set;
	}

	public override bool FinishedLaunching(UIApplication app, NSDictionary options)
	{
		var presenter = new MvxTouchViewPresenter(this, Window);
		var setup = new Setup(this, presenter);
		setup.Initialize();
		return true;
	}
}

TipCalc.UI.TouchViewController.cs の ViewModel は、MvxViewController を継承するように変更して、ViewDidLoad メソッドの中身だけ変更します。
base.ViewDidLoad で元のメソッドを呼び出す前に、MvxViewModelRequest オブジェクトを作らないといけません。この引数が変更になっていて、ViewModel のクラス名(ここでは TipViewModel )を渡します。

CreateBindingSet は拡張メソッドなので、
using Cirrious.MvvmCross.Binding.BindingContext;
することを忘れずに…いつもあれ?ってなるので。

public partial class TipCalcUITouchViewController : MvxViewController
{
	public TipCalcUITouchViewController(IntPtr handle)
		: base(handle)
	{
	}

	public new TipViewModel ViewModel
	{
		get { return (TipViewModel)base.ViewModel; }
		set { base.ViewModel = value; }
	}

	public override void ViewDidLoad()
	{
		this.Request = new MvxViewModelRequest(typeof(TipViewModel), null, null, new MvxRequestedBy());
		base.ViewDidLoad();
		// Perform any additional setup after loading the view, typically from a nib.
		var set = this.CreateBindingSet<TipCalcUITouchViewController, TipViewModel>();
		set.Bind(labelTip).To(vm => vm.Tip);
		set.Bind(textSubTotal).To(vm => vm.SubTotal);
		set.Bind(sliderGene).To(vm => vm.Generosity);
		set.Apply();
	}
}

Bind でコントロールを指定して、To で ViewModel のプロパティと結びつけます。いわゆる Binding の Path は .For( c => c.Text) で明示的に指定もできますが省略可能です(デフォルトプロパティを内部で持っていると思われる)。

実行結果

こんな風にスライダーを動かすと、ラベルの数値が変化します。

20141126_02

サンプルコード

サンプルはこちら
http://1drv.ms/1CeHWYp

カテゴリー: Xamarin, iOS | Xamarin.iOS+MvvmCrossでstoryboardを使う方法(MvvmCross v3.2.2 対応) はコメントを受け付けていません

Xamarin.Forms の話ともうちょっと突っ込んだ話…のメモ書き

第2回 Japan Xamarin User Group Conference 東日本編 : ATND
https://atnd.org/events/57246/

で 50分ほど頂いたので、Xamarin.Forms の概要ともうちょっと突っ込んだ話をします。

当日、聴衆の様子を見てから判断しますが、Xamarin.Forms の概要は、概要は Xamarin のホームページにあるし、日本語の情報もちらちらと揃っているので「概要」だけ聞かされても面白くない、って方が多い(私もその一人)と思われるので、

  • Xamarin.Forms のざっと概要を 15 分程度
  • カスタムコントロールを作る話を残りの時間で

ってことを考えます。カスタムコントロールは、いくつか方法があって、その中で 3 つの方法を紹介します。

  • 既存のコントロールを継承して、Xamarin.Forms 内で完結する方法
  • ネイティブ環境(iOS/Android)を使うために DependencyService を使う方法
  • カスタムレンダラーを使って、ネイティブ環境(iOS/Android)で描画させる方法

これも、それぞれについては Xamarin サイトや日本語の解説ページがあるのですが、ひとまとめに書いているものが無いのと、それぞれのサンプルが実用的すぎて難しい(!)ので、簡単なサンプルで比較します。

それぞれの解説自体は、本家 Xamarin のドキュメント(英語だけど)に載っている。

日本語のサンプルもある。

この他に考えられるカスタムコントロールとしては、

  • Xamarin.Forms.Labs を使う(ライブラリを買うとパターン)
  • リフレクションを使う(DependencyService と同じだが、インターフェースを定義しない)

ぐらいでしょうか。Xamarin.Forms 用のコントロールもいくつかあるので、それを購入するという方法もある。

話の流れ

  • Xamarin.iOS, Xamarin.Android で、ネイティブな環境のアプリを C#(.NET)で作れる。
  • UIが別(storyboard, axml)だったので、共通で使える Xamarin.Forms が現れる。
  • Xamarin.Forms のベースは XAML になる。
    • XAML の規格は Microsoft が公開していて、自由に作れる。
    • x:Class, x:Name などが決められている。
    • Microsoft の WPF/Sliverlight などの XAML と互換ではないが…いくつか互換がある。
    • iOS, Android, Windows Phone(Silverlight) の共通のコントロールが用意されている。
    • データバインドが使える。MS-XAML に規定されている {Binding …}
    • ドット付の名前 Grid.Row などが使える。これも MS-XAML に規定されている。
    • PLC あるは Shared プロジェクトとして作り、UI を共有する。
  • ベースコンテナで ContentPage などがある。
    • Grid、StackLayout のように MS-XAML と互換がある。
  • Xa-XAML は、XAML を解釈したのちに、それぞれの環境のコントロールにレンダリングする。
    • MS-XAML は、直接オブジェクトに変換される、という違いがある。
    • これは WPF, Silverlight, WinStore-XAML, WP-Xaml とそれぞれ違う
  • が、表面上は一緒なので、Xamarin.Forms も MS-XAML と同様に扱える。
  • 大抵は StackLayout と Grid を使いこなすと良い。
  • それぞれのプラットフォームの最大公約数なので、プラットフォーム特有の機能がない。
    • タップイベントやドラッグがないのが辛いところ。
  • 独自のコントロールや、機種ごとの機能を使うことができる。
    • 独自コントロールは、MS-XAML のユーザコントロールと似たように、既存のコントロールを組み合わせられる
      • ContentPage を継承した例が多いが、View を継承しても作ることができる。
      • xmlns:local=”clr-namespace=…” を使って、独自アセンブリをロードする
      • <local:CustomButton…> のように書く。
        • が、StackLayout の最後に計算されるという Bug ? がある。
    • DependencyService を使って、プラットフォーム毎の機能を使う。
      • 要するに intarface を利用した委譲パターン(Listenパターン?)
      • インターフェースを PCL 側に定義する
      • 内部動作を iOS/Android 側で実装する。
        • [assembly: Dependency … ] を定義する
      • DependencyService.Get<…> で呼び出す。
        • 実装がないときは null になる(コードを変えなくて良い利点がある)。
      • このテクニックは、共通処理を PCL で書き、それぞれの動作をプラットフォーム毎に書くパターンと同じなので、UI だけでなく普通の処理にも使える(機種番号を拾うとか、独自のフォルダアクセスとか)
    • カスタムレンダラを使う
      • 独自コントロールの内部動作だけ、プラットフォームに依存させる。
      • PCL に既存コントロールを継承したクラスを作る。
      • 実行時のレンダリングを、iOS/Android で OnElementChanged として書く。
        • たとえば Entry コントロールの場合は、レンダリング用の  EntryRenderer が定義されている。
        • ASP.NET のユーザコントロールの作り方に似ている。
        • ネイティブコントロール(iOS/Android)を自由に扱える。
  • 使い分ける
    • 共通画面や共通部品は、Xamarin.Forms の基本コントロールをまとめて扱う。
      • 独自のプロパティを作って、データバインディングすると再利用性が高まる。
      • XAML, コードのコピペではなく、ライブラリとして提供できる。
    • DependencyService は、ピンポイントで機種依存の機能を使う。
      • 共通のインターフェースを必要とするが、自分で定義できる。
      • PLC 内では Device で分岐させることも可能
        • ただし、iOS, Android, WP Silverlight 限定になるが… Device クラスを独自に作ることも可能。
    • UI がある場合は、カスタムレンダラを使う。
      • 応用範囲が広い
      • 必ず、Xamarin.Forms のコントロールを継承する必要あり? Renderer なので。
      • OnElementChanged 内で、マウスイベントを取ることも可能?
        • グラフィック表示
        • マウスイベントの取得
        • アニメーション処理
      • 機種ごとに、Xamarin.iOS/Android が使える。

これに図を加える。

カテゴリー: Xamarin | Xamarin.Forms の話ともうちょっと突っ込んだ話…のメモ書き はコメントを受け付けていません

Visual Studio 2013 + Hyper-V で Xamarin.Android を動かそう

Visual Studio 2015 preview を使って Hyper-V で Xamarin.Android を動かそう | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/6648

では、Visual Studio 2015 preview で Hyper-V の Android エミュレータを動かす方法を紹介しましたが、もう少し頑張ると現状の Visual Stuido 2013 からも Android エミュレータを動かすことができます。

注)動かせるのは動かせるのですが、Visual Studio からデバッグモードで動かすことはできなくて、何故か Release モードでデプロイした後に、エミュレータ上でアプリを起動できる、ってところまでです。デバッグ時に「Couldn’t connect to logcat, GetProcessId returned: 0」が出てデバッグ用のコネクションが接続しないのですが、アプリのデプロイは成功している状態になりました。

Visual Studio 2015 Preview をインストールする

Preview 版自体をインストールしない方法を模索してはいるのですが、ちょっと無理そう。ただし、Preview 版であっても 2013 と同居ができるので、この方法を使います(たぶん、2010 や 2012 が入っている状態でも同じだと思います)。

Visual Studio 2015 Downloads
http://www.visualstudio.com/downloads/visual-studio-2015-downloads-vs

  1. 実機 PC に Visual Studio 2015 preview をインストールする。
  2. 実機 PC の Hyper-V を有効にする。
  3. 最初の Xamarin Android プロジェクトを作って、リンク先から XamarinInstaller-VS2015 をダウンロード&インストールする。
  4. Visual Studio 2013 の拡張機能を 2015 へコピーする
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Xamarin\ を
    C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common\IDE\Extensions\ にコピーする。インストーラが Visual Studio 2013 のほうにしか拡張機能をコピーしないためです)
  5. C:\Program Files (x86)\NuGet\Visual Studio 2015\NuGet.Tools.vsix を実行して拡張機能を有効にする。
  6. Bussiness アカウントでログインをして、Xamarin Update で Statble に戻す。
  7. Statable に戻すときに、何故か元に戻しすぎてログインができない状態までになるが、慌てずに xamarin.com から XamarinInstaller をダウンロードして、再インストールすれば回復します。
  8. 2015 あるいは 2013 で Xamarin.Forms のプロジェクト( Mobile Apps )を作成する。
  9. Debug 実行をして、一旦、Hyper-V に VS Emulator Android – Phone を作成する。
  10. Debug 実行のままだと、Connect エラーが出るので、一度だけ Release モードで実行する。そうすると、デバッグ用のコネクション( GetProcessId が取れるようになる)が確立されて、以後は Debug モードでも実行できるようになる。

ここまでやると、Visual Studio 2013/2015 で Xamarin.Forms を使ってアプリを作ることができます。

お次は Xamarin.Android でもビルドできるように C:Program Files (x86)MSBuildXamarinAndroidXamarin.Android.Common.targets を修正します。

<Target Name=&quot;_ConvertDebuggingFiles&quot;
	Inputs=&quot;$(OutDir)$(TargetFileName);$(_IntermediatePdbFile)&quot;
	Outputs=&quot;$(OutDir)$(TargetFileName).mdb&quot; 
	DependsOnTargets=&quot;_ValidateAndroidPackageProperties&quot;>
	<ConvertDebuggingFiles InputFiles=&quot;$(OutDir)$(TargetFileName)&quot; />
<!--	<Touch Files=&quot;$(OutDir)$(TargetFileName).mdb&quot; />  -->
</Target>

デバッグ用の *.mdb ファイルを探してエラーになっているので、これをコメントアウトします。ファイルはメモ帳などを管理者モードで起動して編集してください(Visual Studio 自体を管理者モードで起動しても ok です)

この状態で、VS 2015 からエミュレータを起動して、VS 2013 を開くと、Target Android Deveice のに Hyper-V のエミュレータが現れます。

image

Debug モードでビルドをすると、デプロイ&デバッグコネクションのエラーになりますが、Release モードにすると正常にデプロイが完了します。ただし、残念なことにデバッグ状態では起動できないので、便利なブレークポイントなどの機能が使えません。まあ、そういう場合は Xamarin Android Player を使うということでよいでしょう。

あと、Hyper-V の Android Emulator は v4.4 が入っているので Xamarin.Android プロジェクトの設定を合わせておきます。

image

それと、Android Options > Advanced を開いてサポートする CPU に x86 を含めてください。Java のサイズとかはいつも通りに設定します(設定しなくても普通は動きます)。

image

単独で VS Emulator Android – Phone を起動する

これで Visual Studio 2013 から Hyper-V の Android Emulator を起動することはできたのですが、最初の起動を 2015 から行わなければいけないというのも変です。なので、単独で Emulator が起動できるようにしましょう。

image

WP8 のエミュレーターを単体起動するためのショートカット – 高橋 忍のブログ – Site Home – MSDN Blogs
http://blogs.msdn.com/b/shintak/archive/2012/11/06/10366015.aspx

実は、Windows Phone のエミュレータを起動する方法と同じです。VS Emulator Android は、

C:\Program Files (x86)\Microsoft Visual Studio Emulator for Android\1.0\XDE.exe

にあるので、実行ファイルを差し換えればよいでしょう。ヘルプ自体は xed.exe /? にすると表示ができます。

[Window Title]
Visual Studio Emulator for Android

[Content]
Emulator version 1.0.41108.1

Usage:
xde [/name vmname] [/vhd vhdpath] [/memsize sizeMB] [/com[1|2] pipeName] [/createDiffDisk diffVhd] [/language lcid] [/video widthXheight] [/diagonalSize screenSize] [/showName] [/noStart] [/snapshot] [/displayName text] [/fastShutdown] [/noALS] [/noFFC] [/noGyro] [/noMag] [/noNFC] [/softButtons] [/camera capability] [/?]

/name vmname: The name of the virtual machine. If you do not provide a name, the default ‘Default Emulator’ is used.

/vhd vhdpath: The path to the VHD for the virtual machine (required if the virtual machine does not exist).

/memsize sizeMB: The amount of RAM in MB that the virtual machine should use. Default: 512

/com[1|2] pipeName: The named pipe that the host uses to communicate with serial ports on the virtual machine.

/createDiffDisk diffVhd: Creates a differencing disk, using the path specified by /vhd as the base. The virtual machine uses diffVhd for its VHD.

/language lcid: The hex language ID to use for the emulator. This ID applies only to the host-side emulator application and not to the guest. Example: /language 040c

/bootlanguage lcid: The hex language ID to use for the emulator. This ID applies only to the guest-side OS and not to the host-side emulator application. Example: /bootlanguage 040c

/video widthXHeight: The initial screen resolution of the emulator application. Example: /video 640×800. Default: 480×800

/diagonalSize screenSize: Specifies the diagonal screen size for the emulator (in inches).

/showName: Displays the name of the virtual machine on the emulator chrome.

/noStart: Exits the program without showing the emulator (after creating or modifying the virtual machine).

/snapshot: Tries to boot to the default snapshot, or create a new snapshot if no snapshots are found.

/displayName text: The text to use for the application window and task bar icon.

/fastShutdown: Turns off the virtual machine without waiting for the OS to gracefully shutdown.

/noALS: Disables the Ambient light sensor.

/noFFC: Disables the Front facing camera.

/noGyro: Disables the Gyroscope.

/noMag: Disables the Magnetometer.

/noNFC: Disables the NFC sensor.

/softButtons: Enables the software buttons. (Not valid for all resolutions.)

/camera capability: Switches the camera to the specified capability mode. Valid capabilities: WP8

/?: Displays this help dialog.

私の環境では、/vhd と /video だけ指定すると動くので、/createDiffDisk しなくても良いかもしれません。

“C:\Program Files (x86)\Microsoft Visual Studio Emulator for Android\1.0\
XDE.exe” /vhd “D:vmVS Emulator Android – PhoneVirtual Hard Disksvsemulator.
phone.android.vhd” /video 480×800

な感じのバッチファイルを動かして起動させます。

image

/video の指定値は C:\Program Files (x86)\Microsoft Visual Studio Emulator for Android\1.0\skins にあるスキンのサイズに合わせれば大丈夫なはずです。それ以外は対応してないと思います。いくつか適当な値を入れてもエラーになってしまうので。

後は、Visual Studio 2013 からデプロイ先を指定すれば ok です。

カテゴリー: Xamarin | Visual Studio 2013 + Hyper-V で Xamarin.Android を動かそう はコメントを受け付けていません

Visual Studio 2015 preview を使って Hyper-V で Xamarin.Android を動かそう

現時点(2014/11/14)で Visual Studio 2015 はプレビュー版だし、Xamarin.Android はアルファ版を入れないとうまく行きそうにないので、うまくいかなくても仕方がないのですが…色々地雷があるので、回避方法(回復方法)をいくつか記録しておきます。

Visual Studio 2015 Preview の発表と共に Android のエミュレーターが Hyper-V 上で動くことが Connect(); で発表された(実演されている)のですが、結構限られた環境でないと動かなさそうな感じです。結論から言えば、私の環境では動いておりません…でしたが、Xamarin.Forms ならば動くことができました。

Visual Studio 2015 Preview をダウンロードする

Visual Studio 2015 Downloads
http://www.visualstudio.com/downloads/visual-studio-2015-downloads-vs

上記からダウンロードができます。まだプレビュー版なので、Hyper-V なり VMWare なりの仮想環境で試したほうがいいのですが、Android エミュレータ自体が Hyper-V で動作しているために、Hyper-V の中で Hyper-V を動かすことはできない/できなかった、ので実機 PC にインストールします。手元の環境では Visual Studio 2013 が入っている上に上書きをしたのですが、これはこれで嵌ります。ちなみに Visual Studio 14 TP が入っていると 2015 をインストールできないので、14 のほうはアンインストールします。

Xamarin.Android を入れる

Hyper-V で動く Android は Visual Studio からしか起動できません。Xamarin Studio からは従来通りの Andorid エミュレータか、Xamarin Android Player を使います。動かしてみるとわかるのですが、Hyper-V 版も Xamarin Android Player 版も速度はあまり変わりません。ただし、Windows Phone のエミュレート環境が Hyper-V であることと、Xamarin Android Player はリモートデスクトップ先では使えない(OpenGLが対応していない)ことが、Hyper-V 版を使ったほうが良い理由になります。

下記は、すでに Xamarin.Android をインストール済みなので、いくつかのテンプレートが表示されていますが、最初はひとつのテンプレートしかありません。

image

そのテンプレートを開くと Xamarin のページに誘導されます。田淵さんのブログにもありますが、Visual Studio で Xamarin.Android 開発を行うときは Bussiness ライセンス以上が必要になります。なので、プレビュー版であっても相当のお金を払っていないと試せないので、結構制限がきついかと。

こんなページが Visual Studio に出てくるので、Download Xamarin をクリックして指定ページに飛びます。

image

左の「Tell us a bit about yourself」に、名前やメールアドレス等を入れて XamarinInstaller-VS2015 をダウンロードします。ちなみに、ライセンスを持っている場合でも(Sign Inしている場合でも)、ここのリンクからダウンロードしなければいけません。

image

Xamarin.Android Update のアルファ版から入れられそうな気もするのですが、うまくいきませんでした。

ビルド時に MergeApkRecipelists なエラーが出る

これで 2013 と同じようにビルドができて Android アプリが作れるかと思い気や、いきなりビルドができなくてこけます。ブランクアプリを作ってもエラーが出るので、はっきり言って設定ミスです。

image

回避策としては、 下記にあるように、C++ のプロジェクトを作って参照設定させるとビルドが通るのですが、実はその後のデプロイに失敗するので意味がありません。

c# 6.0 – Getting Build Error Creating Android Application using Xamarin Extension for Visual Studio 2015 Preview – Stack Overflow
http://stackoverflow.com/questions/26902711/getting-build-error-creating-android-application-using-xamarin-extension-for-vis

どうやら、C++ ネイティブライブラリを必ず読み込むような設定にしてしまっているようです。これは早急に修正されるでしょう。ビルドしたものをデプロイしようとすると JNI のロードでエラーになります。そもそも、C# ライブラリだけを入れたいので、C++ は余計なだけだし、何故か思い余って Visual Studio 2013 に入っている Xamarin.Android にも影響を与えてしまうという悲惨な状態です。

image

解決策としては、Stable に設定し直してください、ってのが正解です。2013 のほうの Hyper-V でのエミュレータは使えなくなりますが、2015 preview のほうかは使えます(使えるといっても、エミュレータを起動できる、という状態なのですが)。

Stable に戻しても、2015 では Android アプリがビルドできない

実は Stable に戻した状態でも、2015 preview では Android アプリがビルドできません。

image

やっぱり、App5.dll.mdb とあるように、C++ のデバッグ情報を書き込もうとして失敗しています。なんだかなーという感じですが、native android はビルドできませんでした。

じゃあ、2015 preview では絶望的なのかといえば、そうではありません。Xamarin.Forms を使うアプリだとビルドができるんですよ。内部的にどうなっているのかわかりませんが(おそらく *.targets を直せばいいんですが)、Xamarin.Forms 用のプロジェクトを作るとビルドが通ります。

VS Emulator Android Phone にデプロイができない

ビルドが正常にできて、いざ Hyper-V 上で動かそうと思うと、一見うまく行きそうに見えますが…ダメです。

image

Hyper-V にインストールされた Android が起動はされるのですが、次のように Connect エラーになります。おそらく adb が Hyper-V 上の Android に接続しようとして失敗していると思うのですが、解決法がわかりません。以前、Android エミュレーターを動かしたときに、何度か遭遇しているネットワークエラーっぽいものなのですがね。

image

ちなみに、従来の Android エミュレータや Xamarin Android Player だと正常に動きます。なので、Hyper-V を使わない、かつ Xamarin.Forms に限定する、のであれば 2015 preview の状態で使えるのですが…いや、素直に 2013 に戻って開発したほうがよさそうです。

Visual Studio 2013 と共存していると拡張機能が 2015 preview に入らない

ここまで、さっくりと 2015 preview に Xamarin.Android がインストールできたように書いていますが、実は、2013 が入っている PC に 2015 Preview を入れると、拡張機能が 2015 のほうに入りません。

こんな感じに Xamarin Account のメニューが出るハズなのですが、最初はでなくて苦労しました。

image

以前、2010, 2012, 2013 が同居している環境でも同じことが起こっていましたが、

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Xamarin\

のフォルダにある拡張機能を Microsoft Visual Studio 14.0 にコピーします。3.9.41.0 のフォルダが、Hyper-V 込みなのですが、すべてコピーしてしまって大丈夫です。

コピーした後は念のために
C:\Program Files (x86)\NuGet\Visual Studio 2015\NuGet.Tools.vsix

を実行しておいてください。拡張機能の状態が更新されて、Xamarin Account の表示が出てきます。

2015 preview + android + Hyper-V は地雷が多い

そんな訳で現時点では、この組み合わせは地雷満載です。地雷を踏み抜く勇者だけが通れる道…つーか、デモでは通った訳なので、素な環境で素なプロジェクトを作れば意外とスムースに進むかなと。

Hyper-V で Xamarin.Forms を動かす手順

先に書いた通り native な Xamarin.Android はビルドエラーになってしまうのですが、Xamarin.Forms の場合は Hyper-V で動作が確認できています。通常の場合は、既に Visual Studio 2013 が入っている状態で、追加で Visual Studio 2015 を入れるでしょうから、ちょっと手順がややこしくなっています。
実機 PC は Hyper-V を動かす都合上、x64 版を使ってください。

  1. 実機 PC に Visual Studio 2015 preview をインストールする。
  2. 実機 PC の Hyper-V を有効にする(Visual Stuido をインストールした時点で Hyper-V が有効になっているはず)
  3. 最初の Xamarin Android プロジェクトを作って、リンク先から XamarinInstaller-VS2015  をダウンロード&インストールする。
  4. Visual Studio 2013 が入っている場合は、
    C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Xamarin\  を
    C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common\IDE\Extensions\ にコピーする。インストーラが Visual Studio 2013 のほうにしか拡張機能をコピーしないためです(これはいずれ直るでしょう)
  5. Bussiness アカウントでログインをして、Xamarin Update で Statble に戻す。
    2015 だけ使っている場合は不要ですが、2013 のほうの Xamarin.Android が動かなくなるのを回避します。
  6. 2015 あるいは 2013 で Xamarin.Forms のプロジェクト( Mobile Apps )を作成する。
  7. Debug 実行をして、一旦、Hyper-V に VS Emulator Android – Phone を作成する。
  8. Debug 実行のままだと、Connect エラーが出るので、一度だけ Release モードで実行する。そうすると、デバッグ用のコネクション( GetProcessId が取れるようになる)が確立されて、以後は Debug モードでも実行できるようになる。

image

この状態で無事、Xamarin.Forms のアプリが立ち上がります。

【速報】 Visual Studio 2015 Preview で Xamarin.Forms 開発が快適に! – Xamarin 日本語情報
http://ytabuchi.hatenablog.com/entry/2014/11/14/214918

田淵さんに先を越されましたが(苦笑)、二番槍ということで。

おまけ

Visual C++ で Android アプリが作れるようになりましたが、内実は Android Open Source Project です。Google の Android とは違うスタイルのオープンソースな Android ってことです。

image

Visual Studio のテンプレートを開くと OpenGL に特化しているらしく、おそらくゲームか画像関係のアプリを作るときに使うもののようですね。なので、C++/CX などのように C# と同じように Android アプリを作れるわけではありません。また、Xamarin.Forms を使うこともできないでしょう。Microsoft が C++ で Android 環境を提供するなんて…と思った方もおられるでしょうが、そういう訳で、もともと Android Open Source としてあるものを組み入れているし、得意分野も異なるので Xamarin 自体とは競合しません。むしろ、Delphi/C++ のほうとぶつけてきたという感じです。Delphi/C++ のほうでは、C++ で Android/iOS アプリが作れることを売りとしているので、そこが魅力的なところなのですが、Visual C++ でも作れるとなると開発環境を移す必要はなく、Visual Studio で統一できる、という結論に至ります。

これもデプロイ時にエラーがでるので、Hyper-V との接続がクリアできればいけそうです(つまりは、私の手元では動いていないのです…)

image

どうやら、一度 VS Emulator Android – Phone との接続を確立してしまうと、他の Debug モードも動くようです。上記の Android + C++ アプリも無事動きました。背景の緑の色が変化するサンプルのようです。

image

カテゴリー: Xamarin | 1件のコメント

Roslyn の活用しどころ

グロサミの最終日に Roslyn のハッカソンがあったので、午前中にちょっとだけ参加してきました。午前中だけなので、何をやるという訳でもなく、ざっくりと Roslyn Syntax Visualizer の解説を受けて、その後なにがしかの演習っぽいものをやるわけですが、いやいや、その前で抜けているので、ピザ食べて午後あたりになったときにどうなっているのかは分かりません。MS Store 行ってキーボードを買ってきて、お昼を食べて帰ってきて覗いてみたら、なんかまったりと Roslyn をインストールする感じだったので、駄弁るって感じだったんですかね?ハッカソンというものに出たことがないので、雰囲気だけ。

そんな中で、今岡さん(@imaoca)に力説した「Roslynは組み込みにも役に立つかもしれへんでー」という根拠をちらちらと書き散らしていきます。多少、希望的観測も入っているので実現が難しいところがあるかもしれませんが。

そもそも Roslyn ってどうやって使うの?

.NET コンパイラ プラットフォーム (“Roslyn”)
http://msdn.microsoft.com/ja-jp/vstudio/roslyn.aspx
Visual Studio “14”の新機能“Roslyn”とは – Build Insider
http://www.buildinsider.net/enterprise/roslyn/01
.NET Compiler Platform (“Roslyn”) – Home
https://roslyn.codeplex.com/

Roslyn が何か?ってのは、いくつかのブログで読めるので飛ばしてしまって、まずはインストールして使える状態にします。最後の https://roslyn.codeplex.com/ なところから、 Build tools that understand C# and Visual Basic な手順を順々に入れていけば OK です。

  1. Set up a box with Visual Studio “14” CTP 4. Either…
  2. Install the Visual Studio “14” SDK. You’ll need to do this even if you’re using the Azure VM image.
  3. Install the SDK Templates VSIX package to get the Visual Studio project templates.
  4. Install the Syntax Visualizer VSIX package to get a Syntax Visualizer tool window to help explore the syntax trees you’ll be analyzing.

Azure 上には Visual Studio 14 導入済みのものがあるので、それに 3,4 の VSIX をインストールします。そうすると、ファイルオープンなところに「Roslyn」カテゴリが増えるのと、

image

View → Other Windows → Roslyn Syntax Visualiser なメニューを選択すると、

image

CodeDOM が見れるようになります。

image

これをもとに、既存の言語に機能追加をしたり、解釈を変えたりするわけです。C# 自体の新機能も含まれているのですが、C#、VB のような特定言語よりも「コンパイラ」自体に興味がある人は、この機能が公開されて利用できる、ってところに注目します。つーか、私から見た目玉機能はこれですね。

構文木を作る lex/yacc

Roslyn の詳細な API はともかくとして、オープンソースなコンパイラであれば、gcc でもよいし、ruby でも python でも良いわけで F# だってソースが公開されています。gcc のコンパイラそのものを弄ることは少ないけど吐き出される as コードを見て C 言語レベルで最適化をかけたり(部分的にアセンブラを使うとか)するわけで、コンパイラがオープンソースになったところで、あまりインパクトは大きくありません。

IL に落とすという意味でも、そこまで突っ込むことは少ないし、そもそも C# や VB の文法をローカルに変えてまでやるぐらいであれば、別の言語を読み込ませるたり、F# のコンピテーション式のように DSL を埋め込んだりしても良いのです。また、C/C++ で適当なマクロを作れば、大抵のアセンブラ的なコード(行単位の命令コードの羅列)は書けます。別言語になってしまうという難点はありますが、ライブラリとして独立さればよい話で、混乱するような形になるならば、汎用的に作らずとも、R言語のように統計に特化させても良いのです。

そんなプログラム言語単体の話よりも(リファクタリング等の機能もあるのでしょうが)、Visual Studio という IDE の機能を Roslyn により使えるというところに私は注目したいのです。構文木(Syntax Tree)を扱う時に、内部的には CodeDOM のようなスタイルになっているのでしょう。なので、このスタイルに則ってコンパイラを書けば、そのまま Visual Studio の機能が使える…と思います。おそらく、F# は対応されるだろうから、そのあたりで Roslyn の実力を見てっところなんでしょうが。

懸念点と言えば、現在 C#/VB しか対応していないところから、C#/VB に似た言語スタイルでないと Roslyn の API は使えないのか?という点です。たとえば、LISP を Roslyn で通して、Visual Studio で編集できるようになるだろうか?とか、PHP や Perl のようなスクリプト言語の場合はどうなるのだろうかとか。Ruby や Python のほうは、オブジェクト指向言語だし過去に IronRuby な形で編集できるようにもなっているので、導入は比較的楽かもしれませんが。

また、既存の複雑な言語でなくても、ちょっとした DSL を自前で作っておいて、Roslyn に対応させておけば、Visual Studio で編集ができる(補完機能とかサジェッションみないな機能とか)可能せがあります。そうなると、自前でちまちまと専用エディタを作る必要もなくなるし、読み込ませ方によっては結構面倒な JSON や XML 形式で書きつけなくてもよい、ってことになりますよね(まあ、適当なスキーマを作れば JSON のほうが便利ってのもありますが)。

そういう訳で、 Roslyn が扱う CodeDOM(かな?)に直しさえすれば、Syntax Tree から派生する機能が使えるのではないか?と想像できます。

組み込み言語と Roslyn の関係

.NET Micro Framework の場合、C# が使えるから、そのまま Roslyn の機能が使えます。IL に落とす段階や、プラットフォーム毎の .NET のバージョンの違いなどは、Windows 10 で改良されるので(Microsoft.NET とか One.NET とかいうスタイルで)、C# で書いておけば組み込み機器でも動作する、というパターンにはできそうです。

現在、.NET MF は x86 と ARM しか対応していないわけですが、将来的に(過去的にも)マイコン系の CPU に対応させたり、あるいは各種の C言語コンパイラを Roslyn スタイルに直すことで、Visual Studio 上でビルドをすることも可能では?と思っています。あるいは C# でコンパイルしたものを IL に直し、IL 自体を独自の C ライブラリに直すとか、あるいは C# で書いた後に、独自 CPU に対応した IL(内部的には C言語コール)に直してしまうとか。これもローカルな言語を Visual Studio で動かせるようになれば、組み込み言語自体のコーディング速度も変わってくるはずです。まあ、最初のターゲットとしては Arduino 用の C 言語を Visual Studio 上でビルドできる、ってのが理想的ですよね。今でも専用エディタが付いているし、.NET MF を使えば C# で書けるのですが、うまくエディタと IDE が独立に動作して、かつ、コード分析レベルでは同期することができれば、そういうことも可能でしょう。かつて CodeWarrior が、多言語の開発環境を担っていましたが、あれと同じスタイルになると良いです。まあ、それでも Visual Studio で、ひとつのソリューションに複数の言語を入れて開発することができるので、かなり実現されているわけですが。

そんな訳で、ちらちらと Roslyn の中身を眺めなければ。

カテゴリー: 開発 | Roslyn の活用しどころ はコメントを受け付けていません

AllJoyn とは何だろうか?

いままで知らなかったのですが、AllJoyn という通信フレームワークがあります。IoT の中で中核を成す…というか、どうやってモノ同士で通信させるんだろうか?ってのは、C/S でも問題だし、P2P でも問題になるわけですが。

MS、IoTを推進するAllSeen Allianceに加入–クアルコムが主導 – CNET Japan
http://japan.cnet.com/news/business/35050321/
Open Source IoT to advance the Internet of Everything – AllSeen Alliance
https://allseenalliance.org/

実は AllJoyn というオープンソースな規格があって、Qualcomm が推進していることを先日のグロサミで知りました。PC から Raspberry Pi への通信とか、Raspberry Pi から BrickPi を通じて Logo のモータを動かしている訳ですが、自前の BrickPiNet では、REST で通信するようにしています。Raspberry pi の場合は、Linux が動いているので REST を Apache 上に作るか、HttpListener で作ってしまいます。動的にアセンブリをロードするわけではないので、HttpListener のほうでも楽に作れます。モーターを動かすとかセンサーを起動させるとか、そういう REST を送る訳ですが、このぐらいのものであれば、何か規格があっても不思議ではないよな…とは思っていたのですが。

それが、AllJoyn という規格です。規格自体は 2008年頃?で、SDK 自体は 2011年ぐらいです。現在は ver.14 で https://allseenalliance.org/source-code にアクセスすると各種環境の SDK がダウンロードできます。Qualcommが発起人で、現在は Linux 財団がオープンソースとして管理、ってな感じなんですかね。

何ができるのか?

各種 OS 間でデータ通信を行います。データ通信自体ならば TCP/IP をそのまま使ったり(特には IP だけ使ったり)、最近の機器では組み込み系の Linux が入っているから Apache を入れて応答を返すってのが普通に行われますが、Android や Phone やら、TV やオーディオ、冷蔵庫などまで範囲を広げます。相互に通信をできるようにする訳ですから、なんらかの規格を決めないといけません。

  • データ自体は、XML で送受信
  • データ内容は Get/Set などシンプルなメソッドを使う

途中に AllJoyn のルータなどが挟まるのでネットワーク的には複雑なのですが、EndToEnd 視点ならば非常に単純です。Pull と Push の両方の機能を備えるので、端末機器からの Event 通知を受けることができます。このあたり、SNMP の MIB に近いのかなと思ったりするのですが、どうでしょう? MIB 自体はバイナリと IP を扱わなくて結構大変なのですが、現在の端末機器の CPU とメモリを考えれば XML データを流してエンコード/デコードしてもパワー的に十分ですよね。

https://allseenalliance.org/developer-resources/alljoyn-open-source-project にあるメニューリストを見ると、Unity や Windows 7 が入っています。ゲームの双方向通信にも使われているらしく、Unity + AllJoyn で作っておけば、WiFi/Bluetooth 環境にあるゲーム機器が、機種に関係なく相互通信ができるのでは?と思ったりするのですがどうなんでしょう。

また、先に書いた通り、シンプルな XML をデコードする機能さえあればいいので、.Net Micro Framework のような非力な機器でも使えそうです。データの内容を見ると SOAP のように名前空間を使っていません。

プログラム言語は、Java, Objective-C, C++, C#, C で扱えます。https://allseenalliance.org/alljoyn-framework-tutorial C# で扱えるんだから、F# とか VB でも扱えるでしょう。

具体的にどうやるのかは、これからチュートリアルなどを読んでいくわけですが、クラス名もこんな感じでそう多くありません。

image

BusLitener と SessionListener が肝な感じがします。

ひとまず、自分用のメモまで。

カテゴリー: 開発, AllJoyn | AllJoyn とは何だろうか? はコメントを受け付けていません

MVP Global Summit 2014 感想戦

MVP Global Summit
http://mvp.microsoft.com/summit

MVP 自体は 4年目なのですが、Global Summit に行くのは初めて。さっくりとツアーで行ってツアーで帰ってくるつもりだったのですが、同室の方の都合で最終日まで Red Lion に1日伸ばしでした。セッションの会場はマイクロソフト社内なので、ホテルからバスで送迎だし市内から遠くてもあまり変わらんですよね、安いし(ツインで120$ だったので、延長分はひとり頭 60$ でした)。

初日のベイエリアの観光以外は最終日の午後にベルビュースクエアを回ったぐらいで、碌な観光もせずに勉強会のノリで行ってきました。ぎっちり、3日間ひとりでセッションを回ってきたのでほぼ英語漬けの毎日ですが、なんか、あのスピードの英語ヒアリングはつらいです。スライドとかデモをやっているときはいいんだけど、ディスカッションになって(スライドの途中でも容赦なく質問をして、容赦なくディスカッションになってしまうあたり欧米風なのか、やっぱり言いたい MVP さんがたくさんやってきているのか)しまうとかなり辛い感じ。GAG のところが笑えないのは、今後ヒアリングを第一に勉強しようという原動力にはなるかもって感じです。やっていることは、所詮コンピュータ関係なので、概要は聞き取れるし、込み入って難しい話になればこれは英語でも日本語でも難しい話になってしまうので、同じことです。セッション中に手を上げて、スライドの途中でも止めてしまうスタイルは、.NETラボで発表するときにでも取り入れていきたいですね。スライドを淡々と読み上げると眠くなってしまうので、デモを交えてという工夫をやるのですが、質疑応答…というか議論自体が間に挟んでしまえばスライド自体ほとんど要らないという利点もあります。あと、顔を合わせている「勉強会」なりのメリットもあるでしょう。

F# のランチセッションで、替え歌に合わせて OWIN を解説するってことをやっていました。以前、プロ生で西山さんがギターの弾き語りセッションをやっていましたが、ああいうノリもありかなと思ってます。日本の勉強会だと世代差が気になる感じだけど、グロサミに出て手を上げているガリガリ質問しているのは50歳以上っぽい人(私よりちょっと上ぐらい)だし、そういうかき回し方もよいでしょう。

私が主に行ったのは、IoT のセッションです。Visual C# ってところで、ASP.NET vNext と Roslyn 、Xamarin はちらっと回ってきて、後は IoT に入り浸っていました。セキュリティ F# セッションってことで、てくてくと雨の中を歩いて聞いてきましたが(10人ぐらいいて、部外者が2人な感じだったよw)、ほとんどは Embedded のところです。Microsoft Band のページを調べていて、話しかけてきたおじさんに(自分もおじさんですが)、Raspberry Pi やってて、これから Spilder で勉強するつもりなんや、って話すと、Splider でバーベキューの温度を測る機械を作っている(らしい)ページを見せてみせてもらいました。あと、なんか前のほうで、Not NDA のページをセッション資料を作っている人がいるなーと思ったら、最後の LT(10分ぐらいのミニトークで、MVP が発表する)で、組み込み機器は「Wife のように扱えるといい」(英語を忘れました)という、ヒーターとかオートロックとかをまとめて Windows Phone のアプリにしたりしている人でした。「Wife のように~」のところで、皆が爆笑しているのであれは流行り(独身が多い?)なのかも。組み込みの場合は、年齢層が高.くて、Windows CE、Windows Mobile から、Windows XP Embedded な人が多いですね。完全に組み込みな、.NET Micro Framework のときは質疑応答が少なかったので、少しジャンルが分けられているようです。

codenameathens

Microsoft’s fitness band: What kinds of software and services are inside? | ZDNet
http://www.zdnet.com/microsofts-fitness-band-what-kinds-of-software-and-services-are-inside-7000035344/

Windows 10 に統合して、4つの分野に Framework を分ける、っていう話は、Tech Ed Europe で発表されているもので、NDA ではありません、よね。Windows Phone や 従来の Surface RT のような Windows RT は Windows 10 “Mobile” になって、従来の .NET Compact Framework は、Windows 10 “Athens” になるってことです。更にコンパクトになっている組み込みに使う .NET Micro framework は通りに使われる感じです。Microsoft Band の UI は、Windows 8.1 のスタート画面風なので、Embedded 8.1 か Windows Phone ベースなのかなと思っていたのですが、スライドを見るとそれっぽい時計の絵が描かれているので、ひょっとすると .NET Micro かもしれません。.NET Micro は情報だけはちららと追っていたのですが、今年の夏にやっとこさ Splider を買ったぐらいで、netduino の存在は知らなかったんですよね。

2010年頃にすでに発表があって、日本で買えたりしてました。「してました」って過去系になっているのは、スイッチサイエンス社が在庫切れになったままで、新しい netduino plus 2 を扱っていません。コネクタ等が arduino 互換なので、外部機器を共用するならば netdouino のほうがいいかなと思っています。まあ、コードの接続がややこしいですが、ハルロックを読んで頑張りましょう(ちなみに、ハルロックには基板解説とかは出てこないので、やる気だけを貰うということで)。

日本の IoT と海外の IoT の違い

Microsoft 技術からの視点なので、本格的に Raspberry Pi とか Aruduino から見たら(半田付けする、という点で)違うかもしれませんが、グロサミに行った感じでは、日本と海外(欧米)とでは結構違いがあります。

私は Kinect や Leap Motion を扱わないので(あと Oculus Rift DK2も)そのあたりはよくわからなくて、日本の組み込み系は MS太田さんオンリーなのかなと思っていたりするわけですが、Raspberry Pi や Aruduino で何かモノを動かそうと思うと、もうちょっと周辺の器械を活用しないと駄目ですよね。さきほどの MVP ライトニングトークスで出てきた、デカいモーターや、ごついドライヤー(温度センサーを温めるらしい)、デカいタッチディスプレイを担いでくるあたりが、海外の IoT さんの面白いところです。

確かに、Windows Phone を買ったり、Surface Pro を買ったりするのもいいんですけど、同じ値段ならば、Rspberry Pi を買ったり、Aruduino 用のセンサーを買ったりするほうが、「よりたくさんの機器が買えるんですよッ!!!」。まあ、センサーにも色々あって結構な値段はするし、Lego Mindstorms EV3 は Windows Phone と同じぐらいの値段になるので、どっちを買っても一緒ではあるのですが(苦笑)。

そんな訳で、日本の IoT は、Internet のほう(Windows Phone とか Surface とか)から入っている感じがしますが、欧米の IoT は、Thing のほうから入って来てます。周辺機器の豊富さもあるのかもしれませんが、もともとある DYI の精神なのかな、と思ってます。家のガレージに工具を置くことあができたり、広い公園でラジコンやロケットを飛ばしたりするのが普通の環境じゃないと、あの発想はできないのでは?ってな感じです。

じゃあ日本はどうやって IoT というジャンルを確立していくのか?というと、同じ方面じゃなくてもよくて、ロボットでも踊りでもARでもVRでもよいのですが、もうちょっと海外と対抗するような視点を持ってモノを作ってもよいかなと思いました。Oculus も初音ミクもMMDもすごいといえばすごし、そこそこ手軽に実現ができるようになってるし、日本でやっている人が多いから日本語で情報が得られるので、初手としていいのはいいのでしょうが、そのまま海外(欧米)に持っていくと違和感アリな感じです。それを日本独自の文化と捉えるか、違和感のまま捉えるか、ってのがあると思います。勿論、日本のアニメ文化の延長上でという感覚もあるんですが。

そんなこんなで、自分としては今まで通りニッチなところかつ、海外で受け入れやすいスタイルで、Raspberry Pi を扱っていきます。いつかの IoT のセッションを見ていくと、海外(欧米)が特に進んでいるという訳でもないし(同時に日本が取り残されている訳でもないし)、いくつかの面では高速道路も準備されて、マス的な Microsoft Band のような当たりを日本で作るのは難しいでしょうが、もっとバリエーション(機器の組み合わせてという意味で)を作って、それを実現するときに、.NET Framework + Xamarin + Raspberry Pi/Netduino  + AllJoyn のようなスタイル確立できるかな、と思って帰ってきました。ひとまず、.NET Micro framework が動く netduino を試してみるのが初手、つーか、その前に FEZ Spider Starter Kit ぐらいは開封せねば。

英語のヒアリング

ディスカッションをするには、英会話が必須なんですが、TOICE 300点前後(程度だよ。たぶん。10年前ぐらいだけど)の自分としてはヒアリングをやらないといかんと痛感です。たまに channel 9 とか TechEd の画像を流しっぱなしにして仕事をしていますが、スライドとは関係ないところで話をしていると途端に分からなくなります(キーワードを拾い集めて、おおまかな意味から推測するってことをやっているので)。コンピュータの本は洋書が多いし、MSDN で英語文にあたることが多いから、英文をざっと読み込むことはできるし、英文を書くときは Google 翻訳を使ってほぼコピペで流すことはできるのですが、カンファレンスのヒアリングは難しいですね。自分の後ろの席で、自動翻訳っぽい音が聞こえた(英語じゃない言語で、ちょっと遅れで話している感じ)ので、そんなのを使うのもアリなんでしょうが、やっぱり、英語は英語のまま理解するほうが脳への負担は少ないと思われます(疲れにくい、退屈して眠りにくいっていう意味で)。

レッドドワーフ号のイギリス英語のほうが少しわかりやすいけど、アメリカ英語と聞き取りづらいのはなまりの問題もあるかなーと思うけど、まあ、すべてとは言わなくても半分ぐらいは英語のまま理解したいですよね。お金を払って英語のセッションに行って、英語が聞き取れなかったら意味がないわけで(グロサミ自体は MS が会場費を持ってくれているけど、日本からの旅費は自前だし)、これは早急にやり始めないとという感じでした。

因みに、日常的な英会話も不便な私ですが、相手に話すときは「文法通りに話す」と意味が伝わりやすいです。文法通りってのは前置詞あれこれってのもあるのでしょうが、SVO を守って、3単語ずつしゃべればだいたい通じます。どう聞こえているか分からんけど、相手にとっては外人だから許してくれるでしょう。…つーか、経験上、意図を正確に伝えたいときは文法通りに、雰囲気を伝えたいときはジェスチャーでって感じ。ビジネスのときは困るだろうけど、街中歩くときと、同じプログラマの人と話すときはこれで十分かと。

カテゴリー: 開発 | MVP Global Summit 2014 感想戦 はコメントを受け付けていません

XAML とは何か? … Microsoft だけのものじゃない

XAML を勉強しておけば将来役に立つよ…と Microsoft 様よりお達しがあって久しいのですが、そもそも、XAML ってのは何?ってのが昨日気になって調べていました。データの形式だけで見れば、XML 形式なのですが、あえて「XAML」とするところに意味はあるのか?かつ、Xamarin.Forms で使われている XAML は XAML と言えるのか?って話です。

Japan Xamarin User Group (JXUG)
https://www.facebook.com/groups/xm.jxug/
Using Workflow Markup
http://msdn.microsoft.com/en-us/library/vstudio/ms735921(v=vs.90).aspx

榎本さんの話で、Xamarin.Forms 以外にも WF(Workflow)でも使われているそうです。中身を見ると、XML でも良いような気がするけど、なぜに XAML なのか?

XAML は仕様が公開されている

結論から言えば、XAML の仕様は公開されています。Microsoft 自身が MS-XAML として公開していて、それに基づいて WPF やストアアプリの XAML を作っています。当然、WF の XAML も作っていて、同じように Xamarin.Forms の XAML もこれに基づいている(ハズ)です。

XAML 構文の詳細
http://msdn.microsoft.com/ja-jp/library/ms788723(v=vs.110).aspx

の中にある MS-XAML をクリックすると、公開しようの PDF に至ります。Silverlight などの XAML は以下でも公開されています。

Microsoft Domain-Specific Languages
http://msdn.microsoft.com/en-us/library/dd361847.aspx

ついでに言うと、Excel のファイルを保存したときにできる .xlsx の形式とか、VBA の仕様とかも公開されています。Microsoft は、この公開情報に基づいてデータを作っている(あるいは拡張している)ので、まあ、Office データの互換フォーマット率なんかは、このあたりを元にすれば適切かなーと思ったり。

XML と XAML の違い

SPEC をざっと読むと、いくつかの違いがあります。XAML ⊂ XML な訳だから、XML の形式に基づいてはいますが、いつかの拡張があるってことです。

  • namespace で http://schemas.microsoft.com/winfx/2006/xaml が必須
  • x:Class で実クラスにマッピングする
  • tagName.propName のように、ドットでつながった名前が特別扱い
  • attrName=”{Binding xxxx}” のような、属性値に {…} を指定したときに特別扱い

他にもいくつか細かい違いがあるのですが(「Name と x:Name を同時に定義してちゃいけない」という仕様がある!)、まあこんな感じです。

WPF やストアアプリ、Windows Phone で規定されているコントロールとかは XAML 本体とは別ものなので、Xamarin.Forms の XAML の共通部分も、ここの MS-XAML にあっている(はず)です。

名前空間 http://schemas.microsoft.com/winfx/2006/xaml を利用

XAML では x:Name のように、x 付きの属性が頻発するのですが、これが XAML の肝っぽいですね。名前空間のエイリアスが「x:」でつけられているのですが、「xxx:」のように変更することも可能です。

乱暴なことを言えば、このスキームを設定するだけで、XAML です、と言い張ることもできる…かもしれません。あまり意味はありませんが。

x:Class で実クラスにマッピングする

XAML は、XAML ファイル単体で存在するとは少なくて、特定のクラスとマッピングされます。XAML 内にある x:Name を x:Class で指定したクラスのフィールド(プロパティでも良い?)やイベントにバインドしています。なので、特にバインドしない場合は、x:Class を書かなくても良いと思うのですが。このバインド自体が、*.g.cs のようなバックグラウンドのコードを吐くので、ビルド環境依存になるような気がするんですけどね。このために Visual Studio で普通の C#/VB の XAML を書いたときにはバインド用の中間ファイルが作られます。F# の場合は、この中間ファイルを作らない(作れない?)ので、x:Class を指定せずにタイププロバイダを使うという方法を取っています。

ちなみ、自前の XamarinForms のプレビューアは x:Class を指定しているけど、動的にクラスをバインドするという手法を取っていて、動的なコードを作りません。なので、XAML 解析コードを自前で作れば、ちょっと違ったマッピングの仕方もできるということです。

ドットでつながった名前を特別扱いする

XAML を調べていた理由として、このドット付きの名前があります。<TextBlock Text=”…” Grid.Row=”0″ のように、親の Grid に設定をしたり、<TextBlock.Background>Black</TextBlock.Background> のようにプロパティを設定したりできます。ドット記号自体は名前に使ってよいことは調べたのですが、このドットの前後を SPEC で規定しているのか否か?ってところです。

MS-XAML を見ると、6.5.1. DottedXamlName として、ドット付き名前が規定されています。これに基づいて、ドット前後の XamlName に分けて XAML 解析を行うという訳です。

属性値に {…} を使う

XAML の拡張として、属性値に {…} が使われているのですが、これはどういうフォーマットなのか?自由フォーマットなのか?と思っていましたが、これも MS-XAML で規定されています。

6.6.7.1. Markup Extension Parsing なところで、MarkupExtension としてフォーマットが決まっています。なので、Text=”{Binding text}” のような感じなのも勝手なフォーマットを使っている、という訳ではないのです。

XAML 形式を解析する

Xaml ファイルをロードしてマッピングする場合は、XamlReader を使います。ストアアプリのような WinRT の場合は、いかな感じで読み込みます。

[WinRT] XElement を使い XAML を構築して動的に XamlReader.Load で読み込む技 | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/6556

WinRT の場合、Windows.UI.Xaml.Markup 名前空間にあるのですが、WPF のような本来(?)の XAML は、System.Xaml の下にあります。何故、System.Xaml から動いてしまったのか、Xamarin.Forms に System.Xaml が無いのはなぜなのか、は分かりませんが、処々の事情がありそうです。

  • XamlXmlReader
  • XamlObjectReader
  • XamlServices

XAML 解析とマッピング自体は上記の 3つのクラスを使えばよさそうです。Read メソッドで SAX 風にタグを読み込んでマッピング部分を自前で書いていけばよいのです。Xamarin.Forms プレビュアは、XML として読み込んだ後に、独自に解析をしているので、このあたりを変えたいな…とは思ってはみたものの、Xamarin.Form には、というか mono には System.Xaml がないんですよね…ともったらあるよ( http://www.mono-project.com/archived/systemxamlhacking/ )。ストアアプリ WinRT のほうにも System.Xaml がないので、互換ライブラリを作って PCL 化するのがいいんですかね。

ここまで書いて、一切 UI な部分が出てきませんが、そうなんです。XAML は UI とは全く関係ないんですね。ってことは、普通にクラスにマッピングする XML 形式のデータであればよいのです。なるほど。

連載:Windowsストア・アプリ開発入門:第5回 データを画面に表示する (1/5) – @IT
http://www.atmarkit.co.jp/ait/articles/1311/01/news095.html

のように、デザイン時のデータ形式は、JSON と XAML が選べます。そうなんです。XML じゃなくて XAML なんですよ。これは、まあ、そういう意味があるということです(逆に言えば、クラス構造を外して、JSON のように XML 形式でも十分ではないか?とも言えますが)。

カテゴリー: XAML | XAML とは何か? … Microsoft だけのものじゃない はコメントを受け付けていません