Mejores prácticas para aplicaciones iOS

Cuando desarrolles aplicaciones iOS, usa estas mejores prácticas para mejorar la compatibilidad entre Citrix Endpoint Management™ y las aplicaciones móviles para dispositivos iOS.

MDX App SDK Framework y empaquetado

Si tu aplicación usa el MDX App SDK Framework, entonces debes usar la versión correspondiente de MDX Toolkit para el empaquetado. Una falta de coincidencia de versiones entre estos dos componentes podría causar un funcionamiento incorrecto.

Para evitar tal falta de coincidencia, empaqueta la aplicación como una aplicación ISV y especifica un modo de aplicación Premium o General. Esto te permite entregar una aplicación preempaquetada. Como resultado, tu cliente no necesita empaquetar la aplicación, evitando así el uso de un MDX Toolkit no coincidente. Para obtener detalles sobre el empaquetado ISV, consulta Empaquetado de aplicaciones móviles iOS.

Usa ID de aplicación explícitos

Si tu cuenta de iOS Developer Enterprise no admite ID de aplicación con comodines, asegúrate de crear un ID de aplicación explícito para cada aplicación que planees empaquetar con el MDX Toolkit. Además, crea un perfil de aprovisionamiento para cada ID de aplicación.

  • No bloquees el hilo principal

No uses código de bloqueo cuando se ejecute en el hilo principal. Esta es una directriz de Apple, pero es aún más crucial con Citrix Endpoint Management. Algunas acciones pueden tardar más en una aplicación administrada o pueden bloquear la ejecución posterior del hilo. Las operaciones de archivo, base de datos y red son ejemplos de operaciones que podrían bloquear el hilo que se está ejecutando actualmente y deben evitarse en el hilo principal.

  • Escribe código robusto

  • En particular, debes escribir aplicaciones siguiendo las mejores prácticas documentadas en las guías de programación de Apple, como la Guía de programación de aplicaciones de Apple.

  • Usa solo interfaces publicadas por Apple

  • Verifica los valores de retorno de todas las llamadas a la API y maneja cualquier excepción que pueda ocurrir como efecto secundario de una llamada a la API. Este esfuerzo garantiza una recuperación de errores elegante o una terminación elegante de la aplicación. Si bien esta es una práctica común de programación, es especialmente importante para las aplicaciones administradas.

  • Varias API que esperarías que funcionaran fallan si la funcionalidad subyacente ha sido bloqueada debido a las políticas de Citrix Endpoint Management. Los ejemplos incluirían cualquiera de las capacidades descritas anteriormente:

  • Las API de red fallan como si no hubiera red disponible.
  • Las API de sensores, como GPS y cámara, devuelven nulo o lanzan una excepción.

Los siguientes selectores de tiempo de ejecución de Objective-C devuelven nil si la funcionalidad subyacente ha sido bloqueada debido a las políticas de Citrix Endpoint Management y, por lo tanto, deben manejarse en consecuencia.

Clase de objeto: AVCaptureDevice

  • Nombre del selector: devicesWithMediaType:

Clase de objeto: MFMailComposeViewController

  • Nombre del selector: init:

  • Clase de objeto: MFMessageComposeViewController

  • Nombre del selector: initWithNibName:bundle:

Clase de objeto: NSFileManager

  • Nombre del selector: URLForUbiquityContainerIdentifier:

Clase de objeto: NSUbiquitousKeyValueStore

  • Nombre del selector: defaultStore:

Clase de objeto: PHPhotoLibrary

  • Nombre del selector: sharedPhotoLibrary:

Clase de objeto: UIImagePickerController

  • Nombre del selector: availableCaptureModesForCameraDevice:

Clase de objeto: UIPasteboard

  • Nombre del selector:

    dataForPasteboardType:

  • valueForPasteboardType:

  • items:

    dataForPasteboardType:inItemSet:

    valuesForPasteboardType:inItemSet:

Clase de objeto: UIPopoverController

  • Nombre del selector: initWithContentViewController:

Clase de objeto: UINavigationController

  • Nombre del selector:

    ctxInitWithRootViewController:

    ctxPopToViewController:animated:

Redirigir interfaces de tiempo de ejecución

Citrix Endpoint Management proporciona interacción con el aviso de PIN de la interfaz de usuario para que no tengas que hacerlo en tu aplicación.

Para garantizar la preparación de Citrix Endpoint Management, te sugerimos que no redirijas ni sustituyas los selectores de tiempo de ejecución de Objective-C. La razón es que Citrix Endpoint Management “swizzles” (modifica dinámicamente) los métodos subyacentes de varios selectores de clase de objeto para controlar o modificar el comportamiento en tiempo de ejecución de una aplicación. La siguiente tabla enumera los selectores de clase de Objective-C que Citrix Endpoint Management redirige:

  • Nombre de la clase de objeto: NSURLProtectionSpace

  • Nombre del selector: serverTrust

Nombre de la clase de objeto: NSURLAuthenticationChallenge

  • Nombre del selector: sender

Nombre de la clase de objeto: NSURLConnection

  • Nombre del selector:

    sendSynchronousRequest:returningResponse:error:

    initWithRequest:delegate:startImmediately:

    initWithRequest:delegate:

    connectionWithRequest:delegate:

Nombre de la clase de objeto: NSURLConnectionDelegate

  • Nombre del selector:

    connection:canAuthenticateAgainstProtectionSpace:

    connection:didReceiveAuthenticationChallenge:

    connection:willSendRequestForAuthenticationChallenge:

Nombre de la clase de objeto: NSURLSessionConfiguration

  • Nombre del selector:

    defaultSessionConfiguration

    ephemeralSessionConfiguration

Nombre de la clase de objeto: ALAssetsLibrary

  • Nombre del selector: authorizationStatus

  • Nombre de la clase de objeto: AVAudioRecorder

  • Nombre del selector:

  • record

    prepareToRecord

    recordForDuration:

recordAtTime:

recordAtTime:ForDuration:

  • Nombre de la clase de objeto: AVAudioSession

  • Nombre del selector: recordPermission

  • Nombre de la clase de objeto: AVCaptureDevice

  • Nombre del selector:

    devices

    devicesWithMediaType:

Nombre de la clase de objeto: AVAsset

  • Nombre del selector: assetWithURL:

Nombre de la clase de objeto: AVURLAsset

  • Nombre del selector:

    initWithURL:options:

    URLAssetWithURL:options:

Nombre de la clase de objeto: AVPlayerItem

  • Nombre del selector:

    playerItemWithAsset:

    initWithURL:

    playerItemWithURL:

Nombre de la clase de objeto: AVPlayer

  • Nombre del selector:

    playerWithPlayerItem:

    initWithPlayerItem:

    initWithURL:

Nombre de la clase de objeto: CLLocationManager

  • Nombre del selector: startUpdatingLocation

  • Nombre de la clase de objeto: UIScrollView

  • Nombre del selector: setContentOffset:

Nombre de la clase de objeto: MFMailComposeViewController

  • Nombre del selector:

  • canSendMail

    init

Nombre de la clase de objeto: MFMessageComposeViewController

  • Nombre del selector:

    canSendText

    initWithNibName:bundle:

Nombre de la clase de objeto: NSFileManager

  • Nombre del selector: URLForUbiquityContainerIdentifier:

Nombre de la clase de objeto: NSUbiquitousKeyValueStore

  • Nombre del selector: defaultStore

Nombre de la clase de objeto: PHPhotoLibrary

  • Nombre del selector: authorizationStatus

Nombre de la clase de objeto: QLPreviewController

  • Nombre del selector:

    setDataSource:

    canPreviewItem:

Nombre de la clase de objeto: QLPreviewControllerDataSource

  • Nombre del selector:

    numberOfPreviewItemsInPreviewController:

  • previewController:previewItemAtIndex:

  • Nombre de la clase de objeto: SLComposeViewController

  • Nombre del selector: isAvailableForServiceType:

  • Nombre de la clase de objeto: UIActivityViewController

  • Nombre del selector:

  • initWithActivityItems:applicationActivities:

  • setExcludedActivityTypes:

    • Nombre de la clase de objeto: UIApplication
  • Nombre del selector:

    • openURL:

    • canOpenURL:

    • setApplicationIconBadgeNumber:

    • Nombre de la clase de objeto: UIDocument

    • Nombre del selector:

    • closeWithCompletionHandler:

    • contentsForType:error:

    • Nombre de la clase de objeto: UIDocumentInteractionController

    • Nombre del selector:

    interactionControllerWithURL:

    • setURL:

    • setDelegate:

    presentPreviewAnimated:

    presentOpenInMenuFromBarButtonItem:animated:

    • presentOpenInMenuFromRect:inView:animated:

    • presentOptionsMenuFromBarButtonItem:animated:

    presentOptionsMenuFromRect:inView:animated:

    • Nombre de la clase de objeto: UIDocumentMenuViewController

    • Nombre del selector: initWithDocumentTypes:inMode:

Nombre de la clase de objeto: UIImage

-  **Nombre del selector:** imageNamed:

Nombre de la clase de objeto: UIImagePickerController

-  **Nombre del selector:** setSourceType:

takePicture

-  startVideoCapture
  • isSourceTypeAvailable:

  • isCameraDeviceAvailable:

    isFlashAvailableForCameraDevice:

  • availableCaptureModesForCameraDevice:

  • setMediaTypes

Nombre de la clase de objeto: UINavigationController

  • Nombre del selector:

  • ctxInitWithRootViewController:

    ctxPushViewController:animated:

    ctxPopToViewController:animated:

Nombre de la clase de objeto: UIPasteboard

  • Nombre del selector:

    generalPasteboard

    pasteboardWithName:create:

    pasteboardWithUniqueName

    setValue:forPasteboardType:

    setData:forPasteboardType:

    setItems:

    addItems:

    dataForPasteboardType:

    valueForPasteboardType:

    numberOfItems

    pasteboardTypes

    pasteboardTypesForItemSet:

    containsPasteboardTypes:

    containsPasteboardTypes:inItemSet:

    items

    itemSetWithPasteboardTypes:

    dataForPasteboardType:inItemSet:

    valuesForPasteboardType:inItemSet:

    string

    strings

    URL

    URLs

    image

    images

    color

    colors

Nombre de la clase de objeto: UIPopoverController

  • Nombre del selector: initWithContentViewController

Nombre de la clase de objeto: UIPrintInteractionController

  • Nombre del selector:

    isPrintingAvailable

    presentAnimated:completionHandler:

    presentFromBarButtonItem:animated:completionHandler:

    presentFromRect:inView:animated:completionHandler:

Nombre de la clase de objeto: UIViewController

  • Nombre del selector: presentViewController:animated:completion:

Nombre de la clase de objeto: UIWebView

  • Nombre del selector:

    loadRequest:

    setDelegate:

    UIWebViewDelegate

    webView:shouldStartLoadWithRequest:navigationType:

    webViewDidStartLoad:

    webViewDidFinishLoad:

    webView:didFailLoadWithError:

Nombre de la clase de objeto: UIWindow

  • Nombre del selector: makeKeyAndVisible

Nombre de la clase de objeto: UIApplicationDelegate

  • Nombre del selector:

    applicationDidFinishLaunching:

    application:didFinishLaunchingWithOptions:

    application:willFinishLaunchingWithOptions:

    applicationWillResignActive:

    applicationDidEnterBackground:

    applicationWillEnterBackground:

    applicationDidBecomeActive:

    applicationWillTerminate:

    application:openURL:sourceApplication:annotation:

    application:handleOpenURL:

    applicationProtectedDataWillBecomeUnavailable:

    applicationProtectedDataDidBecomeAvailable:

    application:performFetchWithCompletionHandler:

    application:handleEventsForBackgroundURLSession:completionHandler:

    application:didReceiveLocalNotification:

    application:didReceiveRemoteNotification:

    application:didReceiveRemoteNotification:fetchCompletionHandler:

    application:didRegisterForRemoteNotificationsWithDeviceToken:

    application:didFailToRegisterForRemoteNotificationsWithError:

    applicationSignificantTimeChange:

    application:shouldAllowExtensionPointIdentifier:

Nombre de la clase de objeto: QLPreviewController

  • Nombre del selector: allocWithZone:

Asegurar la compatibilidad con el cifrado de datos

Una de las características principales de MDX es que todos los datos persistentes se cifran de forma transparente. No necesitas modificar tu aplicación para obtener esta funcionalidad y, de hecho, no puedes evitarla directamente. El administrador de Citrix Endpoint Management puede deshabilitar el cifrado de forma selectiva o total, pero no la aplicación.

Este es uno de los aspectos más complejos de MDX y requiere comprender los siguientes puntos:

  • El cifrado de archivos está presente para todo el código nativo que se ejecuta en procesos gestionados.

    La implementación del cifrado de datos de archivos admite todo el código nativo y no solo el código de las aplicaciones que usan los frameworks de Apple y el tiempo de ejecución de Apple Objective-C. Cualquier cifrado de datos de archivos implementado dentro y únicamente para el tiempo de ejecución de Objective-C puede ser subvertido fácilmente.

  • Algunas API de framework, como la clase AVPlayer, la clase UIWebView y QLPreviewController, son implementadas por procesos de servicio de iOS en un contexto de ejecución diferente al proceso de la aplicación gestionada del usuario.

    Estos procesos de servicio no pueden descifrar los datos de archivos cifrados de MDX. Por lo tanto, la aplicación gestionada debe proporcionar al proceso de servicio una copia temporal sin cifrar de los datos. La aplicación gestionada elimina la copia después de 5 segundos. Es importante que seas consciente de esta limitación al usar estas clases. La razón es que perdemos el control de contención de los datos proporcionados a estas clases debido a la implementación de Apple de las clases específicas.

  • La asignación de memoria es problemática para el cifrado de Citrix Endpoint Management, ya que depende de que la aplicación llame a las interfaces de llamadas al sistema de E/S de archivos.

    Después de que un archivo se asigna en memoria, las solicitudes de E/S para el archivo se gestionan fuera del contexto de la aplicación del usuario, eludiendo el cifrado de Citrix Endpoint Management. Todas las llamadas POSIX mmap(2) de una aplicación gestionada se asignan como MAP_PRIVATE y MAP_ANON y no se asocian con ninguna descripción de archivo. Se intenta leer todos los datos asignados durante la llamada mmap si se especifica una descripción de archivo para cargar todos los datos, ya que cualquier paginación posterior de datos por parte del sistema operativo resulta en la lectura de datos cifrados sin que Citrix Endpoint Management los descifre. Esta técnica ha tenido éxito en todas las aplicaciones probadas con Citrix Endpoint Management, ya que la cantidad de datos asignados en memoria es pequeña y no se producen recuperaciones de páginas de memoria dentro de la aplicación.

  • El cifrado añade una sobrecarga medible. Los desarrolladores deben optimizar la E/S de disco para evitar la degradación del rendimiento. Por ejemplo, si estás leyendo y escribiendo repetidamente la misma información, podrías querer implementar una caché a nivel de aplicación.

  • Citrix Endpoint Management solo cifra instancias de la libsqlite.dylib de Apple. Si la aplicación se vincula directamente con y/o incrusta una versión privada de la libsqlite.dylib, las instancias de bases de datos de esa biblioteca privada no son cifradas por Citrix Endpoint Management.

  • Las bases de datos SQLite de Apple son cifradas por Citrix Endpoint Management usando la capa del sistema de archivos virtual de SQLite.

    El rendimiento puede ser un problema. El tamaño estándar de la caché de la base de datos es de 2000 páginas u 8 megabytes. Si tu base de datos es grande, un desarrollador podría necesitar especificar un pragma de SQLite para aumentar el tamaño de la caché de la base de datos. En el framework Objective-C Core Data, el pragma de SQLite se puede agregar como un diccionario de opciones al agregar el objeto de almacén persistente al objeto de controlador de almacén persistente.

  • El modo WAL de SQLite no es compatible, ya que la biblioteca se revincula a las interfaces de E/S de archivos y utiliza internamente la asignación de memoria de forma extensiva.

  • NSURLCache DiskCache es implementado por iOS usando una base de datos SQLite. Citrix Endpoint Management deshabilita la caché de disco asociada, ya que esta base de datos es referenciada por procesos de servicio de iOS no gestionados.

  • La siguiente es una lista de los patrones de nombres de rutas de archivo excluidas codificadas:

    • .plist: Excluido debido al acceso de los procesos del sistema iOS fuera del contexto del proceso.
    • .app: Subcadena heredada en el nombre del paquete de la aplicación. Esta subcadena está obsoleta porque ahora se excluye una ruta explícita del paquete de la aplicación.
    • .db: Un archivo con este sufijo no se cifra si el archivo no es una base de datos SQLite.
    • /System/Library: Las rutas de archivo que existen dentro del directorio sandbox del paquete de la aplicación y las rutas de archivo fuera del sandbox de datos de la aplicación no se pueden cifrar. En iOS, la aplicación instalada es de solo lectura y está en un directorio diferente al de los archivos de datos de la aplicación que esta produce y almacena cuando se ejecuta.
    • Library/Preferences: iOS accede directamente a los archivos. Normalmente, solo los archivos .plist están presentes en esta ruta de directorio.
    • /com.apple.opengl/: iOS accede directamente a los archivos.
    • csdk.db: Base de datos SQLite heredada de Citrix SSLSDK
    • /Library/csdk.sql: Base de datos SQLite de Citrix SSLSDK
    • CtxLog_: Prefijo del nombre de archivo de registro de Citrix®
    • CitrixMAM.config: Nombre de archivo interno de MDX
    • CitrixMAM.traceLog: Nombre de archivo interno de MDX heredado
    • CtxMAM.log: Nombre de archivo interno de MDX
    • data.999: Nombre de archivo interno de MDX
    • CTXWrapperPersistentData: Nombre de archivo interno de MDX
    • /Documents/CitrixLogs: Directorio de registros de MDX
    • /Document/CitrixLogs.zip: Nombre del directorio de registros de MDX comprimido
    • Cualquier archivo en la ruta del directorio del paquete de la aplicación: Directorio de solo lectura de archivos de la aplicación
  • Citrix Endpoint Management sustituye una instancia de la clase privada Citrix Endpoint Management SecureViewController por instancias de la clase de objeto Apple Objective-C QLPreviewController en tiempo de ejecución. La clase Citrix Endpoint Management SecureViewController se deriva de la clase de objeto Apple Objective-C UIWebView. La clase de objeto QLPreviewController admite de forma nativa algunos formatos de archivo que la clase de objeto UIWebView no admite de forma nativa, como los tipos de audio y PDF.

  • Para un mejor rendimiento, las solicitudes de E/S de archivos deben emitirse a desplazamientos de archivo que sean un múltiplo de 4096 bytes y deben emitirse para una longitud que también sea un múltiplo de 4096 bytes.

  • El indicador de modo de archivo O_NONBLOCK no es compatible con el cifrado de Citrix Endpoint Management. Este indicador de modo de archivo se elimina de la lista de modos cuando es procesado por Citrix Endpoint Management.

Entropía de usuario de cifrado

Una opción de Citrix Endpoint Management para el cifrado requiere que el usuario final introduzca un PIN antes de que se pueda generar la clave de cifrado. Esta opción se llama entropía de usuario. Puede causar un problema particular para las aplicaciones.

Específicamente, no se puede realizar ningún acceso a archivos o bases de datos hasta que el usuario introduzca un PIN. Si una operación de E/S de este tipo está presente en una ubicación que se ejecuta antes de que se pueda mostrar la interfaz de usuario del PIN, siempre fallará.

Para asegurarte de que este problema no esté presente en tu aplicación, prueba con la entropía de usuario habilitada. La propiedad de cliente de Citrix Endpoint Management, “Cifrar secretos con código de acceso”, añade entropía de usuario. Puedes configurar esa propiedad de cliente, que está deshabilitada por defecto, en la consola de Citrix Endpoint Management en Configurar > Ajustes > Más > Propiedades de cliente.

Compatibilidad de contención de datos

  • Cualquier controlador de vista remota no tendrá contención de seguridad (por ejemplo, cifrado de datos; bloqueo de políticas de copiar, cortar y pegar; etc.) porque un controlador de vista remota se ejecuta en un contexto de proceso diferente al de la aplicación administrada por MDX.
  • La acción de Copiar es la única compatible desde UIResponder. Otras acciones, como Cortar y Eliminar, no son compatibles.
  • AirDrop solo se intercepta a nivel de interfaz de usuario (UI), no a un nivel inferior.
  • MFI y Bluetooth no se interceptan.

Compatibilidad con archivos de icono

El empaquetado MDX requiere la presencia de al menos un icono que pueda usarse como icono de la pantalla de inicio o icono de la aplicación. Los desarrolladores de aplicaciones pueden agregar sus iconos al Catálogo de activos, o usar las claves CFBundleIcons o CFBundleIconFiles en Info.plist.

El MDX Toolkit elige el primero de la lista de ubicaciones plist conocidas en Info.plist:

  • CFBundleIcons
  • CFBundlePrimaryIcon
  • CFBundleIconFiles
  • UINewsstandIcon
  • CFBundleDocumentTypes

Si no se encuentra ninguna de esas claves en Info.plist, el MDX Toolkit identificará uno de los siguientes iconos en la carpeta raíz del paquete de la aplicación:

  • Icon.png
  • Icon-60@2x.png
  • Icon-72.png
  • Icon-76.png

Redes y micro VPN

Actualmente, MDX solo gestiona las llamadas de red emitidas directamente por una aplicación. Algunas consultas DNS son emitidas directamente por el framework de Apple y, por lo tanto, no son gestionadas por MDX.

Hay varias opciones de política de Citrix Endpoint Management disponibles para los administradores en cuanto a redes.

La política de acceso a la red previene, permite o redirige la actividad de red de la aplicación.

Importante:

La versión 18.12.0 del MDX Toolkit incluyó nuevas políticas que combinaron o reemplazaron políticas anteriores. La política de Acceso a la red combina Acceso a la red, Modo VPN preferido y Permitir cambio de modo VPN. La política de Lista de exclusión reemplaza a la Lista de exclusión de túnel dividido. La política de Sesión micro VPN requerida reemplaza a Sesión en línea requerida. Para obtener más detalles, consulta Novedades de versiones anteriores.

“Tunelizado - SSO web” es el nombre de “Navegación segura” en los ajustes. El comportamiento es el mismo.

Las opciones son las siguientes:

  • Usar configuración anterior: Por defecto, utiliza los valores que habías establecido en las políticas anteriores. Si cambias esta opción, no deberías volver a Usar configuración anterior. Ten en cuenta también que los cambios en las nuevas políticas no surten efecto hasta que el usuario actualice la aplicación a la versión 18.12.0 o posterior.
  • Bloqueado: Las API de red utilizadas por tu aplicación fallarán. Según la directriz anterior, deberías gestionar este fallo de forma elegante.
  • Sin restricciones: Todas las llamadas de red van directamente y no se tunelizan.
  • Tunelizado - VPN completa: Todo el tráfico de la aplicación administrada se tuneliza a través de Citrix Gateway.
  • Tunelizado - SSO web: La URL HTTP/HTTPS se reescribe. Esta opción solo permite el tunelizado del tráfico HTTP y HTTPS. Una ventaja significativa de Tunelizado - SSO web es el inicio de sesión único (SSO) para el tráfico HTTP y HTTPS, y también la autenticación PKINIT. En Android, esta opción tiene una baja sobrecarga de configuración y, por lo tanto, es la opción preferida para operaciones de navegación web.
  • Tunelizado - VPN completa y SSO web: Permite cambiar entre modos VPN automáticamente según sea necesario. Si una solicitud de red falla debido a una solicitud de autenticación que no se puede manejar en un modo VPN específico, se reintenta en un modo alternativo.

Limitaciones

  • Los usuarios no pueden reproducir vídeos alojados en sitios web internos en aplicaciones MDX empaquetadas para iOS porque los vídeos se reproducen en un proceso de reproductor multimedia en el dispositivo que MDX no intercepta.
  • La descarga en segundo plano de NSURLSession (NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier) no es compatible.
  • Bloqueamos el tráfico UDP si la política de acceso a la red está configurada como Bloqueado. No tunelizamos el tráfico UDP si la política de acceso a la red está configurada como Tunelizado - VPN completa.
  • Las aplicaciones empaquetadas con MDX no pueden instanciar un servidor de sockets que escuche las conexiones entrantes. Sin embargo, las aplicaciones empaquetadas con MDX pueden usar un socket de cliente para conectarse a un servidor.

Compatibilidad con bibliotecas de terceros

Algunos frameworks de aplicaciones tienen problemas de compatibilidad con Citrix Endpoint Management:

  • Las aplicaciones desarrolladas con el entorno de desarrollo multiplataforma Xamarin son compatibles. Citrix no declara oficialmente la compatibilidad con otros entornos de desarrollo multiplataforma debido a la insuficiencia de ejemplos de uso y pruebas.
  • SQLCipher no funciona con el cifrado porque utiliza la asignación de memoria. Una solución es no usar SQLCipher. Una segunda solución es excluir el archivo de la base de datos del cifrado utilizando una política de exclusión de cifrado. Un administrador de Citrix Endpoint Management debe configurar la política en la consola de Citrix Endpoint Management.
  • Las aplicaciones y bibliotecas de terceros que se vinculan directamente a las bibliotecas libcrypto.a y libssl.a de OpenSSL pueden provocar un error de vinculación debido a símbolos faltantes y errores de vinculación debido a la definición de múltiples símbolos.
  • Las aplicaciones que requieren compatibilidad con el Servicio de notificaciones push de Apple deben seguir los pasos específicos que Apple exige.
  • Citrix Endpoint Management establece explícitamente la versión de la base de datos SQLite en 1 para deshabilitar el archivo de registro de escritura anticipada (WAL) y la compatibilidad con archivos asignados en memoria dentro de las bases de datos SQLite. Cualquier intento de acceder directamente a las interfaces de SQLite en la versión 2 o 3 de SQLite fallará.