Programación con los SDK de extensión
Para comprender cómo Windows 10 permite que la aplicación de Plataforma universal de Windows (UWP) tenga como destino de forma más eficaz diferentes clases de dispositivos, en este tema se explican los conceptos siguientes.
- Familia de dispositivos
- SDK de extensión
- Contrato de API
También se muestra cómo usarlos en la programación.
Vídeo: Introducción a las familias de dispositivos y UWP
Familias de dispositivos y familia de dispositivos de destino de la aplicación
Una familia de dispositivos identifica las API, las características del sistema y los comportamientos que puede esperar en una clase de dispositivos.
Una familia de dispositivos es la base de un sistema operativo (SO). Por ejemplo, los equipos y tabletas ejecutan una edición de escritorio del sistema operativo y se basa en la familia de dispositivos de escritorio. Los dispositivos IoT ejecutan una edición de IoT del sistema operativo, que se basa en la familia de dispositivos IoT.
Cada familia de dispositivos secundarios agrega sus propias API a las API que hereda de la familia de dispositivos universales. Se garantiza que la unión resultante de las API de una familia de dispositivos secundarios esté presente en un sistema operativo basado en esa familia de dispositivos y, por tanto, en todos los dispositivos que ejecutan ese sistema operativo.
La decisión sobre qué familia de dispositivos (o familias) tendrá como destino la aplicación es la suya. Y esa decisión afecta a la aplicación en estos aspectos importantes. Determina
- las familias de dispositivos a los que se ofrece la aplicación para la instalación desde Microsoft Store (y, por tanto, los factores de forma que debes tener en cuenta al diseñar la interfaz de usuario de la aplicación) y
- el conjunto concreto de API que puede confiar en estar presente en un dispositivo que ejecuta la aplicación (el dispositivo host).
Al confiar en estar presente, significamos que puede llamar a esas API sin necesidad de probar primero para ver si están presentes en el dispositivo host. La familia de dispositivos de destino proporciona esa garantía (diferentes garantías para diferentes familias de dispositivos).
Configuración de la familia de dispositivos de destino
En el archivo de origen del manifiesto del paquete de la aplicación (el Package.appxmanifest
archivo), el elemento TargetDeviceFamily tiene un atributo Name . El valor de ese atributo es el nombre de la familia de dispositivos a la que se dirige la aplicación. Los valores siguientes son válidos.
- Windows.Desktop
- Windows.Holographic
- Windows.IoT
- Windows.Mobile
- Windows.Team
- Windows.Universal
- Windows.Xbox
De forma predeterminada, la aplicación para UWP tiene como destino la familia de dispositivos universales (es decir, Microsoft Visual Studio especifica Windows.Universal
para TargetDeviceFamily). Y eso significa que la aplicación se puede instalar en todos los dispositivos Windows 10, y que puede confiar en un gran conjunto básico de API que están presentes en el dispositivo host. Una aplicación como la que necesita tener una interfaz de usuario muy adaptable y funcionalidades de entrada completas, ya que se puede ejecutar en una amplia variedad de dispositivos. Consulte Vista previa de la interfaz de usuario en diferentes tamaños de pantalla más adelante en este tema.
Si quieres limitar las familias de dispositivos a los que se ofrece la aplicación para la instalación desde Microsoft Store, puedes elegir seleccionar como destino una familia de dispositivos diferente( por ejemplo, la familia de dispositivos de escritorio (Windows.Desktop
) o la familia de dispositivos IoT (Windows.IoT
). Por supuesto, habrá menos dispositivos que puedan hospedar la aplicación, pero podrá confiar en un conjunto mayor de API que estén presentes en esos dispositivos (que será el conjunto en la familia de dispositivos universales, además del conjunto en la familia de dispositivos de destino). Una aplicación como esa normalmente solo debe ser moderadamente adaptable; puede estar algo especializado en sus funcionalidades de entrada y interfaz de usuario, ya que solo se puede ejecutar en un tipo específico de dispositivo.
Sugerencia
Pero también puedes tener lo mejor de ambos mundos. Puedes configurar la aplicación para que se ejecute en todos los dispositivos Windows 10 y también acceder a las funcionalidades especializadas de determinadas familias de dispositivos cuando encuentres que estás ejecutando en uno. Este mejor escenario de ambos mundos requiere un poco de trabajo adicional y veremos los detalles de eso más adelante en este tema.
Configuración de la versión de la familia de dispositivos de destino
Las API se agregan a Windows a lo largo del tiempo, por lo que otra dimensión para elegir una familia de dispositivos está decidiendo qué versión (o versiones) de destino. Algunos tipos de proyecto de Visual Studio tienen una página de propiedades en la que puede configurar las versiones de la plataforma de destino. Pero para todos los tipos de proyecto puede configurar las versiones de la plataforma de destino directamente en el archivo del proyecto.
Este es un ejemplo que muestra las propiedades pertinentes en un archivo de proyecto.
<!-- MyProject.Xxxproj -->
<PropertyGroup Label="Globals">
...
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
...
</PropertyGroup>
En tiempo de compilación, estos valores (junto con el valor de TargetDeviceFamily@Name de Package.appxmanifest
) se copian en el archivo que se genera en la AppxManifest.xml
carpeta de salida del proyecto. Este es un ejemplo.
<!-- AppxManifest.xml -->
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal"
MaxVersionTested="10.0.19041.0"
MinVersion="10.0.17134.0" />
...
</Dependencies>
MaxVersionTested especifica la versión máxima de la familia de dispositivos en la que la aplicación tiene como destino que lo ha probado. Y MinVersion especifica la versión mínima de la familia de dispositivos a la que se dirige la aplicación. Para obtener más información, consulte TargetDeviceFamily.
Importante
Debe configurar estos números de versión mediante las páginas de propiedades del proyecto de Visual Studio o los valores de WindowsTargetPlatformVersion y WindowsTargetPlatformMinVersion en el archivo del proyecto. No edite AppxManifest.xml
, porque la compilación sobrescribe ese archivo. Y no edite los atributos MinVersion y MaxVersionTested del elemento TargetDeviceFamily en el archivo de origen del manifiesto del paquete de la aplicación (el Package.appxmanifest
archivo), porque esos valores se omiten.
SDK de extensión y cómo hacer referencia a ellos
Si en el proyecto de Visual Studio cambia el destino de la familia de dispositivos universales a otra familia de dispositivos, debe agregar una referencia al SDK de extensión correspondiente a esa familia de dispositivos. Esto hace que las API de esa familia de dispositivos estén disponibles para el proyecto.
Si, por ejemplo, tiene como destino la familia de dispositivos IoT, (con el nodo del proyecto seleccionado en Explorador de soluciones) haga clic enAgregar referencia delproyecto>...>Windows universal>Extensiones y seleccione la versión adecuada de las extensiones de Windows IoT para UWP. Por ejemplo, si la API de IoT más reciente a la que quiere llamar se introdujo en la versión 10.0.17134.0, seleccione esa versión.
Y así se vería esa referencia en el archivo del proyecto.
<ItemGroup>
<SDKReference Include="WindowsIoT, Version=10.0.17134.0" />
</ItemGroup>
El nombre y el número de versión coinciden con las carpetas de la ubicación de instalación del SDK. Por ejemplo, la información anterior coincide con la carpeta denominada
\Program Files (x86)\Windows Kits\10\Extension SDKs\WindowsIoT\10.0.17134.0
Otros SDK de extensión incluyen extensiones de escritorio de Windows para UWP, Extensiones de Windows Mobile para UWP y Extensiones de equipo de Windows para UWP.
Si dejas la aplicación destinada a la familia de dispositivos universales, puedes agregar una referencia a uno o varios SDK de extensión. Haga referencia a los SDK de extensión que contengan las API adicionales a las que desea llamar. Recuerde que tiene como destino la familia de dispositivos universales, por lo que son las únicas API que puede confiar en estar presente. En el caso de las API de los SDK de extensión a los que se hace referencia, deberá probar que están presentes en el dispositivo host en tiempo de ejecución antes de llamarlos (más detalles en la sección Escribir código más adelante en este tema). Por supuesto, no es necesario realizar esa prueba para las API de la familia de dispositivos universales. Este es el mejor escenario de ambos mundos que mencionamos en la sección anterior.
Mediante el uso de un SDK de extensión, puede tener como destino las API únicas de una familia específica de dispositivos y, por tanto, acceder a sus funcionalidades especializadas. Puede hacerlo tanto si tiene como destino la familia de dispositivos correspondiente como si no.
Contratos de API y cómo buscarlos
Las API de una familia de dispositivos se subdividirán en grupos conocidos como contratos de API. Cuando se publica una nueva versión de una familia de dispositivos, esa nueva versión representa básicamente la colección de nuevas versiones de todos los contratos de API que pertenecen a esa familia de dispositivos.
Por ejemplo, el contrato de API denominado Windows.Foundation.UniversalApiContract
estaba en la versión 6.0 cuando se envió con la versión 10.0.17134.0 de la familia de dispositivos universales. Pero ese mismo contrato estaba en la versión 10.0 cuando se envió con la versión 10.0.19041.0 de esa misma familia de dispositivos.
Búsqueda del contrato de API para una API de WinRT
Veamos cómo puede buscar el nombre del contrato de API y el número de versión de cualquier API de Windows Runtime determinada. En la sección Escribir código más adelante en este tema, verá por qué y cómo podría usar esa información.
Como primer ejemplo, tomaremos el método StorageFolder.TryGetChangeTracker . En la sección de requisitos de Windows 10 de ese tema, podemos ver que StorageFolder.TryGetChangeTracker se introdujo por primera vez con la versión 6.0 de Windows.Foundation.UniversalApiContract
.
A continuación, echemos un vistazo al tema del método StorageFolder.TryGetItemAsync . No hay ninguna sección de requisitos Windows 10 en ese tema. En su lugar, examine el tema de la propia clase StorageFolder . La sección Windows 10 requisitos tiene la respuesta. Dado que el tema StorageFolder.TryGetItemAsync no dice nada diferente, podemos concluir que comparte sus requisitos con su clase primaria. Por lo tanto , StorageFolder.TryGetItemAsync se introdujo por primera vez con la versión 1.0 de Windows.Foundation.UniversalApiContract
.
Cómo elegir una familia de dispositivos de destino
Estas son algunas consideraciones que le ayudarán a decidir qué familia de dispositivos de destino. Para obtener más información, consulte TargetDeviceFamily.
Maximizar el alcance de la aplicación
Para llegar al intervalo máximo de tipos de dispositivos con la aplicación y, por consiguiente, para que se ejecute en tantos dispositivos como sea posible, la aplicación debe tener como destino la familia de dispositivos universales. En concreto, como hemos visto, tendrá como destino una serie de versiones de la familia de dispositivos universales.
Limitar la aplicación a un tipo de dispositivo
Es posible que no quieras que la aplicación se ejecute en una amplia gama de factores de forma de dispositivo; quizás esté especializado para un equipo de escritorio o para una consola Xbox. En ese caso, puede elegir seleccionar como destino una de las familias de dispositivos secundarios.
Limitar la aplicación a un subconjunto de todos los dispositivos posibles
En lugar de establecer como destino la familia de dispositivos universales o una de las familias de dispositivos secundarios, puede dirigirse a dos familias de dispositivos secundarios (o más). Tener como destino escritorio y móvil puede tener sentido para la aplicación. O Escritorio y equipo. O Escritorio, Móvil y Equipo, etc.
Exclusión de la compatibilidad con una versión determinada de una familia de dispositivos
En raras ocasiones, es posible que quieras que la aplicación se ejecute en cualquier lugar , excepto en dispositivos con una versión determinada de una familia de dispositivos determinada. Por ejemplo, supongamos que la aplicación tiene como destino la versión 10.0.x.0 de la familia de dispositivos universales. Cuando la versión del sistema operativo cambie en el futuro (por ejemplo, 10.0.x.2) en ese momento, puedes especificar que la aplicación se ejecute en todas partes excepto la versión 10.0.x.1 de Xbox si tu aplicación se dirige a 10.0.x.0 de Universal y 10.0.x.2 de Xbox. Desde entonces, la aplicación no estará disponible para el conjunto de versiones de la familia de dispositivos en Xbox 10.0.x.1 (inclusive) y versiones anteriores.
Escribir código
Gran parte del código será universal en el sentido de que se ejecutará de la misma manera en todos los dispositivos. Pero para el código adaptado a una familia de dispositivos determinada, tendrá la opción de usar código adaptable. Vamos a considerar estos diferentes casos.
Llamada a una API implementada por la familia de dispositivos de destino
Siempre que quieras llamar a una API en una aplicación para UWP, querrás saber si la familia de dispositivos que tu aplicación tiene como destino o no la API. IntelliSense de Visual Studio muestra las API de la familia de dispositivos universales más las API disponibles para los SDK de extensión a los que se hace referencia.
La documentación de referencia de la API de Windows Runtime indica a qué familia de dispositivos forma parte una API. Si busca el tema de referencia de la API para obtener una API de Windows Runtime y busca la sección requisitos de Windows 10, verá cuál es la familia de dispositivos de implementación y en qué versión de esa familia de dispositivos aparece la API por primera vez. Si no hay ninguna sección de requisitos de Windows 10, examine la clase propietaria del miembro y vea la información de la sección requisitos de Windows 10 allí. Esa información también se aplicará al miembro.
Llamada a una API no implementada por la familia de dispositivos de destino
Habrá casos en los que quiera llamar a una API en un SDK de extensión al que se hace referencia, pero esa API no forma parte de la familia de dispositivos de destino.
Por ejemplo, es posible que tenga como destino la familia de dispositivos universales, pero hay una API de escritorio a la que le gustaría llamar cada vez que la aplicación se ejecuta en un dispositivo de escritorio.
O bien, la aplicación podría admitir versiones anteriores de una familia de dispositivos, pero hay una API a la que quieres llamar que solo está disponible en versiones muy recientes de la misma familia de dispositivos.
En casos como estos, puede optar por escribir código adaptable para que pueda llamar a esas API de forma segura. En la sección siguiente se muestra cómo.
Escritura de código adaptable mediante ApiInformation
Hay dos pasos implicados en el uso del código adaptable para llamar a una API de forma condicional. El primer paso es hacer que la API esté disponible para el proyecto. Para ello, agregue una referencia al SDK de extensión que representa la familia de dispositivos que posee la API.
El segundo paso consiste en usar la clase ApiInformation en una condición del código para probar la presencia de la API a la que desea llamar. Esta condición se evalúa siempre y cuando se ejecute la aplicación. Pero solo se evalúa true
en los dispositivos en los que la API está presente y, por lo tanto, está disponible para llamar.
Si desea llamar a solo un pequeño número de API, puede usar el método ApiInformation.IsTypePresent de esta manera.
// Cache the value, instead of querying it multiple times.
bool isHardwareButtonsAPIPresent =
Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons");
if (isHardwareButtonsAPIPresent)
{
Windows.Phone.UI.Input.HardwareButtons.CameraPressed += HardwareButtons_CameraPressed;
}
En este caso, hay confianza en que la presencia de la clase HardwareButtons implica la presencia del evento CameraPressed , porque la clase y el miembro tienen la misma información de requisitos. Sin embargo, en el tiempo, se agregarán nuevos miembros a clases ya introducidas y esos miembros se habrán introducido más adelante en números de versión. En esos casos, en lugar de usar IsTypePresent, puedes probar la presencia de miembros individuales con IsEventPresent, IsMethodPresent, IsPropertyPresent y métodos similares. Este es un ejemplo.
bool isHardwareButtons_CameraPressedAPIPresent =
Windows.Foundation.Metadata.ApiInformation.IsEventPresent
("Windows.Phone.UI.Input.HardwareButtons", "CameraPressed");
Como sabemos, el conjunto de API dentro de una familia de dispositivos se divide aún más en subdivisiones conocidas como contratos de API. Puedes usar el método ApiInformation.IsApiContractPresent para probar la presencia de un contrato de API. Se trata de una manera eficaz de ejecutar una única condición con el fin de conocer la presencia o, de lo contrario, de un gran número de API que pertenecen a la misma versión de un contrato de API.
Para obtener información sobre cómo determinar el contrato de API que introdujo primero las API de interés, consulte la sección Búsqueda del contrato de API para una API de WinRT anteriormente en este tema.
Una vez que tenga esa información, puede conectarla al código adaptable. Por ejemplo, si el nombre del contrato de API es Windows.Devices.Scanners.ScannerDeviceContract
, y sus números de versión principal y secundaria son 1 y 0, respectivamente, la condición tendrá un aspecto similar al del ejemplo siguiente.
bool isWindows_Devices_Scanners_ScannerDeviceContract_1_0Present =
Windows.Foundation.Metadata.ApiInformation.IsApiContractPresent
("Windows.Devices.Scanners.ScannerDeviceContract", 1, 0);
Vista previa de la interfaz de usuario en diferentes tamaños de pantalla
Te recomendamos que maximices el alcance de la aplicación. Pero incluso si solo tienes como destino un tipo de factor de forma de dispositivo, es probable que haya diferentes tamaños de pantalla en los que tu aplicación pueda acabar apareciendo.
Cuando esté listo para ver el aspecto de la aplicación y diseñar en un tamaño determinado de pantalla, use la barra de herramientas de vista previa del dispositivo en Visual Studio para obtener una vista previa de la interfaz de usuario en un dispositivo móvil pequeño o mediano, en un equipo o en una pantalla de TV grande. De este modo, si has usado las características de diseño adaptable de XAML (consulta Diseños adaptables con estados visuales y desencadenadores de estado), también puedes probarlo.
No tiene que tomar una decisión de antemano sobre cada tipo de dispositivo que admita. Puede agregar un tamaño de dispositivo adicional al proyecto en cualquier momento.