Créer des Frameworks iOS / OSX: est-il nécessaire de les coder avant de les distribuer à d'autres développeurs?

90

J'apprends à créer des frameworks iOS et OSX. Prenons par exemple iOS, les étapes suivantes fonctionnent pour moi jusqu'à présent:

  1. xcodebuild framework utilisant -sdk iphonesimulator et Build action
  2. xcodebuild framework utilisant -sdk iphoneos et Build action
  3. Utilisez l'outil lipo pour créer un binaire universel afin de lipo -infoproduire les résultats attendus:

Les architectures dans le fichier fat: Foo.framework / Foo sont: i386 x86_64 armv7 arm64

Les questions sont:

  1. J'ai lu que mon framework peut être re-signé par le développeur qui l'utilise: "Code Sign on Copy" mais je ne comprends pas quelles sont les conditions préalables, c'est-à-dire dois-je ajouter une étape de conception de code pour coder ce binaire universel avec mon identité de signature avant le distribuer à d'autres développeurs?

  2. si le précédent est positif - devrais-je utiliser mon identité "iPhone Distribution: ..." ou "iPhone Developer: ..." est suffisant (pour que mon framework faisant partie d'un projet iOS passe toutes sortes de validations en particulier la validation App Store )?.

Le contexte de ma réponse est "Erreur CodeSign: la signature de code est requise pour le type de produit 'Framework' dans le SDK 'iOS 8.3'" que j'ai vu sur un certain nombre de frameworks tiers et Carthage # 235 ou "l'objet de code n'est pas signé du tout "(un exemple: problème que j'ai signalé sur Realm # 1998 .

Je veux donc m'assurer que les utilisateurs de mes frameworks ne rencontreront aucun problème de signature de code lorsqu'ils les utiliseront.

PS Cette question devient encore plus intéressante lorsqu'elle est appliquée non pas à un seul développeur mais à une organisation qui est un fournisseur de framework.

Stanislav Pankevich
la source
Ce commentaire suggère d'utiliser 'CODE_SIGN_IDENTITY = iPhone Developer' mais il n'est pas clair pourquoi 'Developer' est utilisé au lieu de 'iPhone Distribution'.
Stanislav Pankevich
Rubrique connexe: Exportation d'une application avec un framework intégré mais sans réponse définitive.
Stanislav Pankevich
J'ai également dupé cette question sur les forums de développeurs Apple: forums.developer.apple.com/thread/6400 .
Stanislav Pankevich
J'ai une question lorsque vous distribuez votre framework, vous distribuez une version de débogage ou une version de version? et si vous le distribuez dans la version release, comment faire cela?
niczm25
@ niczm25, voici une façon de faire: stanislaw.github.io/2015/11/23/… .
Stanislav Pankevich

Réponses:

137

J'ai ouvert la prime: "A la recherche d'une réponse tirée de sources crédibles et / ou officielles." mais je n'ai pas reçu de tel depuis lors.

Bien que la réponse fournie par @jackslash soit correcte, elle ne raconte qu'une partie de l'histoire, donc je veux écrire la mienne d'une manière que j'aurais aimé voir au moment où je posais cette question.

La réalité de cette réponse est: juillet 2015. Il est fort probable que les choses changeront.

Tout d'abord, affirmons que les actions nécessaires pour une signature correcte du code du framework doivent être divisées en étapes que le développeur du framework doit suivre et en étapes que le consommateur du framework doit prendre.

TLDR;

Pour le framework OSX: Le développeur est libre de distribuer le framework OSX sans le coder car le consommateur le recodifiera de toute façon.

Pour le framework iOS: le développeur est libre de distribuer le framework iOS sans le coder car le consommateur le recodifiera quand même, mais le développeur est obligé par Xcode de coder son framework lorsqu'il construit pour un appareil iOS.

À cause du radar: "Les frameworks iOS contenant des tranches de simulateur ne peuvent pas être soumis à l'App Store" Le consommateur du framework iOS est obligé d'exécuter un script spécial comme "copy_frameworks" ou "strip_frameworks" qui utilise lipo -removepour supprimer les tranches de simulateur du framework iOS et re -codesigns a dépouillé le framework car à ce stade, son identité de code, quelle qu'elle soit (ou non), est supprimée comme effet secondaire de la lipo -removemanipulation.

Une réponse plus longue suit.


Cette réponse n'est pas un «tirage à partir de sources crédibles et / ou officielles» mais est plutôt basée sur un certain nombre d'observations empiriques.

Observation empirique n ° 1: le consommateur s'en fiche car il reconcevera le cadre qu'il reçoit du développeur

Les distributions de framework binaire de projets open source bien connus sur Github ne sont pas codées . La commande codesign -d -vvvvdonne: "l'objet de code n'est pas du tout signé" sur tous les frameworks binaires iOS et OSX que j'ai utilisés pour explorer. Quelques exemples: ReactiveCocoa et Mantle , Realm , PromiseKit .

À partir de cette observation, il est clair que les auteurs de ces frameworks ont l'intention qu'ils soient codés par le consommateur, en leur nom, c'est-à-dire qu'un consommateur doit utiliser soit le drapeau «Code Sign on Copy» dans la phase de construction «Embed frameworks» fournie par Xcode, soit utiliser un shell personnalisé script qui fait la même chose manuellement: cadre de codesigns pour le compte du consommateur.

Je n'ai trouvé aucun exemple du contraire: un framework open source qui serait distribué avec une identité de code-signature, donc dans le reste de la réponse, je suppose que cette approche largement adoptée est correcte: il n'est pas nécessaire que le développeur de framework distribuer leur framework à d'autres développeurs avec une identité de code car le consommateur le recodifiera de toute façon .

Observation empirique n ° 2 qui s'applique uniquement à iOS et qui est entièrement une préoccupation des développeurs

Bien que la consommation ne se soucie pas si le cadre qu'ils reçoivent du développeur est ou non un des concepteurs, développeur doit encore leur cadre iOS concerter de façon décisive dans le cadre de son processus de construction quand ils construisent pour appareil iOS car sinon Xcode ne construit pas: CodeSign error: code signing is required for product type 'Framework' in SDK 'iOS 8.1'. Pour citer Justin Spahr-Summers :

Les frameworks OS X n'ont pas besoin d'être codés lors de la construction ... Malheureusement, Xcode nécessite que les frameworks iOS soient codés au moment de la construction.

Cela répond assez bien à ma question n ° 2: l'identité "iPhone Developer" suffit à cajoler Xcode afin qu'il crée un framework iOS pour l'appareil. Ce commentaire sur Carthage # 339 dit la même chose.

Observation empirique n ° 3: outil lipo

Comportement spécifique de l' outil de lipo: lorsqu'il est appliqué à binaire-cadre, il a toujours supprime récursive toutes les identités codesign de celui - ci : lipo -create/-remove codesigned framework ... -> not codesigned framework.

Cela pourrait expliquer pourquoi tous les exemples de l'observation n ° 1 ne sont pas du tout signés par un code: leur identité de signature de code est époustouflée après l'application de la lipo, mais puisque selon l'observation n ° 1, le consommateur ne s'en soucie pas.

Cette observation est particulièrement pertinente pour la prochaine observation n ° 4 sur l'AppStore.

Observation empirique n ° 4: les frameworks iOS contenant des tranches de simulateur ne peuvent pas être soumis à l'App Store

Ceci est largement discuté dans: Realm # 1163 et Carthage # 188 et le radar est ouvert: rdar: // 19209161 .

C'est entièrement la préoccupation du consommateur: pour le cadre universel iOS que le consommateur inclut dans son application, lorsque l'application est en cours de construction, il doit exécuter un script spécial (phase d'exécution de script personnalisée) qui supprime la tranche de simulateur du binaire de ce cadre afin que l'application puisse passer la validation AppStore.

Le bon exemple de frameworks binaires que j'ai trouvé dans Realm: strip-frameworks.sh .

Il utilise lipopour supprimer toutes les tranches d'architectures autres que ${VALID_ARCHS}, puis le recode avec l'identité du consommateur - c'est là que l'observation n ° 3 entre en jeu: le cadre doit être recodé à cause de manipulations lipo dessus.

Carthage a le script CopyFrameworks.swift qui fait la même chose à tous les frameworks inclus par Consumer: il supprime les tranches du simulateur et recode le framework pour le compte de Consumer.

Il existe également un bon article: Suppression des architectures indésirables des bibliothèques dynamiques dans Xcode .


Maintenant, l'aperçu des étapes nécessaires pour produire iOS et OSX du point de vue du développeur et du consommateur. D'abord le plus facile:

OSX

Développeur:

  1. Construit le cadre OSX
  2. Le donne au consommateur

Aucune activité de signature de code n'est requise de la part du développeur.

Consommateur:

  1. Reçoit le framework OSX du développeur
  2. Copie le framework dans le répertoire Frameworks / et le code automatiquement pour le compte du consommateur dans le cadre du processus «Code Sign on Copy».

iOS

Développeur:

  1. Construit le cadre iOS pour l'appareil. La signature de code est requise par Xcode, l'identité «iPhone Developer» suffit.
  2. Construit un cadre iOS pour le simulateur.
  3. Utilise lipo qui produit le cadre iOS universel des deux précédents. À ce stade, l'identité de signature de code de 1 étape est perdue: le cadre binaire universel "n'est pas signé du tout" mais c'est très bien puisque "le consommateur s'en fiche".
  4. Le donne au consommateur

Consommateur:

  1. Reçoit le framework iOS du développeur
  2. Copie le framework dans le répertoire Frameworks / (cette étape peut être redondante selon le script de l'étape 3).
  3. Utilise un script spécial dans le cadre du processus de construction: ce script supprime le simulateur du framework iOS, puis le recode au nom du consommateur.
Stanislav Pankevich
la source
9
Ceci est un article précieux. Nice one
jackslash
@Stanislaw merci pour les informations et les données précieuses. Alors que j'écris un framework que j'ai conçu pour les développeurs, je veux qu'ils puissent prendre le framework tel quel et l'utiliser sans avoir besoin de créer un script spécial pour le télécharger sur l'App-Store. Je pense que GoogleMobileAd fonctionne de cette façon. mais vous dites qu'ils doivent exécuter certains scripts? vous savez comment GoogleMobileAds ne l'exige pas? merci
Michael A
@MichaelA, en effet c'est intéressant. Je vais regarder.
Stanislav Pankevich
Pouvez-vous me donner un lien vers GoogleMobileAds que vous utilisez?
Stanislav Pankevich
1
Merci d'avoir économisé mon temps, cela a fonctionné pour moi. Xcode 7.3, Mac OS X 10.11.4.
eugen
21

À la lecture du fil lié sur le repo de Carthage, cela semble relativement simple. Si vous distribuez le framework binaire, vous devez le signer par code et si vous distribuez la source via carthage ou des cosses de cacao, vous ne le faites pas car ces outils s'en chargent via différentes méthodes.

La raison pour laquelle vous devez coder le signer lorsque vous distribuez le cadre binaire est que Xcode ne produira pas de binaire de cadre sans le signer par le code. Si vous essayez de ne pas coder signer le cadre binaire, vous obtenez cette erreur:

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

Peu importe l'identité avec laquelle vous codez pour signer le framework (iPhone Developer ou iPhone Distribution) car, comme vous le faites remarquer, le framework sera recodé avec le paramètre «code sign on copy». Cela signifie que votre framework sera recodé par le certificat approprié du profil de développeur du consommateur de framework lorsque votre framework est copié dans leur application. Cela signifie qu'il n'y aura pas de problèmes avec l'App Store car il ne verra que la signature de code finale du consommateur du framework.

En fin de compte, vous pourriez aussi bien signer le code de votre binaire .framework que vous ne voulez pas avoir à maintenir un processus de construction exotique, et comme Xcode ne produira que des frameworks signés, vous ne devriez pas vous éloigner trop du les valeurs par défaut. De toute façon, cela n'a pas vraiment d'importance car le consommateur final le signera à nouveau.

jackslash
la source
dans votre réponse, dans le deuxième paragraphe, vous dites qu'il n'est pas nécessaire de coder le cadre car il sera recodé par le consommateur et je suis également sûr à 95% que c'est vrai, mais je ne comprends pas pourquoi en même temps dans le premier paragraphe vous dites: "Si vous distribuez le framework binaire, vous devez le coder le signer" - quelle est la différence - si je distribue un framework binaire (c'est à dire pas sa source via carthage ou cocoapods) pourquoi J'aurais besoin de le coder?
Stanislav Pankevich
Je pense que je ne devrais pas coder mon framework quel que soit le type de distribution que j'utilise (fichier .framework zippé ou carthage ou cocoapods). Exemples: toutes les distributions de framework binaires suivantes ne sont pas codées: Realm , ReactiveCocoa , OCMockito .
Stanislav Pankevich
Je suis donc un peu confus avec votre "Si vous distribuez le framework binaire, vous devez le coder le signer" qui (à mon humble avis) contredit le reste de votre réponse. Précisez s'il vous plaît. Veuillez également noter que j'ai ouvert cette prime comme "À la recherche d'une réponse tirée de sources crédibles et / ou officielles".
Stanislav Pankevich
1
Oui, j'ai également regardé Realm et OCMockito. Realm a des identités "iPhone Developer" et oui, OCMockito est une bibliothèque statique. Je pense que je comprends le problème - c'est le lipo qui supprime la signature de code de l'iphoneos lorsqu'il combine des iphoneos signés avec un code et un simulateur d'iphones non signé.
Stanislav Pankevich
1
J'ai une question lorsque vous distribuez votre framework, vous distribuez une version de débogage ou une version de version? et si vous le distribuez dans la version release, comment faire cela?
niczm25
1

La réponse de Stanislav Pankevich ci-dessus est très valide et correcte. Mais veuillez noter qu'à partir de Xcode 9.4, l'EDI vous demandera de désactiver la signature de code pour iOS Cocoa Touch Frameworks. Apple dit maintenant qu'il n'est pas recommandé de signer le code de votre .framework.

J'espère que ça aide.

Dino Alves
la source
1
Avez-vous une source pour Apple qui recommande de ne pas signer de cadres?
Rick le