Xamarin+Prism开发详解七:Plugin开发与打包测试

有了上章【Xamarin+Prism开发详解六:DependencyService与IPlatformInitializer的关系】的基础,现在来理解Plugin开发就简单了。

本文实例代码地址:https://github.com/NewBLife/XamarinDemo/tree/master/Speecher

简介

Plugin其实就是各类相对独立的功能提取出来的Package,一般都不引用Xamarin相关类库,比如上章的Text To Speech功能(Github库地址https://github.com/jamesmontemagno/TextToSpeechPlugin):

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3shzifi4mVf1yM6GGkzF24iLA7O1QP-xofE2QIMQCZH4tO.png

xamarin的Plugin有一个专门的统计库【xamarin/XamarinComponents】,目前统计结果如下:

Battery StatusGather battery level, charging status, and type.NuGetGitHub@JamesMontemagno

Barcode ScannerScan and create barcodes with ZXing.NET.Mobile.NuGetGitHub@Redth

Bluetooth LEScan and connect to Bluetooth devices.NuGetGitHub@allanritchie911

CalendarQuery and modify device calendarsNuGetGitHubCaleb Clarke

CompassAccess device compass heading.NuGetGitHub@cbartonnh & @JamesMontemagno

ConnectivityGet network connectivity info such as type and if connection is available.NuGetGitHub@JamesMontemagno

CryptographyPCL Crypto provides a consistent, portable set of crypto APIs.NuGetGitHub@aarnott

Device InfoProperties about device such as OS, Model, and Id.NuGetGitHub@JamesMontemagno

Device MotionProvides access to Accelerometer, Gyroscope, Magnetometer, and Compass.NuGetGitHub@rdelrosario

Embedded ResourceUnpack embedded resource cross-platform.NuGetGitHub@JosephHill

External MapsLaunch external maps from Lat/Long or Address.NuGetGitHub@JamesMontemagno

File Storage/File SystemPCL Storage offers cross platform storage APIs.NuGetGitHub@dsplaisted

File PickerPick and save files.NuGetGitHub@studyxnet

FingerprintAccess Fingerprint sensor on iOS, Android, and Windows.NuGetGitHub@smstuebe

FFImageLoadingImage loading with caching, placeholders, transformations and moreNuGetGitHub@molinch, @daniel-luberda

GeofencingMonitor regions when user enters/exits.NuGetGitHub@allanritchie911

GeolocatorEasily detect GPS location of device.NuGetGitHub@JamesMontemagno

iBeacon & EstimoteRange and monitor Bluetooth beacons.NuGetGitHub@allanritchie911

LampAccess to LEDNuGetGitHub@kphillpotts

Local NotificationsShow local notificationsNuGetGitHub@EdSnider, @JamesMontemagno

Manage SleepManage auto sleep/auto lock.NuGetGitHub@molinch0

MediaTake or pick photos and videos.NuGetGitHub@JamesMontemagno

Media ManagerPlayback for Audio.NuGetGitHub@mhvdijk

MessagingMake phone call, send sms, and send e-mailNuGetGitHub@cjlotz

Microsoft BandConnect and communicate with the Microsoft Band from shared code!NuGetGitHub@mattleibow

Mono.Data.SqliteAdd Mono.Data.Sqlite to any Xamarin or Windows .NET app.NuGetGitHub@mattleibow

PermissionsEasily check and request runtime permissions.NuGetGitHub@JamesMontemagno

Persistent key-value storeAkavache is an asynchronous, persistent (i.e. writes to disk) key-value store.NuGetGitHub@paulcbetts

Portable RazorLightweight implemenation of ASP.NET MVC APIs for mobile.NuGetGitHub@JosephHill

Push NotificationsCross platform iOS and Android Push Notifications.NuGetGitHub@rdelrosario

Secure StorageProvides secure storage for key value pairs DataNuGetGitHub@sameerIOTApps

SettingsSimple & Consistent cross platform settings API.NuGetGitHub@JamesMontemagno

ShareEasily share text, links, or open a browser.NuGetGitHub@JamesMontemagno & @Jakob Gürtl

SocketsTCP & UDP Listeners and Clients + UDP multicast.NuGetGitHub@rdavis_au

Speech RecognitionSpeech to Text.NuGetGitHub@allanritchie911

Text To SpeechTalk back text from shared code.NuGetGitHub@JamesMontemagno

ToastA simple way of showing toast/pop-up notifications.NuGetGitHub@AdamPed & @EgorBo

User DialogsMessage box style dialogs.NuGetGitHub@allanritchie911

Version TrackingTrack which versions of your app a user has previously installed.NuGetGitHub@ColbyLWilliams

VibrateVibrate any device.NuGetGitHub@JamesMontemagno
 

开发实践

Xamarin为Plugin开发提供了一个Visual Studio模板,通过它你可以快速开发各类Plugin。

1、安装Plugin for Xamarin Templates

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3sh32e-W866dGPyPzMyqbPBcbiXQGRUH00GrzHkOT71u7a.png

2、从Plugin for Xamarin模板新建项目

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3sh0HJ_UjSNdU6zfJkxfy5fVGyfArl2Oli8isQVuXyrwj3.png

整体项目结构:

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3shzrDq18a67sc5T6scEnBm9tH_S06Mk82H_VJEXTc31uk.png

通过模板创建的项目包含三类工程文件:

  • Plugin.功能名(PCL):懒汉式实例创建文件,生成Plugin.功能名.dll。(共享类文件)
  • Plugin.功能名.Abstractions(PCL):接口和Enums的定义,生成Plugin.功能名.Abstractions.dll。
  • Plugin.功能名.平台名(n个):接口实现,生成Plugin.功能名.dll。

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3sh_AsWzmC_9cvx_QEObL3cUeQE2yTMuQqwHhwZ_mbQNFD.png

3、添加接口

namespace Plugin.Speecher.Abstractions
{
    /// <summary>
    /// Interface for Speecher
    /// </summary>
    public interface ISpeecher
    {
        void Speak(string text);
    }
}

4、各个平台接口实现

iOS平台

using AVFoundation;
using Plugin.Speecher.Abstractions;


namespace Plugin.Speecher
{
    /// <summary>
    /// Implementation for Speecher
    /// </summary>
    public class SpeecherImplementation : ISpeecher
    {
        public void Speak(string text)
        {
            var speechSynthesizer = new AVSpeechSynthesizer();

            var speechUtterance = new AVSpeechUtterance(text)
            {
                Rate = AVSpeechUtterance.MaximumSpeechRate / 4,
                Voice = AVSpeechSynthesisVoice.FromLanguage("en-US"),
                Volume = 0.5f,
                PitchMultiplier = 1.0f
            };

            speechSynthesizer.SpeakUtterance(speechUtterance);
        }
    }
}

Android平台(由于没有Xamarin.Forms,所以这里使用Application.Context)

using Android.App;
using Android.Runtime;
using Android.Speech.Tts;
using Plugin.Speecher.Abstractions;
using System.Collections.Generic;

namespace Plugin.Speecher
{
    /// <summary>
    /// Implementation for Feature
    /// </summary>
    public class SpeecherImplementation : Java.Lang.Object, ISpeecher, TextToSpeech.IOnInitListener
    {
        TextToSpeech speaker;
        string toSpeak;
        public SpeecherImplementation() { }

        public void Speak(string text)
        {
            var ctx = Application.Context;
            toSpeak = text;
            if (speaker == null)
            {
                speaker = new TextToSpeech(ctx, this);
            }
            else
            {
                var p = new Dictionary<string, string>();
                speaker.Speak(toSpeak, QueueMode.Flush, p);
            }
        }

        public void OnInit([GeneratedEnum] OperationResult status)
        {
            if (status.Equals(OperationResult.Success))
            {
                var p = new Dictionary<string, string>();
                speaker.Speak(toSpeak, QueueMode.Flush, p);
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("was quiet");
            }
        }
    }
}

UWP平台

using Plugin.Speecher.Abstractions;
using System;
using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Controls;

namespace Plugin.Speecher
{
    /// <summary>
    /// Implementation for Feature
    /// </summary>
    public class SpeecherImplementation : ISpeecher
    {
        public async void Speak(string text)
        {
            MediaElement mediaElement = new MediaElement();

            var synth = new SpeechSynthesizer();
            var stream = await synth.SynthesizeTextToStreamAsync(text);
            mediaElement.SetSource(stream, stream.ContentType);
            mediaElement.Play();
        }
    }
}

备注

如果确定一直使用Prism做开发的话,只需要定义接口与接口的实现就可以了。然后在实际项目各个平台的RegisterTypes方法中注册接口到IOC容器,

public void RegisterTypes(IUnityContainer container){    container.RegisterType<ISpeecher, SpeecherImplementation>();}

使用IOC容器管理对象生存周期,比懒汉式加载更加自由方便。比如在Prism.Forms中只需构造函数添加接口作为参数就可以自动创建对象。

打包并测试

在安装Plugin for Xamarin Templates的时候其实已经安装了另外一个打包用的模板【Plugin for Xamarin NuSpec】,通过它可以快速打包。

1、添加Package配置文件【Speecher.Plugin.nuspec】

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3shy8xO3EZE4WW_UfOcw3n4pu9_SsBrIW3flfnvLWCSlV9.png

默认生成的文件如下,包含所有平台:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata minClientVersion="2.8.3">
        <id>Plugin.Speecher</id>
        <version>1.0.0</version>
        <title>Speecher Plugin for Xamarin and Windows</title>
        <authors>Your Name</authors>
        <owners>Your Name</owners>
        <licenseUrl/>
        <projectUrl/>
        <!--Default Icon, a template can be found:  https://raw.githubusercontent.com/jamesmontemagno/Xamarin-Templates/master/Plugins-Templates/icons/plugin_icon.png-->  
        <iconUrl>https://raw.githubusercontent.com/jamesmontemagno/Xamarin-Templates/master/Plugins-Templates/icons/plugin_icon_nuget.png</iconUrl>

        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>
         Long description for your plugin.
        </description>
        <summary>Short description for your plugin.</summary>
        <tags>xamarin, pcl, xam.pcl, plugin, plugin for xamarin, windows phone, winphone, wp8, winrt, android, xamarin.forms, ios</tags>
        <dependencies>
            <group targetFramework="net">
            </group>
            <group targetFramework="win">
            </group>
            <group targetFramework="wp">
            </group>
            <group targetFramework="wpa">
            </group>
            <group targetFramework="MonoAndroid">
            </group>
            <group targetFramework="Xamarin.iOS10">
            </group>
            <group targetFramework="Xamarin.Mac20">
            </group>
            <group targetFramework="portable-net45+win+wpa81+wp80">
            </group>
            <group targetFramework="uap">
            </group>
            <group targetFramework="dotnet">
            </group>
        </dependencies>
    </metadata>
    <files>
        <!--Core-->
        <file src="Speecher\Plugin.Speecher\bin\Release\Plugin.Speecher.dll" target="lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher\bin\Release\Plugin.Speecher.xml" target="lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher\bin\Release\Plugin.Speecher.pdb" target="lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.Speecher.pdb" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.Speecher.Abstractions.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.pdb" target="lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\Plugin.Speecher.Abstractions.pdb" />        
        
        <!--dotnet-->
        <file src="Speecher\Plugin.Speecher\bin\Release\Plugin.Speecher.dll" target="lib\dotnet\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher\bin\Release\Plugin.Speecher.xml" target="lib\dotnet\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher\bin\Release\Plugin.Speecher.pdb" target="lib\dotnet\Plugin.Speecher.pdb" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\dotnet\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\dotnet\Plugin.Speecher.Abstractions.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.pdb" target="lib\dotnet\Plugin.Speecher.Abstractions.pdb" />
        
        <!--Win Phone Silverlight-->
        <file src="Speecher\Plugin.Speecher.WindowsPhone8\bin\Release\Plugin.Speecher.dll" target="lib\wp8\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher.WindowsPhone8\bin\Release\Plugin.Speecher.xml" target="lib\wp8\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher.WindowsPhone8\bin\Release\Plugin.Speecher.pdb" target="lib\wp8\Plugin.Speecher.pdb" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\wp8\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\wp8\Plugin.Speecher.Abstractions.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.pdb" target="lib\wp8\Plugin.Speecher.Abstractions.pdb" />
        
        <!--Win Phone 81-->
        <file src="Speecher\Plugin.Speecher.WindowsPhone81\bin\Release\Plugin.Speecher.dll" target="lib\wpa81\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher.WindowsPhone81\bin\Release\Plugin.Speecher.xml" target="lib\wpa81\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher.WindowsPhone81\bin\Release\Plugin.Speecher.pdb" target="lib\wpa81\Plugin.Speecher.pdb" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\wpa81\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\wpa81\Plugin.Speecher.Abstractions.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.pdb" target="lib\wpa81\Plugin.Speecher.Abstractions.pdb" />
        
        <!--WinStore-->
        <file src="Speecher\Plugin.Speecher.WindowsStore\bin\Release\Plugin.Speecher.dll" target="lib\win8\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher.WindowsStore\bin\Release\Plugin.Speecher.xml" target="lib\win8\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher.WindowsStore\bin\Release\Plugin.Speecher.pdb" target="lib\win8\Plugin.Speecher.pdb" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\win8\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\win8\Plugin.Speecher.Abstractions.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.pdb" target="lib\win8\Plugin.Speecher.Abstractions.pdb" />

        <!--Xamarin.Android-->
        <file src="Speecher\Plugin.Speecher.Android\bin\Release\Plugin.Speecher.dll" target="lib\MonoAndroid10\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher.Android\bin\Release\Plugin.Speecher.xml" target="lib\MonoAndroid10\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher.Android\bin\Release\Plugin.Speecher.pdb" target="lib\MonoAndroid10\Plugin.Speecher.pdb" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\MonoAndroid10\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\MonoAndroid10\Plugin.Speecher.Abstractions.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.pdb" target="lib\MonoAndroid10\Plugin.Speecher.Abstractions.pdb" />

        <!--Xamarin.iOS-->
        <file src="Speecher\Plugin.Speecher.iOS\bin\iPhone\Release\Plugin.Speecher.dll" target="lib\Xamarin.iOS10\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher.iOS\bin\iPhone\Release\Plugin.Speecher.xml" target="lib\Xamarin.iOS10\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\Xamarin.iOS10\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\Xamarin.iOS10\Plugin.Speecher.Abstractions.xml" />

        <!--uap-->
        <file src="Speecher\Plugin.Speecher.UWP\bin\Release\Plugin.Speecher.dll" target="lib\UAP10\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher.UWP\bin\Release\Plugin.Speecher.xml" target="lib\UAP10\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher.UWP\bin\Release\Plugin.Speecher.pdb" target="lib\UAP10\Plugin.Speecher.pdb" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\UAP10\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\UAP10\Plugin.Speecher.Abstractions.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.pdb" target="lib\UAP10\Plugin.Speecher.Abstractions.pdb" />
        
        <!--Xamarin.Mac
        <file src="Speecher\Plugin.Speecher.Mac\bin\iPhone\Release\Plugin.Speecher.dll" target="lib\Xamarin.Mac20\Plugin.Speecher.dll" />
        <file src="Speecher\Plugin.Speecher.Mac\bin\iPhone\Release\Plugin.Speecher.xml" target="lib\Xamarin.Mac20\Plugin.Speecher.xml" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.dll" target="lib\Xamarin.Mac20\Plugin.Speecher.Abstractions.dll" />
        <file src="Speecher\Plugin.Speecher.Abstractions\bin\Release\Plugin.Speecher.Abstractions.xml" target="lib\Xamarin.Mac20\Plugin.Speecher.Abstractions.xml" />
        -->
    </files>
</package>
  • 由于只正对iOS,Android,UWP三个平台,其他的配置都删除掉
  • 固定文件名用*代替

修改后的文件如下:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata minClientVersion="2.8.3">
    <id>Plugin.Speecher</id>
    <version>1.0.0</version>
    <title>Speecher Plugin for Xamarin and Windows</title>
    <authors>NewBlifes</authors>
    <owners>NewBlifes</owners>
    <iconUrl>https://github.com/NewBLife/NewBlife.Core/blob/master/logo.png</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>
      Text to speech plugin.
    </description>
    <summary>Text to speech plugin.</summary>
    <tags>xamarin, pcl, xam.pcl, plugin, plugin for xamarin, windows phone, UWP, android, xamarin.forms, ios</tags>
    <dependencies>
      <group targetFramework="MonoAndroid">
      </group>
      <group targetFramework="Xamarin.iOS10">
      </group>
      <group targetFramework="portable-net45+win+wpa81+wp80">
      </group>
      <group targetFramework="uap">
      </group>
    </dependencies>
  </metadata>
  <files>
    <!--Core-->
    <file src="Speecher\Plugin.Speecher\bin\Release\Plugin.Speecher.*" target="lib\portable-net45+wp8+wpa81+win8+MonoAndroid10+MonoTouch10+Xamarin.iOS10+UAP10\" />

    <!--Xamarin.Android-->
    <file src="Speecher\Plugin.Speecher.Android\bin\Release\Plugin.Speecher.*" target="lib\MonoAndroid10\" />

    <!--Xamarin.iOS-->
    <file src="Speecher\Plugin.Speecher.iOS\bin\iPhone\Release\Plugin.Speecher.*" target="lib\Xamarin.iOS10\" />

    <!--uap-->
    <file src="Speecher\Plugin.Speecher.UWP\bin\Release\Plugin.Speecher.*" target="lib\UAP10\" />

  </files>
</package>

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3shwX3uJk3Q2DJ4srhCVT99Up_bMJEDErNM-nHjvvlKgdf.png

2、编译解决方案的Release版本,使用【nuget pack】命令打包

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3sh6ru4FaySJm9SpNJ26cOQNv_VOp6pp7KgP6RMMfJIQuD.png

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3sh6_oHxsVdveFEpZ6zC5zDwcVdjaVqohqV_BS0vhtvvpD.png

如果没有Nuget的命令行工具记得安装。

3、测试

添加本地包路径

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3shyMsVgruw0GUC6jFgXA3eKPhr97ZXuM8Ch90p8M90x8r.png

创建测试项目,添加Package引用

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3sh-rVjBiI1FFXUnc0XazDiKE3Uca452YUsI_6kvzq2tPE.png

测试代码

using Plugin.Speecher;
using Prism.Commands;
using Prism.Mvvm;

namespace SpeecherTest.ViewModels
{
    public class MainPageViewModel : BindableBase
    {
        private string _speakText;
        public string SpeakText
        {
            get { return _speakText; }
            set
            {
                SetProperty(ref _speakText, value);
            }
        }

        public MainPageViewModel()
        {
        }

        public DelegateCommand SpeakCommand => new DelegateCommand(
            () =>
            {
                CrossSpeecher.Current.Speak(SpeakText);
            },
            () => !string.IsNullOrEmpty(SpeakText)).ObservesProperty(() => this.SpeakText);
    }
}

DbhVozhcEZvQGMfR6Pkc-A33RMAoVqH3kdctdDxLPiyU1XxDGxxs5yqZVWHnl7KJvbxNfrRDaFAeruvvJb3sh6cEKztYKJ2OR_mooufqp6rVtpRSYmIIMkyQFNRkor8x.gif

总结

通过使用Plugin For xamarin模块来开发Plugin简单又快速,你只需要关注真正的逻辑就可以。

相关推荐