Können Sie dynamische Bibliotheken für iOS erstellen und zur Laufzeit laden?

114

Werden dynamische Bibliotheken unter iOS (iPhone / iPad) unterstützt?

In Xcode habe ich versucht, ein neues Projekt zu erstellen -> Framework & Library -> Cocoa Library (dynamisch) . In den Projekteinstellungen habe ich das Basis-SDK auf iOS device 4.1und das Ziel auf festgelegt iOS4.1, aber es hat einen Erstellungsfehler:

Ziel gibt den Produkttyp 'com.apple.product-type.library.dynamic' an, aber es gibt keinen solchen Produkttyp für die 'iphonesimulator'-Plattform ".

Der Build, den ich ausgewählt habe, ist Simulator -> Debug -> i386 .

user510951
quelle
4
iOS8 + unterstützt Frameworks, die auf einer gemeinsam genutzten Bibliothek basieren.
Eonil
1
@Eonil, kannst du das näher erläutern? Ich würde gerne mehr darüber erfahren, ein Artikel oder ein Link zu einigen Informationen wäre sehr dankbar.
Maxim Chetrusca

Antworten:

105

Zum Zeitpunkt der Beantwortung dieser Frage wurden dynamische Bibliotheken von iOS nicht unterstützt und führen dazu, dass Ihre App abgelehnt wird. Es sind nur statische Bibliotheken zulässig.

In iOS8 können Sie jedoch dynamische Bibliotheken und Frameworks verwenden. Es sollte "einfach funktionieren"

DarkDust
quelle
14
Weiß jemand warum das so ist? Für mich scheint es einfach völlig verrückt zu sein.
Erik de Castro Lopo
73
@Erik de Castro Lopo: Der Grund ist die Sicherheit: Da eine dynamische Bibliothek zur Laufzeit geladen und entladen werden kann, können Sie zusätzlichen ausführbaren Code herunterladen und laden (siehe Plug-In). Dies könnte von einem Hacker kompromittiert werden und es ist eine sehr schlechte Sache, wenn bösartiger Code auf Ihrem Telefon ausgeführt wird. Es würde auch ermöglichen, einer genehmigten App nicht genehmigte Funktionen hinzuzufügen. Kurz gesagt: In dieser Umgebung betrachtet Apple die dynamische Verknüpfung als eine Pandoras-Box, die streng kontrolliert werden muss, da sie sonst die Sicherheit gefährden könnte, und ich stimme zu, dass dies auf dem Telefon sinnvoll ist .
DarkDust
6
Ich entwickle eine interne App, die nicht über den AppStore verteilt wird. Daher sind mir die Einschränkungen von Apple für den AppStore egal. Ist es technisch möglich, eine dynamische Bibliothek für die iOS-App zu erstellen?
Aliaksei
3
@Aliaksei: Technisch gesehen ja, sonst könnten Sie keine Links zu Apples Bibliotheken erstellen. Die Unterstützung für dynamische AFAIK-Bibliotheken entspricht in etwa der von Mac OS X. Xcode unterstützt sie jedoch nicht, es scheint jedoch, dass Sie Bundles verwenden können. Siehe diesen Artikel .
DarkDust
3
Nicht unterstützt ist nicht dasselbe wie nicht erlaubt.
dtech
162

Ich bin mit DarkDusts Antwort nicht wirklich einverstanden , aber wenn ich meinen inneren Bill Clinton kanalisieren darf, hängt es davon ab, was die Bedeutung von unterstützt ist :)

Apple möchte nicht, dass Sie dies für App Store-Apps tun, aber das Betriebssystem erlaubt dies auf jeden Fall. Jailbreak-Apps verwenden diese Technik ständig. Grundsätzlich verwenden Sie eine Standard-UNIX-Technik, um ein Framework / eine Bibliothek dynamisch zu öffnen und dann Inhalte darin zu verwenden. Mit der Funktion dlopen können Sie die Bibliothek öffnen, indem Sie den Pfad zu diesem Framework oder dylib übergeben. In einigen Dokumenten zum Erstellen von Jailbreak-Apps finden Sie hier ein Beispiel für den Aufruf einer init()Funktion, die in Ihrer eigenen, separaten Dylib implementiert ist:

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

Darüber hinaus ist die Standardeinschränkung, dass Sie kein dynamisches Bibliotheksprojekt für iOS erstellen dürfen , in Xcode enthalten, die Sie durch Bearbeiten einiger XCode-XML-Dateien überschreiben können:

Erstellen und verwenden Sie Dylib unter iOS

Sobald Sie dies getan haben, können Sie eine normale iOS .dylib- Bibliothek erstellen und diese gemäß dem obigen Beispielcode verwenden. (Ja, Sie müssen diese Funktion wahrscheinlich erneut entsperren, wenn Sie eine neue XCode-Version installieren.)

Es handelt sich also nicht um eine technische Einschränkung, sondern um eine Einschränkung der App Store-Richtlinien. Wenn Sie nicht auf den App Store beschränkt sind, können Sie dies tun. Beachten Sie, dass diese Technik nicht nicht Jailbreak erforderlich, obwohl , wenn die App Sandbox ist es begrenzen kann , wo dylibs aus geladen werden kann.

Bearbeiten: Um sicherzustellen, dass diese Informationen nicht für zukünftige Linkfäule verloren gehen, finden Sie hier den Inhalt des Links, den ich zum Aktivieren von iOS-Dylibs in Xcode bereitgestellt habe. ( Hinweis: Dieser Vorgang funktioniert weiterhin mit Xcode 4, Aktualisierungen der Pfade usw. finden Sie in den Kommentaren unten.) Quelle ist das iOS Place-Blog :


Mit Xcode können Sie keine Dylib für iOS erstellen. App wird abgelehnt, wenn es sich nicht um eine einzelne Binärdatei handelt. Ich habe jedoch eine Anwendung mit Plug-In-Architektur zum Laden optionaler Module. Ich möchte nur, dass ein schneller Prototyp das Konzept beweist, bevor er vollständig auf iOS portiert wird. Es ist schneller, wenn Dylib einfach funktionieren könnte. In diesem Beitrag wird gezeigt, wie Dylib erstellt und verwendet wird. Beachten Sie jedoch, dass es nicht für den App Store zugelassen wird. (Getestet mit Xcode 3.2.4 am 10.6.4)

1. Öffnen Sie diese Dateien im Eigenschaftenlisten-Editor: /Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Specifications/MacOSX Product Types.xcspec und /Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications / iPhone Simulator ProductTypes.xcspec

2. Suchen Sie das Element in der Datei " MacOSX Product Types.xcspec " mit dem Produkttyp com.apple.product-type.library.dynamicund ziehen Sie es in die " iPhone Simulator ProductTypes.xcspec ".

Xcode Screenshot 1

3. Öffnen Sie " MacOSX Package Types.xcspec " und " iPhone Simulator PackageTypes.xcspec " an denselben Stellen.

4. Suchen Sie das Element in der Datei " MacOSX Product Types.xcspec " mit dem Pakettyp com.apple.package-type.mach-o-dylibund ziehen Sie es in die Datei " iPhone Simulator PackageTypes.xcspec ".

Xcode Screenshot 2

5. Wiederholen Sie die Schritte für die „ iPhoneOS.platform “ und starten Sie Xcode neu, falls es ausgeführt wurde.

Lassen Sie uns nun eine Dylib bauen. Beginnen Sie mit der Vorlage „ Cocoa Touch Static Library “. Das sollte das Foundation.framework in das Projekt einbeziehen. Hier sind die Änderungen, die ich über der Vorlage vorgenommen habe, um Dylib zu erstellen.

1. Öffnen Sie die Datei project.pbxproj (im Xcode-Projektdateibündel enthalten) in einem Texteditor. Suchen Sie nach der Zeichenfolge " producttype " und ändern Sie den Wert in com.apple.product-type.library.dynamic;

Öffnen Sie nun das Projekt mit Xcode und gehen Sie zu Projekt-> Projekteinstellungen bearbeiten

2. " Installationsverzeichnis " wurde auf gesetzt, @executable_path/da ich die Dylib im selben Verzeichnis wie die ausführbare Datei der App ablegen möchte.

3.Mach-O Type ” auf Dynamic Library eingestellt

4. " Executable Extension " auf dylib gesetzt

5. " Ausführbares Präfix " auf leer gesetzt

6. Fügen Sie der Bibliothek eine oder zwei einfache Methoden hinzu und erstellen Sie sie.

Erstellen Sie jetzt eine App, um sie zu testen. Dieses Mal wähle ich die ansichtsbasierte Anwendung . Schließen Sie einen UIButton und ein UILabel an, um die lib aufzurufen und die Rückmeldung anzuzeigen. Sie können das komplette Projekt TestApp herunterladen und damit spielen.

Nate
quelle
2
Ab XCode 4.5 finden Sie diese Dateien unter (z. B.) /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications
Chris Devereux
@ ChrisDevereux, danke! Ich habe eine Notiz eingefügt, um Ihren Kommentar auf aktuelle Pfade zu überprüfen ... was sich in einer zukünftigen Version natürlich wieder ändern könnte :)
Nate
3
Diese Antwort benötigt mehr Upvotes (und sollte wirklich die akzeptierte Antwort sein, aber ich bezweifle, dass user510951 zurück sein wird, nachdem er 2 Jahre von SO entfernt war). Sehr schöne Antwort Nate!
Chown
1
Es sollte eine Art Master-Override geben, bei der @chown sagt, dass eine Antwort richtig ist ... es ist verdammt gut richtig.
Tim
@Panagiotis, bitte poste eine neue Frage, damit dies richtig angesprochen werden kann. Zeigen Sie den von Ihnen verwendeten Code und alle Fehlermeldungen an. Wenn Sie möchten, können Sie auch auf diese Frage / Antwort zurückgreifen. Wenn Sie das Tag "iphone-privateapi" hinzufügen, wird es angezeigt. Sie sollten angeben, dass dies nicht für den App Store gilt. Andernfalls können Personen abstimmen, um die Frage zu schließen.
Nate
0

Ab Xcode 11.4.1 sind dynamische Bibliotheken nicht zulässig (Ihr Projekt wird nicht für alle Ziele kompiliert). Die neue Art, libs / Frameworks zu verwenden, ist das create-xcframework von xcodebuild.

Carla Camargo
quelle