I'm creating an UWP application for Windows 10 that uses the Speech APIs but I'm getting a weird error when compiling.
The scenario is this:
A PCL Project targeted to Windows 8.1 (When I created the project I set Windows 10 as target but Visual Studio downgrades to Windows 8.1 because "they support the same set of portable APIs") and with a reference to "Windows.Foundation.UniversalApiContract" because it contains the Speech APIs (Windows.Media.SpeechRecognition and Windows.Media.SpeechSynthesis).
An UWP Application with a reference to the PCL Project. The UWP doesn't use Speech APIs, I use it only on the PCL project.
The PCL Project is built successfully, but when I build UWP Project there are lots of errors like this "The .winmd file 'Windows.Foundation.UniversalApiContract.winmd' contains type 'XXXXX'. The use of the Windows namespace is reserved." and I think the error is caused by the references of the PCL Project.
I tried calling the Speech APIs directly from the UWP app and it seems to work but I don't like it because I prefer to have the application logic in other library project just in case I port the app to other platforms.
I don't know what to do. If the PCL is targeted to Windows 8.1 I must be able to use Speech APIs without adding references as in the UWP project, isn't it? Is any workaround to force the PCL to target Windows 10 only? I'm wrong and I should use other project type instead PCL?
You cannot reference Windows.Foundation.UniversalApiContract
in your PCL. Because it is a portable class library, it cannot have reference to a Windows-only library. To use Windows API, you would need to have a Windows Universal Class Library or a Windows Universal Runtime Component.
Because you want to have the app portable, you would have to choose a different approach with Dependency Injection.
In the Portable Class Library should be only platform-agnostic code. Because Speech APIs are definitely not platform agnostic (each OS has its own implementation and each implementation is very different), you will need to have just an interface inside your PCL and then provide the implementation in your platform projects.
Let's say for the sake of simplicity, that you want to use only speech synthesis (for speech recognition, the solution would be analogous).
First of all you would create an ISpeechSynthesisService
interface inside your PCL:
public interface ISpeechSynthesisService
{
Task SynthesizeTextAsync( string text );
}
Now you would provide an implementation inside of your UWP project:
public class WindowsSpeechSynthesisService : ISpeechSynthesisService
{
public Task SynthesizeTextAsync( string text )
{
//implementation
}
}
Because you probably would like to use the service inside your PCL project (for example in a ViewModel, you will now benefit of using a Dependency Injection container. Most MVVM frameworks offer this out of the box (Template 10, MvvmLight, MvvmCross, Prism, etc.). The DI container allows you to register implementations for a given interface and the create their instances. So in your UWP project you do something like:
container.RegisterType<ISpeechSynthesisService, WindowsSpeechSynthesisService>();
And then you would either get instance in the PCL directly, for example:
var speechService = container.GetInstance<ISpeechSynthesisService>();
Or you would rather use constructor injection for your ViewModels or other services:
public MyViewModel( ISpeechSynthesisService speechService )
{
//...
}
As I have mentioned, you will get both these approaches "for free" with most MVVM frameworks, so you will not need to implement this manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With