¿Puede crear bibliotecas dinámicas para iOS y cargarlas en tiempo de ejecución?

114

¿Las bibliotecas dinámicas son compatibles con iOS (iPhone / iPad)?

En Xcode, intenté crear un nuevo proyecto -> Framework & Library -> Cocoa Library (dinámico) . En la configuración del proyecto, que establezca el SDK base a iOS device 4.1meta y para iOS4.1, pero tiene un error de compilación:

target especifica el tipo de producto 'com.apple.product-type.library.dynamic', pero no existe tal tipo de producto para la plataforma 'iphonesimulator' ".

La compilación que seleccioné es Simulador -> Depurar -> i386 .

usuario510951
fuente
4
iOS8 + admite marcos basados ​​en biblioteca compartida.
eonil
1
@Eonil, ¿puedes dar más detalles sobre eso? Me gustaría saber más al respecto, agradecería mucho un artículo o un enlace a alguna información.
Maxim Chetrusca

Respuestas:

105

En el momento en que se hizo esta pregunta, las bibliotecas dinámicas no eran compatibles con iOS y provocarán el rechazo de su aplicación. Solo se permiten bibliotecas estáticas.

Sin embargo, en iOS8 puede usar bibliotecas y marcos dinámicos. Debería "simplemente funcionar"

DarkDust
fuente
14
¿Alguien sabe por qué es eso? A mí me parece completamente una locura.
Erik de Castro Lopo
73
@Erik de Castro Lopo: La razón es la seguridad: dado que una biblioteca dinámica puede cargarse y descargarse en tiempo de ejecución, puede descargar código ejecutable adicional y cargarlo (piense en un complemento). Esto podría verse comprometido por un pirata informático y luego tener un código malicioso ejecutándose en su teléfono es algo muy malo. También permitiría agregar funciones no aprobadas a una aplicación aprobada. En resumen: en este entorno, Apple considera que la vinculación dinámica es una caja de Pandora que debe controlarse estrictamente, de lo contrario podría comprometer la seguridad y estoy de acuerdo en que tiene sentido en el teléfono .
DarkDust
6
Estoy desarrollando una aplicación interna que no se distribuirá a través de AppStore, por lo que no me importan las restricciones de Apple para AppStore. ¿Es técnicamente posible crear una biblioteca dinámica para la aplicación iOS?
Aliaksei
3
@Aliaksei: Técnicamente sí, o de lo contrario no podría vincular a las bibliotecas de Apple. El soporte de la biblioteca dinámica AFAIK es aproximadamente el mismo que en Mac OS X. Sin embargo, Xcode no lo admite, pero parece que puede usar paquetes. Vea este artículo .
DarkDust
3
No admitido no es lo mismo que no permitido.
dtech
162

No estoy en desacuerdo con la respuesta de DarkDust , pero si se me permite canalizar mi interior Bill Clinton, que depende de cuál es el significado de la soportado es :)

Apple no quiere que hagas esto para las aplicaciones de la App Store, pero el sistema operativo ciertamente lo permite. Las aplicaciones de Jailbreak utilizan esta técnica todo el tiempo. Básicamente, usa una técnica UNIX estándar para abrir dinámicamente un marco / biblioteca y luego usa cosas en él. La función dlopen le permite abrir la biblioteca pasando la ruta a ese marco , o dylib. De algunos documentos para crear aplicaciones de jailbreak , aquí hay un ejemplo de init()cómo llamar a una función implementada dentro de su propio dylib separado:

#include <dlfcn.h>

initWrapper() {
    char *dylibPath = "/Applications/myapp.app/mydylib2.dylib";

    void *libHandle = dlopen(dylibPath, RTLD_NOW);
    if (libHandle != NULL) {
        // This assumes your dylib’s init function is called init, 
        //    if not change the name in "".
        void (*init)() = dlsym(libHandle, "init");
        if (init != NULL)  {
            init();
        }
        dlclose(libHandle);
    }
}

Además, la restricción predeterminada que no le permite crear un proyecto de biblioteca dinámica para iOS es algo en Xcode que tiene la capacidad de anular editando algunos archivos xml de XCode:

Compila y usa dylib en iOS

Una vez que haga esto, puede crear una biblioteca .dylib de iOS normal y usarla según el código de muestra anterior. (sí, probablemente tendrá que desbloquear esta capacidad nuevamente cada vez que instale una nueva versión de XCode).

Entonces, no es una limitación técnica, sino una limitación de la política de la App Store. Si no está limitado a la App Store, puede hacerlo. Tenga en cuenta que esta técnica no requiere jailbreak, aunque si la aplicación está en un espacio aislado, puede limitar desde dónde se pueden cargar los dylibs.

Editar: para asegurarse de que esta información no se pierda en el futuro enlace rot, aquí está el contenido del enlace que proporcioné sobre cómo habilitar iOS dylibs en Xcode. ( Nota: este proceso todavía funciona en Xcode 4, pero consulte los comentarios a continuación para obtener actualizaciones de las rutas, etc.) La fuente es el blog de iOS Place :


Xcode no le permite crear dylib para iOS. La aplicación será rechazada si no es un binario único. Pero tengo una aplicación que tiene una arquitectura de complementos para cargar módulos opcionales. Solo quiero un prototipo rápido para probar el concepto antes de portarlo completamente a iOS. Es más rápido hacerlo si dylib simplemente pudiera funcionar. Por lo tanto, esta publicación muestra cómo compilar y usar dylib, pero tenga en cuenta que no se aprobará en App Store. (Probado con Xcode 3.2.4 en 10.6.4)

1. Abra estos archivos en el Editor de lista de propiedades: /Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspec y /Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications / iPhone Simulator ProductTypes.xcspec

2. Localice el elemento en “ MacOSX Product Types.xcspec ” que tiene el tipo de producto com.apple.product-type.library.dynamicy arrástrelo al “ iPhone Simulator ProductTypes.xcspec ”.

Captura de pantalla 1 de Xcode

3. Abra “ MacOSX Package Types.xcspec ” y “ iPhone Simulator PackageTypes.xcspec ” que se encuentran en los mismos lugares.

4. Busque el elemento en el " MacOSX Product Types.xcspec " que tiene el tipo de paquete com.apple.package-type.mach-o-dyliby arrástrelo al " iPhone Simulator PackageTypes.xcspec ".

Captura de pantalla 2 de Xcode

5. Repita los pasos para " iPhoneOS.platform " y reinicie Xcode si se estaba ejecutando.

Ahora, construyamos un dylib. Comience con la plantilla " Biblioteca estática de Cocoa Touch ". Eso debería incluir el marco Foundation.framework en el proyecto. Estos son los cambios que hice en la parte superior de la plantilla para construir dylib.

1. Abra el archivo project.pbxproj (que se encuentra dentro del paquete de archivos del proyecto Xcode) en un editor de texto. Busque la cadena " producttype ", cambie su valor a com.apple.product-type.library.dynamic;

Ahora, abra el proyecto con Xcode, vaya a Proyecto-> Editar configuración del proyecto

2. " Directorio de instalación " configurado en @executable_path/porque planeo colocar el dylib en el mismo directorio que el ejecutable de la aplicación.

3. " Tipo de Mach-O " establecido en Biblioteca dinámica

4. " Extensión ejecutable " establecida en dylib

5. " Prefijo ejecutable " configurado en vacío

6. Agregue uno o dos métodos simples a la biblioteca y constrúyalos.

Ahora, cree una aplicación para probarla. Esta vez, elijo la aplicación basada en vistas . Conecte un UIButton y un UILabel para llamar a la biblioteca y mostrar un mensaje de retorno. Puedes descargar el proyecto completo TestApp y jugar con él.

Nate
fuente
2
A partir de XCode 4.5, estos archivos se pueden encontrar en (ej.) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications
Chris Devereux
@ChrisDevereux, ¡gracias! Puse una nota para verificar su comentario en busca de rutas actualizadas ... que, por supuesto, podrían cambiar nuevamente en una versión futura :)
Nate
3
Esta respuesta necesita más votos positivos (y realmente debería ser la respuesta aceptada, pero dudo que user510951 vuelva después de estar fuera de SO durante 2 años). Muy buena respuesta Nate!
chown
1
Debería haber algún tipo de anulación maestra en la que si @chown dice que una respuesta es correcta ... es malditamente correcta.
Tim
@Panagiotis, publique una nueva pregunta para que se pueda abordar correctamente. Muestra el código que estás usando y todos los mensajes de error. Si lo desea, puede también vincular de nuevo a esta pregunta / respuesta. Si agrega la etiqueta "iphone-privateapi", la veré. Debe indicar que esto no es para la tienda de aplicaciones, o las personas pueden votar para cerrar la pregunta.
Nate
0

A partir de Xcode 11.4.1 no se permiten bibliotecas dinámicas (su proyecto no se compilará para todos los destinos). La nueva forma de usar libs / frameworks es create-xcframework de xcodebuild.

Carla Camargo
fuente