Visual Basic で iOS アプリを書くプロジェクトを作成…している途中 | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/5604
昨日の続きで、Xamarin.iOSを使ってVBでコードを書いてiOSアプリを書く、というニッチな話を。
結論から言うと、一応できました。結構、回避策を使っているので、もうちょっとアプローチを考えないといけないのですがブレイクスルーはできた感じ。
■Xamarin.MonoTouch.VisualBasic.targets を作成する
以下の3つのファイルを作成します。
C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.MonoTouch.VisualBasic.targets
1 2 3 4 5 6 7 8 | < Project DefaultTargets = "Build" xmlns = "http://schemas.microsoft.com/developer/msbuild/2003" > < PropertyGroup > < TargetFrameworkIdentifier >MonoTouch</ TargetFrameworkIdentifier > < TargetFrameworkVersion Condition = "'$(TargetFrameworkVersion)' == ''" >v1.0</ TargetFrameworkVersion > </ PropertyGroup > < Import Project = "$(MSBuildBinPath)\Microsoft.VisualBasic.Targets" /> < Import Project = "Xamarin.MonoTouch.Common.targets" /> </ Project > |
C:\Program Files (x86)\MSBuild\Xamarin\Xamarin.ObjcBinding.VisualBasic.targets
1 2 3 | < Project DefaultTargets = "Build" xmlns = "http://schemas.microsoft.com/developer/msbuild/2003" > < Import Project = "$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.ObjcBinding.VisualBasic.targets" /> </ Project > |
C:\Program Files (x86)\MSBuild\Xamarin\iOS\Xamarin.ObjcBinding.VisualBasic.targets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | < Project DefaultTargets = "Build" xmlns = "http://schemas.microsoft.com/developer/msbuild/2003" > < UsingTask TaskName = "Xamarin.ObjcBinding.Tasks.BTouch" AssemblyFile = "Xamarin.ObjcBinding.Tasks.dll" /> < PropertyGroup > < TargetFrameworkIdentifier >MonoTouch</ TargetFrameworkIdentifier > < TargetFrameworkVersion Condition = "'$(OS)' == 'Unix'" >v1.0</ TargetFrameworkVersion > < TargetFrameworkVersion Condition = "'$(OS)' != 'Unix'" >v4.0</ TargetFrameworkVersion > </ PropertyGroup > < Import Project = "$(MSBuildBinPath)\Microsoft.VisualBasic.Targets" /> < Import Project = "Xamarin.ObjcBinding.Common.targets" /> < PropertyGroup > <!-- work around a bug in the Mono Microsoft.CSharp.Targets that defaults the compiler to gmcs --> < CscToolExe Condition = "'$(OS)' == 'Unix'" >vbnc</ CscToolExe > <!-- Btouch needs CscPath, but when building from within Visual Studio, it and the CscTool{Exe,Path} properties will be empty since VS uses the in-process compiler, so fix them. --> < CscPath Condition = "'$(CscPath)' == '' And '$(OS)' != 'Unix'" >$(CscToolPath)$(CscToolExe)</ CscPath > < CscPath Condition = "'$(CscPath)' == '' And '$(OS)' != 'Unix'" >$(MSBuildToolsPath)\vbc.exe</ CscPath > < BaseLibDllPath Condition = "'$(OS)' == 'Unix'" >/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll</ BaseLibDllPath > < BaseLibDllPath Condition = "'$(OS)' != 'Unix'" >$(MSBuildExtensionsPath)\Xamarin\iOS\monotouch.dll</ BaseLibDllPath > < BTouchToolExe Condition = "'$(BTouchToolExe)' == '' And '$(OS)' == 'Unix'" >/Developer/MonoTouch/usr/bin/btouch</ BTouchToolExe > < BTouchToolExe Condition = "'$(BTouchToolExe)' == '' And '$(OS)' != 'Unix'" >$(MSBuildExtensionsPath)\Xamarin\iOS\btouch.exe</ BTouchToolExe > < GeneratedSourcesFileList Condition = "'$(GeneratedSourcesFileListing)' == ''" >$(GeneratedSourcesDirectory)\sources.list</ GeneratedSourcesFileList > </ PropertyGroup > <!-- Add our own pre-build steps --> < PropertyGroup > < CompileDependsOn > GenerateBindings; $(CompileDependsOn) </ CompileDependsOn > </ PropertyGroup > <!-- Override the CoreCompile Target to use btouch --> < Target Name = "GenerateBindings" Inputs = "$(MSBuildAllProjects);@(ObjcBindingApiDefinition);@(ObjcBindingCoreSource);@(ReferencePath);@(ObjcBindingNativeLibrary)" Outputs = "$(GeneratedSourcesFileList)" > < BTouch AdditionalLibPaths = "$(AdditionalLibPaths)" AllowUnsafeBlocks = "$(AllowUnsafeBlocks)" ApiDefinitions = "@(ObjcBindingApiDefinition)" CoreSources = "@(ObjcBindingCoreSource)" DefineConstants = "$(DefineConstants)" GeneratedSourcesDirectory = "$(GeneratedSourcesDirectory)" GeneratedSourcesFileList = "$(GeneratedSourcesFileList)" Namespace = "$(Namespace)" BTouchToolPath = "$(BTouchToolExe)" CompilerPath = "$(CscPath)" BaseLibDll = "$(BaseLibDllPath)" NoStdLib = "$(NoStdLib)" > < Output TaskParameter = "GeneratedSourcesFileList" ItemName = "GeneratedSourcesFileList" /> </ BTouch > < ReadLinesFromFile File = "$(GeneratedSourcesFileList)" > < Output TaskParameter = "Lines" ItemName = "GeneratedSources" /> </ ReadLinesFromFile > < CreateItem Include = "@(ObjcBindingCoreSource)" > < Output TaskParameter = "Include" ItemName = "Compile" /> </ CreateItem > < CreateItem Include = "@(GeneratedSources)" > < Output TaskParameter = "Include" ItemName = "Compile" /> </ CreateItem > < CreateItem Include = "@(ObjcBindingNativeLibrary)" > < Output TaskParameter = "Include" ItemName = "ManifestResourceWithNoCulture" /> </ CreateItem > </ Target > </ Project > |
■*.sln と *.vbproj を書き換える
どうやら、mac にデプロイしていなさそうの勘はあたりで、デプロイ(配置)するようにしたら通りました。
*.sln に以下になるように追加。「Deploy.0」が配置の実行にあたります。91DDFB1F-30BD-472E-9022-0D0E29A8A301 は VB プロジェクトの GUID です。
1 2 3 | {91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator {91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator {91DDFB1F-30BD-472E-9022-0D0E29A8A301}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator |
*.proj のほうは、以下になるように書き換えます。ProjectTypeGuids はプロジェクトの種類を設定するもので、6BC8ED88-2882-458C-8E55-DFD12B67127B は、Xamarin.iOS の C# の GUID です。このままだと C# のコンパイラが走ってしまうのでコメントアウトしています。が、このコメントを消してしまう(ProjectTypeGuids自体を削除する)とデプロイできません。変ですね(苦笑)。まあ、*.vbproj の読み込み部分が変らしいので、これはこれで使わせてもらいます。
1 2 3 4 | <ProjectGuid>{91DDFB1F-30BD-472E-9022-0D0E29A8A301}</ProjectGuid> <!-- <ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{F184B08F-C81C-45F6-A57F-5ABD9991F28F}</ProjectTypeGuids> --> |
ここに出てくる GUID は、*.sln の上のほうにある Project 部分に対応します。
1 2 | Project( "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}" ) = "HelloVB" , "HelloVBHelloVB.vbproj" , "{91DDFB1F-30BD-472E-9022-0D0E29A8A301}" EndProject |
ProjectGuid 関連はこちらへ。おそらく、Visual Basic 用のGUIDを自作すればOKかと思います。
VSの「プロジェクトの種類がこのインストールでサポートされていません」(ProjectTypeGuids) – あおきのTechメモ
http://d.hatena.ne.jp/aoki1210/20090912/p1
INFO: List of known project type Guids
http://www.mztools.com/Articles/2008/MZ2008017.aspx
■Microsoft.VisualBasic.dll を外す
先の方法で、無事 mac へのデプロイはできたのですが、こんどは VisualBasic.dll がロードできなくて iOS シミュレータを立ち上げる前にこけます。具体的には Visual Studio に出てくる出力をみると、以下な感じで、何かが load できていません。
1 2 3 4 5 6 7 8 9 | Loaded assembly: /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe 2014-03-25 03:06:09.981 HelloVB[9011:70b] Could not load 'HelloVB' for registration: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded. at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly, bool ) at System.Reflection.Assembly.GetTypes () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/ class /corlib/System.Reflection/Assembly.cs:351 at MonoTouch.Registrar.OldDynamicRegistrar.RegisterAssembly (System.Reflection.Assembly a) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/OldDynamicRegistrar.cs:67 Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll [External] 2014-03-25 03:06:09.983 HelloVB[9011:70b] This could be due to an outdated assembly kept by the simulator, location: /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe Missing method SetProjectError in assembly /Users/masuda/Library/Caches/Xamarin/mtbs/builds/HelloVB/91ddfb1f-30bd-472e-9022-0d0e29a8a301/assemblies/HelloVB.exe, type Microsoft.VisualBasic.CompilerServices.ProjectData An unhandled exception occured. |
多分、C# にない VisualBasic.dll を参照していると思われるので、*.vbproj から以下の設定で VisualBasic.dll を参照しないようにします。
1 2 3 4 5 6 | <PropertyGroup> <Configuration Condition= " '$(Configuration)' == '' " >Debug</Configuration> <Platform Condition= " '$(Platform)' == '' " >iPhoneSimulator</Platform> ... <NoVBRuntimeReference> true </NoVBRuntimeReference> </PropertyGroup> |
VBなのに VisualBasic.dll を参照しないので、いくつか VB 特有の機能が失われますが、ひとまず。
VisualBasic.dll を参照していないので、My Project 回りの *.vb でコンパイルエラーが出るので、コメントアウトしていまいます。
■デバッグ実行する
■サンプルはこちら
Xamarin の Hello World を VB に直したサンプルです。先の *.targets ファイルも入っています。
VisualBasic.dll を外してしまったために、VB 特有の関数が使えなくなっています。ですが、mono にも vbnc という VB コンパイラがあるので、VisualBasic.dll はあるハズなんですよね。そのあたりをうまく整合性をあわせてやれば、もうちょっと汎用性がある形でできると思うのですが。このあたりは、Android版を作りながら考える予定。
追記 2014/03/26
プロジェクトテンプレートにしてみました。