Pouvez-vous créer des bibliothèques dynamiques pour iOS et les charger au moment de l'exécution?

114

Les bibliothèques dynamiques sont-elles prises en charge sur iOS (iPhone / iPad)?

Dans Xcode, j'ai essayé de créer un nouveau projet -> Framework & Library -> Cocoa Library (dynamique) . Dans les paramètres du projet, j'ai défini le SDK de base sur iOS device 4.1et la cible sur iOS4.1, mais il y a une erreur de construction:

target spécifie le type de produit 'com.apple.product-type.library.dynamic', mais il n'existe pas de type de produit pour la plate-forme 'iphonesimulator' ».

La version que j'ai sélectionnée est Simulator -> Debug -> i386 .

user510951
la source
4
iOS8 + prend en charge les frameworks basés sur une bibliothèque partagée.
eonil
1
@Eonil, pouvez-vous nous en dire plus? J'aimerais en savoir plus, un article ou un lien vers des informations serait très apprécié.
Maxim Chetrusca

Réponses:

105

Au moment où cette question a été posée, les bibliothèques dynamiques n'étaient pas prises en charge par iOS et entraîneront le rejet de votre application. Seules les bibliothèques statiques sont autorisées.

Cependant, dans iOS8, vous pouvez utiliser des bibliothèques et des frameworks dynamiques. Cela devrait "juste fonctionner"

DarkDust
la source
14
Quelqu'un sait-il pourquoi? Pour moi, cela me semble complètement insensé.
Erik de Castro Lopo
73
@Erik de Castro Lopo: La raison est la sécurité: puisqu'une bibliothèque dynamique peut être chargée et déchargée au moment de l'exécution, vous pouvez télécharger du code exécutable supplémentaire et le charger (pensez plug-in). Cela pourrait être compromis par un pirate informatique et exécuter un code malveillant sur votre téléphone est une très mauvaise chose. Cela permettrait également d'ajouter des fonctionnalités non approuvées à une application approuvée. En bref: dans cet environnement, Apple considère que le lien dynamique est une boîte Pandoras qui doit être strictement contrôlée, sinon cela pourrait compromettre la sécurité et je conviens que cela a du sens sur le téléphone .
DarkDust
6
Je développe une application en interne qui ne sera pas distribuée via l'AppStore, donc je me fiche des restrictions d'Apple pour l'AppStore. Est-il techniquement possible de créer une bibliothèque dynamique pour l'application iOS?
Aliaksei le
3
@Aliaksei: Techniquement oui, sinon vous ne seriez pas en mesure de créer un lien vers les bibliothèques Apple. La prise en charge de la bibliothèque dynamique AFAIK est à peu près la même que sur Mac OS X. Cependant, Xcode ne la prend pas en charge, mais il semble que vous puissiez utiliser des bundles. Consultez cet article .
DarkDust
3
Non pris en charge n'est pas la même chose que non autorisé.
dtech
162

Je ne conteste pas vraiment avec la réponse de DarkDust , mais si je peux canaliser mon intérieur Bill Clinton, cela dépend de ce que le sens de prise en charge est :)

Apple ne veut pas que vous fassiez cela pour les applications de l'App Store, mais le système d'exploitation le permet certainement. Les applications de jailbreak utilisent cette technique tout le temps. Vous utilisez essentiellement une technique UNIX standard pour ouvrir dynamiquement un framework / bibliothèque, puis utilisez des éléments dedans. La fonction dlopen vous permet d'ouvrir la bibliothèque en passant le chemin vers ce framework , ou dylib. À partir de certains documents sur la création d'applications de jailbreak , voici un exemple d'appel d'une init()fonction implémentée dans votre propre dylib distinct:

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

De plus, la restriction par défaut qui vous permet de créer un projet de bibliothèque dynamique pour iOS est quelque chose dans Xcode que vous avez la possibilité de remplacer en modifiant certains fichiers xml XCode:

Construire et utiliser dylib sur iOS

Une fois que vous faites cela, vous pouvez créer une bibliothèque iOS .dylib normale et l'utiliser selon l'exemple de code ci-dessus. (oui, vous devrez probablement déverrouiller à nouveau cette fonctionnalité chaque fois que vous installerez une nouvelle version de XCode).

Ce n'est donc pas une limitation technique, mais une limitation de la politique de l'App Store. Si vous n'êtes pas limité à l'App Store, vous pouvez le faire. Notez que cette technique ne nécessite pas de jailbreaker, bien que si l'application est en bac à sable, elle peut limiter l' emplacement à partir duquel les dylibs peuvent être chargés.

Edit: afin de vous assurer que ces informations ne seront pas perdues lors de la pourriture future du lien, voici le contenu du lien que j'ai fourni sur la façon d'activer les dylibs iOS dans Xcode. ( Remarque: ce processus fonctionne toujours sur Xcode 4, mais voir le (s) commentaire (s) ci-dessous pour les mises à jour des chemins, etc.) La source est le blog iOS Place :


Xcode ne vous permet pas de créer dylib pour iOS. L'application sera rejetée s'il ne s'agit pas d'un binaire unique. Mais j'ai une application qui a une architecture plug-in pour charger des modules optionnels. Je veux juste un prototype rapide pour prouver le concept avant de le porter complètement sur iOS. C'est plus rapide à faire si dylib pouvait simplement fonctionner. Donc, cet article montre comment créer et utiliser dylib, mais sachez qu'il ne sera pas approuvé sur l'App Store. (Testé avec Xcode 3.2.4 sur 10.6.4)

1. Ouvrez ces fichiers dans l'éditeur de liste de propriétés: /Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspec et /Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications / iPhone Simulator ProductTypes.xcspec

2. Localisez l'élément dans « MacOSX Product Types.xcspec » qui contient le type de produit com.apple.product-type.library.dynamicet faites-le glisser vers « iPhone Simulator ProductTypes.xcspec ».

Capture d'écran Xcode 1

3. Ouvrez « MacOSX Package Types.xcspec » et « iPhone Simulator PackageTypes.xcspec » qui se trouvent aux mêmes endroits.

4. Localisez l'élément dans « MacOSX Product Types.xcspec » qui a le type de package com.apple.package-type.mach-o-dylibet faites-le glisser vers « iPhone Simulator PackageTypes.xcspec ».

Capture d'écran Xcode 2

5. Répétez les étapes pour « iPhoneOS.platform » et relancez Xcode s'il était en cours d'exécution.

Maintenant, construisons un dylib. Commencez avec le modèle « Cocoa Touch Static Library ». Cela devrait inclure le cadre Foundation.fr dans le projet. Voici les modifications que j'ai apportées au-dessus du modèle pour créer dylib.

1. Ouvrez le fichier project.pbxproj (qui se trouve dans le lot de fichiers de projet Xcode) dans un éditeur de texte. Recherchez la chaîne " producttype ", remplacez sa valeur par com.apple.product-type.library.dynamic;

Maintenant, ouvrez le projet avec Xcode, allez dans Projet-> Modifier les paramètres du projet

2. « Répertoire d'installation » défini sur @executable_path/parce que je prévois de placer le dylib dans le même répertoire que l'exécutable de l'application.

3. « Mach-O Type » défini sur Dynamic Library

4. « Extension exécutable » définie sur dylib

5. « Préfixe exécutable » défini sur vide

6. Ajoutez une ou deux méthodes simples à la bibliothèque et créez-la.

Maintenant, créez une application pour la tester. Cette fois, je choisis l' application basée sur la vue . Connectez un UIButton et un UILabel pour appeler la lib et afficher le message de retour. Vous pouvez télécharger le projet complet TestApp et jouer avec.

Nate
la source
2
Depuis XCode 4.5, ces fichiers peuvent être trouvés à (par exemple) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications
Chris Devereux
@ChrisDevereux, merci! J'ai mis une note pour vérifier votre commentaire pour les chemins à jour ... qui bien sûr, pourraient changer à nouveau dans une version future :)
Nate
3
Cette réponse a besoin de plus de votes positifs (et devrait vraiment être la réponse acceptée, mais je doute que user510951 soit de retour après avoir été absent du SO pendant 2 ans). Très belle réponse Nate!
chown
1
Il devrait y avoir une sorte de remplacement principal où si @chown dit qu'une réponse est correcte ... c'est très bien correct.
Tim
@Panagiotis, veuillez poster une nouvelle question afin qu'elle puisse être traitée correctement. Affichez le code que vous utilisez et tous les messages d'erreur. Si vous le souhaitez, vous pouvez également créer un lien vers cette question / réponse. Si vous ajoutez la balise "iphone-privateapi", je la verrai. Vous devez indiquer que ce n'est pas pour l'App Store, sinon les gens peuvent voter pour fermer la question.
Nate
0

À partir de Xcode 11.4.1, les bibliothèques dynamiques ne sont pas autorisées (votre projet ne sera pas compilé pour toutes les destinations). La nouvelle façon d'utiliser les libs / frameworks est le create-xcframework de xcodebuild.

Carla Camargo
la source