Ich habe mehrere Posts gesehen, die dieses Thema in Bezug auf iOS ansprechen, aber die ein oder andere Erwähnung von OS X sagt nur, dass man ein Framework anstelle einer statischen Bibliothek erstellen sollte. (Ich kann den Beitrag, der anständige Rahmenanweisungen hatte, nicht finden.)
Ich habe mein Projekt als statische Bibliothek erstellt und das Ganze entsprechend codiert. Jetzt möchte ich einfach mein Framework in eine Demo-App einfügen und es beschwert sich über eine fehlende Spitze. Als Notlösung habe ich die Feder in das Elternprojekt kopiert, aber ich möchte die ganze Sache richtig aufteilen.
Was ist der beste Ansatz?
Bearbeiten:
Für Kontext: Ich habe eine Feder erstellt, um ein NSWindowController
in einer Mac-App zu initialisieren.
Nein, das ist nicht möglich, weil eine statische Bibliothek nicht dasselbe ist wie ein "Bündel".
Eine statische Bibliothek ist eine einzelne Datei, die Klassen, Code und Variablen enthält, die vom Ersteller der Bibliothek miteinander verknüpft wurden. Es enthält keine anderen Dateien, es ist im Wesentlichen eine Datenbank mit kompiliertem Code. Obwohl es möglich wäre, die Daten für die XIBs dort zu platzieren, hätte Xcode keine Möglichkeit zu wissen, dass es dort war, da es nach einzelnen Dateien auf dem Dateisystem sucht.
Option 1: (nicht gut)
Behalten Sie einfach die XIB mit der statischen Bibliothek mit einer README-Datei mit Anweisungen bei. Eine Art dummer Weg, aber es ist schnell und nicht schrecklich, da du schon alles hast.
Option 2: (ziemlich gut)
Sie können ein "Framework" erstellen, bei dem es sich im Wesentlichen um ein Bündel von Code, Ressourcen, Einstellungen usw. handelt, das von mehreren Projekten wiederverwendet werden kann.
Apple Doc für Framework: Ссылка
Zufälliger Leitfaden für OS X Frameworks: (Es ist mit einer älteren Version von Xcode, aber es ist das gleiche Konzept) Ссылка
[UPDATE 1] Beachten Sie, dass dies nicht mit iOS funktioniert, da Frameworks in App-Bundles nicht von den App Store-Regeln zugelassen werden. (Dynamisch geladener Code ist sowieso nicht). [Kredit an @nielsbot, die mich in Kommentaren daran erinnern.]
[UPDATE 2] Lesen Sie mehr über iOS 8, sie haben in dieser Hinsicht vieles verändert. (Kann wegen der Apple NDA nicht darüber sprechen)
Ok, ich habe mir die Zeit genommen, eine Probe zusammenzustellen, wie Sie das machen können. Es basiert auf @ TomSwifts Antwort und diesem: Ссылка
Ich habe hier ein Beispielprojekt hochgeladen: Ссылка
Sie fügen Ihrem statischen Bibliotheksziel eine benutzerdefinierte Regel für XIB-Dateien hinzu. Es fügt eine Klassenmethode für NSNib
ein, die Ihre XIB bei jedem Aufruf instanziiert. Die Methode ist der Name Ihres XIB. Wenn Sie also "TestNib.xib" haben, würden Sie +[NSNib TestNib]
aufrufen.
Ausführlicher:
Fügen Sie einen benutzerdefinierten Compiler für XIB-Dateien hinzu (Dies ist wirklich nur ein bisschen Shell-Skript, das wir für jede XIB-Datei im Projekt ausführen wollen)
a) Geben Sie in Ihren statischen lib-Erstellungsregeln "XIB" in das Suchfeld ein und klicken Sie auf die Schaltfläche "In Ziel kopieren", um eine XIB-Dateiregel in Ihrem Projekt zu erstellen.
b) lassen Sie Process als "Interface Builder Dateien", setzen Sie Using auf "Custom script:" Hier ist das benutzerdefinierte Skript:
%Vor%Dadurch werden Ihre XIB-Dateien in .m-Dateien umgewandelt, die automatisch in Ihr Projekt kompiliert werden. Die Vorlage ist CompiledNibTemplate.m, die wie folgt aussieht:
%Vor% Wenn Ihr XIB nach dem obigen Beispiel "StaticLibraryWindowController.xib" hieß, wird NSNib
nun eine neue Klassenmethode StaticLibraryWindowController
haben. ) Wenn [ NSNib StaticLibraryWindowController ]
aufgerufen wird, wird ein NSNib
-Objekt zurückgegeben. Sie können -instantiateWithOwner:topLevelObjects:
wie jedes andere Nib-Handle aufrufen)
Konvertieren Sie Ihre Schreibfeder einfach in eine objektive C-Klasse: Ссылка
Dann schließe das wie deine andere Quelle ein *
* Nie getan, aber in der Theorie sollte es funktionieren, oder?
Wie bereits erwähnt, ist es nicht möglich, eine NIB-Datei mit einer statischen Bibliothek auf die gleiche Weise zu bündeln, wie Sie eine Nib mit einem Framework bündeln. Eine statische Bibliothek enthält nur kompilierten Code. Es ist kein Container für eine Sammlung von Code und anderen Ressourcen.
Wenn Sie das ernst meinen, haben Sie eine Option, die den gleichen Effekt hat. Im Grunde wird base64 die nib in eine Zeichenkette codieren und zur Laufzeit neu erstellen. Hier ist mein Rezept:
1) kompilieren Sie Ihre .xib in binäre .nib-Form. Verwenden Sie XCode oder ibtool .
2) Verwenden Sie ein Tool, um Ihre .nib als base64-Text zu codieren. Unter OSX können Sie dazu openssl
vom Terminal aus verwenden:
3) Kopieren Sie die Base64-Zeichenfolge in eine Ihrer Quelldateien. Konstruiere einen NSString daraus:
%Vor%4) schreibe Code, um die Base64-Zeichenfolge in ein NSData:
zu dekodieren %Vor%5) Konstruiere eine UINib aus dem NSData:
%Vor%6) Verwenden Sie Ihre Feder:
%Vor% Nun müssen Sie möglicherweise einige Dinge in Ihrem Code ändern. Wenn Sie View-Controller aus Nibs mit init
oder initWithNibName:bundle:
erstellen, wird das nicht "nur funktionieren". Warum? Weil diese Mechanismen in einem Bündel (in der Regel das App-Bundle) für die Spitze aussehen und Ihre Spitze nicht da sein wird. Sie können jedoch alle View-Controller in Ihrem Code so anpassen, dass sie von Ihrer gerade neu erstellten UINib geladen werden. Hier ist ein Link, der einen Prozess dafür beschreibt: Ссылка
Sie können schnell feststellen, dass Sie zusätzlich zu Ihrer .nib weitere Ressourcen für Ihren Code benötigen. Z.B. Bilder. Sie können den gleichen Ansatz verwenden, um Bilder oder andere Ressourcen in Ihre statische Bibliothek einzubetten.
Meiner Meinung nach sind die Entwicklerkosten des Workflows, die erforderlich sind, um diese eingebettete Schreibspitze auf dem neuesten Stand zu halten, ziemlich hoch. Wenn ich es wäre, würde ich einfach ein Framework erstellen und das verteilen.
Tags und Links xcode macos frameworks libraries