Xamarin Advent Calendar 2014ã®4æ¥ç®ã§ãã
MvvmCrossã¬ãå¢ã¨ãã¦ã¯æ¸ããããå¾ãªãã¨æã£ã¦ãããã©å¿ããã¦ããã¦ããªãã£ãMvvmCrossã®ãã©ã°ã¤ã³ã®ä½ãæ¹ããã®æ©ä¼ãåãã¦ç´¹ä»ãããã¨æãã¾ãã
ããããMvvmCrossãã©ã°ã¤ã³ã¨ã¯
MvvmCrossãã©ã°ã¤ã³ã¯ãMvvmCrossã§ä½ã£ã¦ããããã¸ã§ã¯ãã«ã«ã¡ã©ããã¤ãã¬ã¼ã·ã§ã³ã¨ãã£ããã©ãããã©ã¼ã ä¾åã³ã¼ããåå©ç¨ã§ããå½¢ã§æä¾ãã¾ãããã©ã°ã¤ã³ãçµã¿è¾¼ãã¨ãIoCã³ã³ããã«ãã©ã°ã¤ã³ãæä¾ãã¦ããã¯ã©ã¹ãç»é²ããã¾ãã
å ¬å¼ã§ãå¤ãã®ããã±ã¼ã¸ãå ¬éããã¦ãããNuGetã§MvvmCross Pluginã§æ¤ç´¢ããã¨å¤§éã«åºã¦ãã¾ããNuGetã§å ¬éããã¦ãããã®ã¯ãã©ã°ã¤ã³ã追å ããã¨ããã«ä½¿ãå§ãããã¨ãã§ãã¾ãã
ã¾ãããã©ã°ã¤ã³ã¯ç°¡åã«ä½ããã¨ãã§ããã®ã§ãèªåãã¡ã§ããã使ãæ©è½ã¯ãã©ã°ã¤ã³åãã¦ãããã¨ã§åå©ç¨ãããã¨ãã§ãã¾ãã
ãã©ã°ã¤ã³ã®ä½ãæ¹
ä»åã¯ç°¡æçãªTextToSpeechã®æ©è½ãä½ãã¨ããæ³å®ã®ãã¨ããã©ã°ã¤ã³ãä½æãã¦ã¿ããã¨æãã¾ãã
ããã¸ã§ã¯ãã®ä½æ
MvvmCrossã®å½åè¦åã«åããã¦ããã¸ã§ã¯ããä½æãã¾ãããã©ã°ã¤ã³ã®PCLã«ã¯Coreãã¤ããããã以å¤ã¯é常ã®ããã¸ã§ã¯ãã¨åãã§ããã¡ã¤ã³ã®åå空éã¯Iseteki.MvvmCross.Plugin.TextToSpeechã¨ãããã¨ã«ãã¾ãããã
- ã½ãªã¥ã¼ã·ã§ã³:
Iseteki.MvvmCross.Plugin.TextToSpeech
ä½æã§ããããåããã¸ã§ã¯ãã«ããããã©ã«ãã®Class1.csã¯åé¤ããiOS, Androidã®ããã¸ã§ã¯ãããã¯PCLã®ããã¸ã§ã¯ããåç §ãã¦ããã¾ãã
MvvmCross ã®è¿½å
ãã¹ã¦ã®ããã¸ã§ã¯ãã«MvvmCross - Hot Tuna MvvmCross Librariesã追å ãã¾ããããã¯MvvmCrossã®æ©è½ã使ãããã®æå°ã®æ§æã®ã©ã¤ãã©ãªã®ã¿ãããã¸ã§ã¯ãã«è¿½å ãããã®ã§ãã
ãã©ã°ã¤ã³ã®åºæ¬ã³ã¼ãã®è¿½å
MvvmCrossã«ãã©ã°ã¤ã³ã¨ãã¦èªèããããã©ã°ã¤ã³å ã®ã¯ã©ã¹ãç»é²ããããã«ãPCLã¨åãã©ãããã©ã¼ã ã«ã¯ããã¾ãã®ã³ã¼ãã追å ããå¿ è¦ãããã¾ãã
PCL: PluginLoader.cs
PCLããã¸ã§ã¯ãã«PluginLoader.csããããã¡ã¤ã«ãä½ãã以ä¸ã®å 容ã«ãã¾ããããã¯å®å ¨ã«ã³ããã³ã¼ãã§ãã
using System; using Cirrious.CrossCore.Plugins; using Cirrious.CrossCore; namespace Iseteki.MvvmCross.Plugin.TextToSpeech { public class PluginLoader : IMvxPluginLoader { public static readonly PluginLoader Instance = new PluginLoader(); public void EnsureLoaded() { var manager = Mvx.Resolve<IMvxPluginManager>(); manager.EnsurePlatformAdaptionLoaded<PluginLoader>(); } } }
ãã©ãããã©ã¼ã : Plugin.cs
åãã©ãããã©ã¼ã ã«ã¯Plugin.csãä½æãã以ä¸ã®å 容ã¨ãã¾ãããã®ã¯ã©ã¹ã®Loadã¡ã½ããã®ä¸ã§ãã©ã°ã¤ã³ãæä¾ããã¯ã©ã¹ãIoCã³ã³ããã«ç»é²ãããã¨ã«ãªãã¾ãã
using System; using Cirrious.CrossCore.Plugins; namespace Iseteki.MvvmCross.Plugin.TextToSpeech.Touch { public class Plugin : IMvxPlugin { public void Load() { // ããã«IoCã³ã³ããã¸ã®ç»é²å¦çãè¨è¿°ãã } } }
ããã¾ã§ããã©ã°ã¤ã³ä½æã®ããã¾ãä½æ¥ã§ãã½ãªã¥ã¼ã·ã§ã³ã¯ä»¥ä¸ã®ãããªç¶æ ã«ãªã£ã¦ããã¯ãã§ãã
ãã©ã°ã¤ã³ã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ã®ä½æ
ããããå ã¯ãã©ã°ã¤ã³ãå®éã«æä¾ããæ©è½ãä½æãã¾ãã
ã¾ãããã©ã°ã¤ã³ãæä¾ããæ©è½ã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ãä½æãã¾ãããã®ã¤ã³ã¿ã¼ãã§ã¤ã¹ã¯ãã¹ã¦ã®ãã©ãããã©ã¼ã ã§å ±éãªã®ã§ãæ¨æºã®æ©è½ãå ±éåããå ´åã¯ããæ¤è¨ããå¿ è¦ãããã¾ãã
using System; namespace Iseteki.MvvmCross.Plugin.TextToSpeech { public interface ITextToSpeech { /// <summary> /// Text To Speech ãåæåããã¦ãããã©ãã /// </summary> bool Initialized { get; } /// <summary> /// èªã¿ä¸ãã®ãã±ã¼ã« /// </summary> SpeechLocale Locale { get; set; } /// <summary> /// Text To Speech ãåæåãã /// </summary> void Initialize(); /// <summary> /// Text To Speech ã解æ¾ãã /// </summary> void Release(); /// <summary> /// Text To Speech ãåæåããããå¼ã³åºããã /// </summary> event EventHandler InitializeCompleted; /// <summary> /// èªã¿ä¸ããå®è¡ãã /// </summary> /// <param name="text">Text.</param> void Speech(string text); } /// <summary> /// èªã¿ä¸ããã±ã¼ã«ã®ãªã¹ã /// </summary> public enum SpeechLocale { English, Japanease } }
ãã©ãããã©ã¼ã ã³ã¼ãã®è¨è¿°
åãã©ãããã©ã¼ã ã§å®ç¾©ããã¤ã³ã¿ã¼ãã§ã¤ã¹ãå®è£ ãã¾ãã
using System; using MonoTouch.AVFoundation; namespace Iseteki.MvvmCross.Plugin.TextToSpeech.Touch { public class TouchTextToSpeech : ITextToSpeech { private AVSpeechSynthesizer _speechSynthesizer; public TouchTextToSpeech() { } #region ITextToSpeech implementation public event EventHandler InitializeCompleted; public void Initialize() { if (_speechSynthesizer == null) { _speechSynthesizer = new AVSpeechSynthesizer(); if (InitializeCompleted != null) { InitializeCompleted(this, EventArgs.Empty); } } } public void Release() { if (_speechSynthesizer != null) { _speechSynthesizer.Dispose(); _speechSynthesizer = null; } } public void Speech(string text) { if (_speechSynthesizer == null) { throw new InvalidOperationException(); } var utterance = new AVSpeechUtterance(text); switch (Locale) { case SpeechLocale.Japanease: utterance.Voice = AVSpeechSynthesisVoice.FromLanguage("ja-JP"); break; default: utterance.Voice = AVSpeechSynthesisVoice.FromLanguage("en-US"); break; } _speechSynthesizer.SpeakUtterance(utterance); } public bool Initialized { get { return _speechSynthesizer != null; } } public SpeechLocale Locale { get; set; } #endregion } }
using System; using Cirrious.CrossCore.Droid; namespace Iseteki.MvvmCross.Plugin.TextToSpeech.Droid { public class DroidTextToSpeech : Java.Lang.Object, ITextToSpeech, Android.Speech.Tts.TextToSpeech.IOnInitListener { Android.Speech.Tts.TextToSpeech _tts; IMvxAndroidGlobals _globals; public DroidTextToSpeech(IMvxAndroidGlobals globals) { _globals = globals; } #region ITextToSpeech implementation public event EventHandler InitializeCompleted; public void Initialize() { if (_tts == null) { _tts = new Android.Speech.Tts.TextToSpeech(_globals.ApplicationContext, this); } } public void Release() { if (_tts != null) { _tts.Shutdown(); _tts.Dispose(); _tts = null; Initialized = false; } } public void Speech(string text) { if (Initialized == false) { throw new InvalidOperationException(); } Java.Util.Locale locale = Java.Util.Locale.English; if (Locale == SpeechLocale.Japanease) { locale = Java.Util.Locale.Japanese; } switch (_tts.IsLanguageAvailable(locale)) { case Android.Speech.Tts.LanguageAvailableResult.MissingData: case Android.Speech.Tts.LanguageAvailableResult.NotSupported: throw new NotSupportedException(); default: _tts.SetLanguage(locale); break; } _tts.Speak(text, Android.Speech.Tts.QueueMode.Flush, null); } public bool Initialized { get; private set; } public SpeechLocale Locale { get; set; } #endregion #region IOnInitListener implementation public void OnInit(Android.Speech.Tts.OperationResult status) { if (status == Android.Speech.Tts.OperationResult.Success) { Initialized = true; if (InitializeCompleted != null) { InitializeCompleted(this, EventArgs.Empty); } } } #endregion } }
IoCã³ã³ããã¸ã®ç»é²
ã¤ã³ã¿ã¼ãã§ã¤ã¹ããã©ãããã©ã¼ã å®è£ ãã§ããããIoCã³ã³ããã«ç»é²ããã³ã¼ããPlugin.csã«è¿½å ãã¾ããRegisterType ã使ã㨠Resolve ãããã³ã«æ°ããã¤ã³ã¹ã¿ã³ã¹ãä½æãããRegisterSingletonã使ãã¨Singletonã«ãªãã¾ãã
using System; using Cirrious.CrossCore.Plugins; using Cirrious.CrossCore; namespace Iseteki.MvvmCross.Plugin.TextToSpeech.Touch { public class Plugin : IMvxPlugin { public void Load() { // ããã«IoCã³ã³ããã¸ã®ç»é²å¦çãè¨è¿°ãã Mvx.RegisterType<ITextToSpeech, TouchTextToSpeech>(); // 追å } } }
ãã¼ãã¹ãã©ããã³ã¼ãã®ä½æ
ããã¾ã§ã§ãã©ã°ã¤ã³ããã«ããã¦ãã¢ããªã®ããã¸ã§ã¯ãã«DLLã追å ããã°ãã®ã¾ã¾ä½¿ããã¨ãã§ãã¾ããããã®éã¢ããªã®ããã¸ã§ã¯ãã«ããBootstrapãã©ã«ãã«ã以ä¸ã®ãããªãã©ã°ã¤ã³ãã¼ãã¹ãã©ãããä½æããå¿ è¦ãããã¾ããMvvmCrossã¯ãã®ã¯ã©ã¹ãå ã«ãã©ã°ã¤ã³ãåæåãã¾ãã
using Cirrious.CrossCore.Plugins; namespace HogeApp.Touch.Bootstrap { public class TextToSpeechPluginBootstrap : MvxLoaderPluginBootstrapAction<Iseteki.MvvmCross.Plugin.TextToSpeech.PluginLoader, Iseteki.MvvmCross.Plugin.TextToSpeech.Touch.Plugin> { } }
ãã©ã°ã¤ã³ã®NuGetããã±ã¼ã¸å
ä»åº¦ã¯ä½æããããã©ã°ã¤ã³ã使ããããããã«NuGetããã±ã¼ã¸ã«ãã¾ãã
ãã¼ãã¹ãã©ããã³ã¼ãããã³ãã¬ã¼ãåãã¦ããã¸ã§ã¯ãã«è¿½å
æ¯åBootstrap.csãä½ãã®ã¯æéãªã®ã§ãNuGetã§è¿½å ããæã«èªåã§è¿½å ãããããã«ãã¦ããã¾ããåã®ãªã¹ã¹ã¡ã¯ããã¸ã§ã¯ãã«è¿½å ãã¦ããã¦ããã«ãã«ã¯å«ã¾ãªããã©ãã®ã¾ã¾åºåãã£ã¬ã¯ããªã«ã³ãã¼ããæ¹æ³ã§ãã
åããã¸ã§ã¯ãã«TextToSpeechPluginBootstrap.cs.pp
ã追å ãã¦ãä¸è¨ã®ããã«è¨è¿°ãã¾ããnamespaceã$rootnamespace$.Bootstrap
ã«ãã¦ããã¨ã追å å
ã®ããã¸ã§ã¯ãã«ç½®ãæãã¦ããã¾ãã
using Cirrious.CrossCore.Plugins; namespace $rootnamespace$.Bootstrap { public class TextToSpeechPluginBootstrap : MvxLoaderPluginBootstrapAction<Iseteki.MvvmCross.Plugin.TextToSpeech.PluginLoader, Iseteki.MvvmCross.Plugin.TextToSpeech.Touch.Plugin> { } }
ãã¡ã¤ã«ãã§ãããããã®ãã¡ã¤ã«ã®ããããã£ãéãã¦ããã«ãã¢ã¯ã·ã§ã³ãNoneãåºåãã£ã¬ã¯ããªã«ã³ãã¼ãã常ã«ã³ãã¼ãã¨æå®ãã¾ãã
ããã±ã¼ã¸ãããã§ã¹ããä½æ
ã½ãªã¥ã¼ã·ã§ã³ã¨åãä½ç½®ã« Package.nuspec ã¨ãããã¡ã¤ã«ãä½ãã¾ãã
<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>Iseteki.MvvmCross.Plugin.TextToSpeech</id> <title>MvvmCross - Text To Speech</title> <version>0.1.0</version> <authors>Nobuhiro Ito</authors> <owners>Nobuhiro Ito</owners> <licenseUrl>https://github.com/iseebi/MvxTextToSpeech/blob/master/LICENSE</licenseUrl> <projectUrl>https://github.com/iseebi/MvxTextToSpeech</projectUrl> <!-- <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl> --> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>Text-to-Speech for MvvmCross</description> <releaseNotes>0.1.0 - First Release</releaseNotes> <copyright>Copyright (C) 2014 Nobuhiro Ito</copyright> <tags>mvvmcross mvvm xamarin monoandroid monodroid monotouch</tags> <dependencies> <dependency id="MvvmCross.HotTuna.CrossCore" version="3.2.2" /> </dependencies> </metadata> <files> <!-- Core --> <file src="Iseteki.MvvmCross.Plugin.TextToSpeech/bin/Release/Iseteki.MvvmCross.Plugin.TextToSpeech.dll" target="lib\portable-net45+wp8+win8+monoandroid+monotouch\Iseteki.MvvmCross.Plugin.TextToSpeech.dll" /> <!-- Touch --> <file src="Iseteki.MvvmCross.Plugin.TextToSpeech.Touch/bin/Release/Iseteki.MvvmCross.Plugin.TextToSpeech.dll" target="lib\monotouch\Iseteki.MvvmCross.Plugin.TextToSpeech.dll" /> <file src="Iseteki.MvvmCross.Plugin.TextToSpeech.Touch/bin/Release/Iseteki.MvvmCross.Plugin.TextToSpeech.Touch.dll" target="lib\monotouch\Iseteki.MvvmCross.Plugin.TextToSpeech.Touch.dll" /> <file src="Iseteki.MvvmCross.Plugin.TextToSpeech.Touch/bin/Release/TextToSpeechPluginBootstrap.cs.pp" target="content\monotouch\Bootstrap\TextToSpeechPluginBootstrap.cs.pp" /> <!-- Droid --> <file src="Iseteki.MvvmCross.Plugin.TextToSpeech.Droid/bin/Release/Iseteki.MvvmCross.Plugin.TextToSpeech.dll" target="lib\monoandroid\Iseteki.MvvmCross.Plugin.TextToSpeech.dll" /> <file src="Iseteki.MvvmCross.Plugin.TextToSpeech.Droid/bin/Release/Iseteki.MvvmCross.Plugin.TextToSpeech.Droid.dll" target="lib\monoandroid\Iseteki.MvvmCross.Plugin.TextToSpeech.Droid.dll" /> <file src="Iseteki.MvvmCross.Plugin.TextToSpeech.Droid/bin/Release/TextToSpeechPluginBootstrap.cs.pp" target="content\monoandroid\Bootstrap\TextToSpeechPluginBootstrap.cs.pp" /> </files> </package>
ããã±ã¼ã¸ä½æ
ããã¾ã§ã§ããããXamarin Studioã§ãªãªã¼ã¹ãã«ãããã¦ãããã¸ã§ã¯ãã®ã«ã¼ããã©ã«ãã§nuget pack
ã³ãã³ããå©ãã¨nupkgãã§ããããã¾ãã
ãã¨ã¯ãããNuGetã«ç»é²ãããªãããã¡ã¤ã«ãµã¼ãã¼ã«ããã¦ãããNuGetãªãã¸ããªã«ãããªããã¦ä½¿ããã¨ãã§ãã¾ãã
æå¾ã«
ä»åã®ããã¸ã§ã¯ãã¯githubã«ããã¦ããã¾ãã®ã§ãåèã«ãªãã°å¹¸ãã§ãã