Erstellen von iOS / OSX-Frameworks: Ist es erforderlich, diese vor der Verteilung an andere Entwickler zu codieren?

89

Ich lerne, wie man iOS- und OSX-Frameworks erstellt. Nehmen wir zum Beispiel iOS. Die folgenden Schritte funktionieren bisher für mich:

  1. xcodebuild Framework mit -sdk iphonesimulator und Build-Aktion
  2. xcodebuild Framework mit -sdk iphoneos und Build-Aktion
  3. Verwenden Sie das Lipo-Tool, um eine universelle Binärdatei zu erstellen, die lipo -infoFolgendes erwartet:

Architekturen in der Fat-Datei: Foo.framework / Foo sind: i386 x86_64 armv7 arm64

Die Fragen sind:

  1. Ich habe gelesen, dass mein Framework von einem Entwickler, der es verwendet, neu signiert werden kann: "Code Sign on Copy", aber ich verstehe nicht, was die Voraussetzungen dafür sind, dh sollte ich einen Codesign-Schritt hinzufügen, um diese universelle Binärdatei mit meiner Signaturidentität zuvor zu codieren an andere Entwickler verteilen?

  2. Wenn die vorherige Bewertung positiv ist, reicht es aus, wenn ich meine Identität "iPhone Distribution: ..." oder "iPhone Developer: ..." verwende (damit mein Framework, das Teil eines iOS-Projekts ist, alle Arten von Validierungen besteht, insbesondere die App Store-Validierung )?.

Hintergrund für meine Antwort ist der "CodeSign-Fehler: Für den Produkttyp 'Framework' in SDK 'iOS 8.3' ist eine Codesignatur erforderlich", den ich in einer Reihe von Frameworks von Drittanbietern gesehen habe, und Karthago # 235 oder "Codeobjekt ist nicht signiert überhaupt "(ein Beispiel: Problem, über das ich in Realm # 1998 berichtet habe .

Daher möchte ich sicherstellen, dass Benutzer meiner Frameworks bei ihrer Verwendung keine Probleme mit der Codesignierung haben.

PS Diese Frage wird noch interessanter, wenn sie nicht auf einen einzelnen Entwickler, sondern auf eine Organisation angewendet wird, die ein Framework-Anbieter ist.

Stanislav Pankevich
quelle
In diesem Kommentar wird die Verwendung von "CODE_SIGN_IDENTITY = iPhone Developer" vorgeschlagen. Es ist jedoch nicht klar, warum "Developer" anstelle von "iPhone Distribution" verwendet wird.
Stanislav Pankevich
Verwandte Themen: App mit eingebettetem Framework exportieren, aber ohne eindeutige Antwort.
Stanislav Pankevich
Ich habe diese Frage auch in den Apple Developer Forums getäuscht: forums.developer.apple.com/thread/6400 .
Stanislav Pankevich
Ich habe eine Frage, wenn Sie Ihr Framework verteilen, Sie einen Debug-Build oder Release-Build verteilen? und wenn Sie es in Release Build verteilen, wie geht das?
Niczm25
@ niczm25, das ist eine Möglichkeit, wie ich es mache: stanislaw.github.io/2015/11/23/… .
Stanislav Pankevich

Antworten:

132

Ich öffnete das Kopfgeld: "Auf der Suche nach einer Antwort aus glaubwürdigen und / oder offiziellen Quellen." habe aber seitdem keine mehr erhalten.

Die Antwort von @jackslash ist zwar korrekt, erzählt aber nur einen Teil der Geschichte. Daher möchte ich meine eigene so schreiben, wie ich es gerne gesehen hätte, als ich diese Frage gestellt habe.

Die Aktualität dieser Antwort lautet: Juli 2015. Es ist sehr wahrscheinlich, dass sich die Dinge ändern werden.

Lassen Sie uns zunächst behaupten, dass die für die korrekte Codesignatur des Frameworks erforderlichen Aktionen in Schritte unterteilt werden müssen, die der Entwickler des Frameworks ausführen muss, und in Schritte, die der Consumer des Frameworks ausführen muss.

TLDR;

Für das OSX-Framework: Es steht dem Entwickler frei, das OSX-Framework zu verteilen, ohne es zu codieren, da Consumer es ohnehin neu codiert.

Für iOS-Framework: Es steht dem Entwickler frei, das iOS-Framework zu verteilen, ohne es zu codieren, da der Verbraucher es trotzdem neu codiert. Der Entwickler wird jedoch von Xcode gezwungen, sein Framework beim Erstellen für iOS-Geräte zu codieren.

Aufgrund des Radars: "iOS-Frameworks, die Simulator-Slices enthalten, können nicht an den App Store gesendet werden" Consumer of iOS-Framework muss ein spezielles Skript wie "copy_frameworks" oder "strip_frameworks" ausführen, mit lipo -removedem Simulator-Slices vom iOS-Framework entfernt und erneut entfernt werden -Codesigns entfernt das Framework, da zu diesem Zeitpunkt seine Codesign-Identität, was auch immer es war (oder nicht war), als Nebeneffekt der lipo -removeManipulation entfernt wird.

Eine längere Antwort folgt.


Diese Antwort ist keine "Zeichnung aus glaubwürdigen und / oder offiziellen Quellen", sondern basiert auf einer Reihe empirischer Beobachtungen.

Empirische Beobachtung Nr. 1: Der Verbraucher kümmert sich nicht darum, weil er das vom Entwickler erhaltene Framework neu codiert

Binäre Framework-Distributionen bekannter Open-Source-Projekte auf Github sind nicht mit einem Code versehen . Der Befehl codesign -d -vvvvgibt an: "Codeobjekt ist überhaupt nicht signiert" auf allen binären iOS- und OSX-Frameworks, die ich untersucht habe. Einige Beispiele: ReactiveCocoa and Mantle , Realm , PromiseKit .

Aus dieser Beobachtung geht hervor, dass die Autoren dieser Frameworks beabsichtigen, sie vom Verbraucher mit einem Code zu signieren, dh ein Verbraucher muss entweder das Flag "Code Sign on Copy" in der von Xcode bereitgestellten Erstellungsphase "Frameworks einbetten" verwenden oder eine benutzerdefinierte Shell verwenden Skript, das dasselbe manuell ausführt: Codesigns Framework im Namen des Verbrauchers.

Ich habe kein einziges Beispiel für das Gegenteil gefunden: ein Open-Source-Framework, das mit einer Codesignatur-Identität verteilt wird. In der restlichen Antwort gehe ich von diesem weit verbreiteten Ansatz als richtig aus: Es besteht keine Notwendigkeit für Framework-Entwickler Verteilen Sie ihr Framework an andere Entwickler mit darin enthaltener Codesignatur, da Consumer es ohnehin neu codiert .

Empirische Beobachtung Nr. 2, die nur für iOS gilt und ausschließlich dem Entwickler ein Anliegen ist

Während es dem Verbraucher egal ist, ob das vom Entwickler erhaltene Framework mit einem Codesign versehen ist oder nicht, muss der Entwickler sein iOS-Framework im Rahmen seines Erstellungsprozesses beim Erstellen für ein iOS-Gerät mit einem Codesign versehen, da Xcode sonst nicht erstellt : CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'. Um Justin Spahr-Summers zu zitieren :

OS X-Frameworks müssen beim Erstellen nicht codiert werden ... Leider erfordert Xcode, dass iOS-Frameworks beim Erstellen codiert werden.

Dies beantwortet meine Frage Nr. 2 ziemlich gut: Die Identität des "iPhone-Entwicklers" reicht aus, um Xcode so zu beschwichtigen, dass ein iOS-Framework für das Gerät erstellt wird. Dieser Kommentar zu Karthago # 339 sagt dasselbe.

Empirische Beobachtung Nr. 3: Lipo-Tool

Spezifisches Verhalten des Lipo-Tools: Wenn es auf die Framework-Binärdatei angewendet wird, werden immer rekursiv alle Codesign-Identitäten daraus entfernt : lipo -create/-remove codesigned framework ... -> not codesigned framework.

Dies könnte eine Antwort sein, warum alle Beispiele in Beobachtung Nr. 1 überhaupt nicht mit einem Code versehen sind: Ihre Identität mit dem Code wird nach dem Auftragen von Lipo weggeblasen, aber laut Beobachtung Nr. 1 ist es dem Verbraucher egal, ob es in Ordnung ist.

Diese Beobachtung ist besonders relevant für die nächste Beobachtung Nr. 4 über AppStore.

Empirische Beobachtung Nr. 4: iOS-Frameworks mit Simulator-Slices können nicht an den App Store gesendet werden

Dies wird ausführlich diskutiert in: Realm # 1163 und Carthage # 188 und Radar wird geöffnet: rdar: // 19209161 .

Dies ist ganz und gar das Anliegen des Verbrauchers: Für das universelle iOS-Framework, das der Verbraucher in seine Anwendung einbezieht, muss er beim Erstellen einer Anwendung ein spezielles Skript (benutzerdefinierte Skriptphase ausführen) ausführen, mit dem das Simulator-Slice aus der Binärdatei dieses Frameworks entfernt wird, damit die App die AppStore-Validierung bestehen kann.

Das gute Beispiel für binäre Frameworks, das ich in Realm gefunden habe: strip-frameworks.sh .

Es wird verwendet lipo, um alle ${VALID_ARCHS}Teile von Architekturen außer zu entfernen und sie dann mit der Identität des Verbrauchers neu zu codieren. Hier setzt Beobachtung Nr. 3 an: Das Framework muss aufgrund von Lipo-Manipulationen neu codiert werden.

Karthago verfügt über das Skript CopyFrameworks.swift, das für alle von Consumer enthaltenen Frameworks dasselbe bewirkt: Es entfernt die Simulator-Slices und signiert das Framework im Auftrag von Consumer neu.

Es gibt auch einen guten Artikel: Entfernen unerwünschter Architekturen aus dynamischen Bibliotheken in Xcode .


Nun die Übersicht über die Schritte, die erforderlich sind, um sowohl iOS als auch OSX aus Sicht von Entwicklern und Verbrauchern zu erstellen. Zuerst das einfachere:

OSX

Entwickler:

  1. Erstellt das OSX-Framework
  2. Gibt es dem Verbraucher

Vom Entwickler sind keine Codesignierungsaktivitäten erforderlich.

Verbraucher:

  1. Erhält das OSX-Framework vom Entwickler
  2. Kopiert das Framework in das Frameworks / -Verzeichnis und signiert es automatisch im Namen des Verbrauchers im Rahmen des Prozesses "Code Sign on Copy".

iOS

Entwickler:

  1. Erstellt ein iOS-Framework für das Gerät. Für Xcode ist eine Codesignierung erforderlich. Die Identität des "iPhone-Entwicklers" reicht aus.
  2. Erstellt ein iOS-Framework für den Simulator.
  3. Verwendet Lipo, das ein universelles iOS-Framework aus den beiden vorherigen erstellt. Zu diesem Zeitpunkt geht die Codesignaturidentität von 1 Schritt verloren: Universal Framework Binary "ist überhaupt nicht signiert", aber das ist in Ordnung, da "Consumer ist das egal".
  4. Gibt es dem Verbraucher

Verbraucher:

  1. Erhält das iOS-Framework vom Entwickler
  2. Kopiert das Framework in das Frameworks / Verzeichnis (dieser Schritt kann redundant sein, je nachdem, welches Skript in Schritt 3 verwendet wird.)
  3. Verwendet ein spezielles Skript als Teil des Erstellungsprozesses: Dieses Skript entfernt Simulator-Slices vom iOS-Framework und signiert es dann im Namen des Verbrauchers neu.
Stanislav Pankevich
quelle
9
Dies ist eine wertvolle Zusammenfassung. Schön
Jackslash
@ Stanislaw danke für die Erkenntnisse und die wertvollen Daten. Während ich ein Framework schreibe, das ich selbst für Entwickler entworfen habe, möchte ich, dass sie das Framework so wie es ist verwenden können, ohne ein spezielles Skript erstellen zu müssen, um es in den App Store hochzuladen. Ich denke, GoogleMobileAd funktioniert so. aber Sie sagen, sie müssen ein bestimmtes Skript ausführen? Sie haben eine Idee, wie GoogleMobileAds das nicht benötigt? danke
Michael A
@ MichaelA, das ist in der Tat interessant. Ich werde schauen.
Stanislav Pankevich
Können Sie mir einen Link zu GoogleMobileAds geben, die Sie verwenden?
Stanislav Pankevich
1
Danke, dass du mir Zeit gespart hast, das hat bei mir funktioniert. Xcode 7.3, Mac OS X 10.11.4.
Eugen
20

Nach dem Lesen des verknüpften Threads auf dem Karthago-Repo scheint es relativ einfach zu sein. Wenn Sie das binäre Framework verteilen, müssen Sie es mit einem Code signieren, und wenn Sie die Quelle über Karthago oder Kakaofrüchte verteilen, tun Sie dies nicht, da diese Tools dies über verschiedene Methoden erledigen.

Der Grund, warum Sie es beim Verteilen des binären Frameworks mit Code signieren müssen, ist, dass Xcode ohne Code-Signatur keine Framework-Binärdatei erzeugt. Wenn Sie versuchen, das binäre Framework nicht mit Code zu signieren, wird folgende Fehlermeldung angezeigt:

CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'

Es spielt keine Rolle, mit welcher Identität Sie das Framework mit einem Code signieren (iPhone Developer oder iPhone Distribution), da das Framework, wie Sie hervorheben, mit der Einstellung "Code Sign On Copy" neu codiert wird. Dies bedeutet, dass Ihr Framework durch das entsprechende Zertifikat aus dem Entwicklerprofil des Framework-Verbrauchers neu codiert wird, wenn Ihr Framework in seine Anwendung kopiert wird. Dies bedeutet, dass es keine Probleme mit dem App Store gibt, da nur die endgültige Codesignatur des Framework-Verbrauchers angezeigt wird.

Am Ende des Tages können Sie Ihre .framework-Binärdatei genauso gut mit Code signieren, da Sie keinen exotischen Erstellungsprozess aufrechterhalten möchten. Da Xcode nur signierte Frameworks ausgibt, sollten Sie sich nicht zu weit von der entfernen Standardeinstellungen. Es spielt sowieso keine Rolle, da der Endverbraucher es neu signieren wird.

Jackslash
quelle
In Ihrer Antwort im zweiten Absatz sagen Sie, dass es nicht erforderlich ist, ein Framework zu codieren, da es vom Verbraucher neu codiert wird, und ich bin mir jetzt auch zu 95% sicher, dass es wahr ist, aber ich verstehe es nicht Warum sagen Sie gleichzeitig im ersten Absatz: "Wenn Sie das binäre Framework verteilen, müssen Sie es mit einem Code signieren" - was ist der Unterschied - wenn ich das binäre Framework verteile (dh nicht dessen Quelle über Karthago oder Cocoapods), warum Ich müsste es mitsignieren?
Stanislav Pankevich
Ich denke, ich sollte mein Framework nicht mit einem Code versehen, egal welche Art von Distribution ich verwende (gezippte .framework-Datei oder Karthago oder Cocoapods). Beispiele: Alle folgenden binären Framework-Distributionen sind nicht mit einem Codesign versehen: Realm , ReactiveCocoa , OCMockito .
Stanislav Pankevich
Ich bin also ein bisschen verwirrt mit Ihrem "Wenn Sie das binäre Framework verteilen, müssen Sie es mit einem Code signieren", was (imho) dem Rest Ihrer Antwort widerspricht. Bitte klären Sie. Bitte beachten Sie auch, dass ich dieses Kopfgeld als "Auf der Suche nach einer Antwort aus glaubwürdigen und / oder offiziellen Quellen" eröffnet habe.
Stanislav Pankevich
1
Ja, ich habe mir auch Realm und OCMockito angesehen. Realm hat "iPhone Developer" -Identitäten und ja, OCMockito ist eine statische Bibliothek. Ich glaube, ich verstehe das Problem - es ist Lipo, das das Codesignieren von iPhoneos entfernt, wenn es Codesignierte iPhoneos und nicht Codesignierte iPhonesimulatoren kombiniert.
Stanislav Pankevich
1
Ich habe eine Frage, wenn Sie Ihr Framework verteilen, Sie einen Debug-Build oder Release-Build verteilen? und wenn Sie es in Release Build verteilen, wie geht das?
niczm25
1

Die obige Antwort von Stanislav Pankevich ist sehr gültig und richtig. Beachten Sie jedoch, dass Sie ab Xcode 9.4 von der IDE aufgefordert werden, die Codesignatur für iOS Cocoa Touch Frameworks zu deaktivieren. Apple hier sagt jetzt, dass es nicht empfohlen wird, dass Sie Ihr .framework mit einem Code signieren.

Ich hoffe das hilft.

Dino Alves
quelle
1
Haben Sie eine Quelle für Apple, die davon abrät, Frameworks zu signieren?
Rick