Sök…


Anmärkningar

Om du inte vill att din kod ska gå sönder när ingen implementering hittas, kontrollera först DependencyService om den har en implementering tillgänglig.

Du kan göra detta genom en enkel kontroll om det inte är null .

var speaker = DependencyService.Get<ITextToSpeech>();

if (speaker != null)
{
    speaker.Speak("Ready for action!");
}

eller, om din IDE stöder C # 6, med operatör med nollvillkor:

var speaker = DependencyService.Get<ITextToSpeech>();

speaker?.Speak("Ready for action!");

Om du inte gör detta och ingen implementering hittas under körning genererar din kod ett undantag.

Implementera text-till-tal

Ett bra exempel på en funktion som begär plattformsspecifik kod är när du vill implementera text till tal (tts). Detta exempel antar att du arbetar med delad kod i ett PCL-bibliotek.

En schematisk översikt över vår lösning skulle se ut som bilden under.

Schematisk översikt (bild av Xamarin)

I vår delade kod definierar vi ett gränssnitt som är registrerat hos DependencyService . Det är här vi kommer att göra våra uppmaningar. Definiera ett gränssnitt som under.

public interface ITextToSpeech
{
    void Speak (string text);
}

Nu i varje specifik plattform måste vi skapa en implementering av detta gränssnitt. Låt oss börja med iOS-implementeringen.

iOS-implementering

using AVFoundation;

public class TextToSpeechImplementation : ITextToSpeech
{
    public TextToSpeechImplementation () {}

    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);
    }
}

I kodexemplet ovan märker du att det finns specifik kod för iOS. Som typer som AVSpeechSynthesizer . Dessa skulle inte fungera i delad kod.

För att registrera denna implementering med Xamarin DependencyService lägger du till detta attribut ovanför namnutrymmesdeklarationen.

using AVFoundation;
using DependencyServiceSample.iOS;//enables registration outside of namespace

[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.iOS {
    public class TextToSpeechImplementation : ITextToSpeech
//... Rest of code

Nu när du ringer ett sådant samtal i din delade kod, injiceras rätt implementering för den plattform du kör din app på.

DependencyService.Get<ITextToSpeech>() . Mer om detta senare.

Android-implementering

Android-implementeringen av den här koden ser ut som under.

using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;

public class TextToSpeechImplementation : Java.Lang.Object, ITextToSpeech, TextToSpeech.IOnInitListener
{
    TextToSpeech speaker;
    string toSpeak;

    public TextToSpeechImplementation () {}

    public void Speak (string text)
    {
        var ctx = Forms.Context; // useful for many Android SDK features
        toSpeak = text;
        if (speaker == null) {
            speaker = new TextToSpeech (ctx, this);
        } else {
            var p = new Dictionary<string,string> ();
            speaker.Speak (toSpeak, QueueMode.Flush, p);
        }
    }

    #region IOnInitListener implementation
    public void OnInit (OperationResult status)
    {
        if (status.Equals (OperationResult.Success)) {
            var p = new Dictionary<string,string> ();
            speaker.Speak (toSpeak, QueueMode.Flush, p);
        }
    }
    #endregion
}

Glöm inte igen att registrera det hos DependencyService .

using Android.Speech.Tts;
using Xamarin.Forms;
using System.Collections.Generic;
using DependencyServiceSample.Droid;


[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.Droid{
    //... Rest of code

Implementering av Windows Phone

Slutligen, för Windows Phone kan denna kod användas.

public class TextToSpeechImplementation : ITextToSpeech
{
    public TextToSpeechImplementation() {}

    public async void Speak(string text)
    {
        MediaElement mediaElement = new MediaElement();

        var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();

        SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");

        mediaElement.SetSource(stream, stream.ContentType);
        mediaElement.Play();
        await synth.SynthesizeTextToStreamAsync(text);
    }
}

Och glöm inte att registrera det ännu en gång.

using Windows.Media.SpeechSynthesis;
using Windows.UI.Xaml.Controls;
using DependencyServiceSample.WinPhone;//enables registration outside of namespace

[assembly: Xamarin.Forms.Dependency (typeof (TextToSpeechImplementation))]
namespace DependencyServiceSample.WinPhone{
    //... Rest of code

Implementering i delad kod

Nu är allt på plats för att det ska fungera! Slutligen, i din delade kod kan du nu ringa denna funktion med gränssnittet. Vid körning kommer implementeringen att injiceras vilket motsvarar den nuvarande plattformen den körs på.

I den här koden ser du en sida som kan vara i ett Xamarin Forms-projekt. Det skapar en knapp som påkallar metoden Speak() med hjälp av DependencyService .

public MainPage ()
{
    var speak = new Button {
        Text = "Hello, Forms !",
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
    };
    speak.Clicked += (sender, e) => {
        DependencyService.Get<ITextToSpeech>().Speak("Hello from Xamarin Forms");
    };
    Content = speak;
}

Resultatet blir att när appen körs och knappen klickas kommer den tillhandahållna texten att talas.

Allt detta utan att behöva göra hårda saker som kompileringstips och sådant. Du har nu ett enhetligt sätt att få tillgång till plattformsspecifik funktionalitet genom plattformsoberoende kod.

Skaffa applikations- och enhetsversionsnummer - Android och iOS - PCL

Exemplet nedan samlar enhetens OS-versionnummer och versionen av applikationen (som definieras i varje projekts egenskaper) som matas in i Versionsnamn på Android och version på iOS.

Skapa först ett gränssnitt i ditt PCL-projekt:

public interface INativeHelper {
    /// <summary>
    /// On iOS, gets the <c>CFBundleVersion</c> number and on Android, gets the <c>PackageInfo</c>'s <c>VersionName</c>, both of which are specified in their respective project properties.
    /// </summary>
    /// <returns><c>string</c>, containing the build number.</returns>
    string GetAppVersion();

    /// <summary>
    /// On iOS, gets the <c>UIDevice.CurrentDevice.SystemVersion</c> number and on Android, gets the <c>Build.VERSION.Release</c>.
    /// </summary>
    /// <returns><c>string</c>, containing the OS version number.</returns>
    string GetOsVersion();
}

Nu implementerar vi gränssnittet i Android- och iOS-projekten.

Android:

[assembly: Dependency(typeof(NativeHelper_Android))]

namespace YourNamespace.Droid{
    public class NativeHelper_Android : INativeHelper {
        
        /// <summary>
        /// See interface summary.
        /// </summary>
        public string GetAppVersion() {
            Context context = Forms.Context;
            return context.PackageManager.GetPackageInfo(context.PackageName, 0).VersionName;
        }

        /// <summary>
        /// See interface summary.
        /// </summary>
        public string GetOsVersion() { return Build.VERSION.Release; }
    }
}

iOS:

[assembly: Dependency(typeof(NativeHelper_iOS))]

namespace YourNamespace.iOS {
    public class NativeHelper_iOS : INativeHelper {
        
        /// <summary>
        /// See interface summary.
        /// </summary>
        public string GetAppVersion() { return Foundation.NSBundle.MainBundle.InfoDictionary[new Foundation.NSString("CFBundleVersion")].ToString(); }

        /// <summary>
        /// See interface summary.
        /// </summary>
        public string GetOsVersion() { return UIDevice.CurrentDevice.SystemVersion; }
    }
}

För att använda koden i en metod:

public string GetOsAndAppVersion {
    INativeHelper helper = DependencyService.Get<INativeHelper>();

    if(helper != null) {
        string osVersion  = helper.GetOsVersion();
        string appVersion = helper.GetBuildNumber()
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow