Avec la sortie de Xcode 8, Apple a introduit une nouvelle façon de gérer la configuration de la signature. Vous avez maintenant deux options Manual
et Automatic
.
Selon la session WWDC 2016 sur la signature de code (WWDC 2016 - 401 - Nouveautés de la signature d'application Xcode) , lorsque vous sélectionnez la signature Automatic
, Xcode va:
Mais selon ce que Apple a dit lors de cette session, le Automatic Signing
va utiliser Development signing
et sera limité aux profils de provisioning créés par Xcode.
Le problème survient lorsque vous essayez d'utiliser Automatic Signing
dans un environnement de CI (comme Travis CI ou Jenkins). Je ne suis pas en mesure de trouver un moyen simple de continuer à utiliser Automatique et à signer pour la distribution (car Xcode vous oblige à utiliser les profils de provisioning développés et développés par Xcode).
Les nouveaux "profils d'approvisionnement créés par Xcode" n'apparaissent pas dans le portail des développeurs, bien que je puisse les trouver ensuite dans ma machine ... dois-je déplacer ces profils vers la machine CI, générer pour Development
et exporter pour Distribution
? Existe-t-il un moyen de remplacer le Automatic Signing
en utilisant xcodebuild
?
Après avoir essayé quelques options, voici les solutions que j'ai pu utiliser sur mon serveur CI:
L'utilisation de Automatic signing
vous oblige à utiliser un certificat Developer
et auto-generated provisioning profiles
. Une option consiste à exporter votre certificat de développement et votre clé privée (Application -> Utilitaires -> Accès au trousseau) et les profils de provisionnement générés automatiquement vers la machine CI. Un moyen de localiser les profils de provisioning générés automatiquement consiste à accéder à ~/Library/MobileDevice/Provisioning\ Profiles/
, à déplacer tous les fichiers dans un dossier de sauvegarde, à ouvrir Xcode et à archiver le projet. Xcode créera des profils de provisionnement de développement générés automatiquement et les copiera dans le dossier Provisioning Profiles
.
xcodebuild archive ...
créera un .xcarchive
signé pour Development
. xcodebuild -exportArchive ...
peut alors renoncer à la construction pour Distribution
Avant d'appeler xcodebuild
, une solution de contournement consiste à remplacer toutes les instances de ProvisioningStyle = Automatic
par ProvisioningStyle = Manual
dans le fichier de projet. sed
peut être utilisé pour une simple recherche et remplacement dans le fichier pbxproj
:
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' <ProjectName>.xcodeproj/project.pbxproj
@thelvis a également créé un script Ruby pour ce faire, à l'aide de la gemme xcodeproj
. Le script vous permet de mieux contrôler ce qui change.
xcodebuild
utilisera alors l'identité de signature de code (CODE_SIGN_IDENTITY
) définie dans le projet, ainsi que les profils d'approvisionnement (PROVISIONING_PROFILE_SPECIFIER
). Ces paramètres peuvent également être fournis en tant que paramètres à xcodebuild
et ils remplaceront l'identité de signature de code et/ou le profil de provisioning défini dans le projet.
EDIT: avec Xcode 9,
xcodebuild
a un nouveau paramètre de constructionCODE_SIGN_STYLE
pour choisir entreAutomatic
etManual
, il n’est donc pas nécessaire de rechercher et de remplacer des instances de automatic avec manual dans le fichier de projet, plus d’informations dans WWDC 2017 Session 403 Nouveautés de la signature pour Xcode et Xcode Server } _
La signature manuelle fournira un contrôle total sur les identités de signature de code et les profils d'approvisionnement utilisés. C'est probablement la solution la plus propre, mais avec l'inconvénient de perdre tous les avantages de la signature automatique.
Pour en savoir plus sur la signature de code avec Xcode 8, je vous recommande vivement cet article ainsi que la session WWDC2016 401 - Nouveautés de la signature d'application Xcode
En gros, je rencontre le même problème avec Jenkins CI et le plug-in Xcode . J'ai fini par créer moi-même la construction et la codification en utilisant xcodebuild
.
Pour réussir les étapes suivantes, vous devez avoir installé les profils d'approvisionnement et les certificats nécessaires. Cela signifie que votre signature de code devrait déjà fonctionner en général.
xcodebuild -project <path/to/project.xcproj> -scheme <scheme-name> -configuration <config-name> clean archive -archivePath <output-path> DEVELOPMENT_TEAM=<dev-team-id>
DEVELOPMENT_TEAM
: l'identifiant de votre équipe de développeurs à 10 chiffres (quelque chose comme A1B2C3D4E5)xcodebuild -exportArchive -archivePath <path/to/your.xcarchive> -exportOptionsPlist <path/to/exportOptions.plist> -exportPath <output-path>
Exemple de exportOptions.plist
:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.Apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>development</string>
<key>teamID</key>
<string> A1B2C3D4E5 </string>
</dict>
</plist>
method
: est l'un de development
, app-store
, ad-hoc
, enterprise
teamID
: l'identifiant de votre équipe de développeurs à 10 chiffres (quelque chose comme A1B2C3D4E5)Ce processus est de toute façon plus proche de ce que vous feriez manuellement avec Xcode, contrairement à ce que fait par exemple le plugin Jenkins Xcode.
Remarque: le fichier .xcarchive sera toujours signé de développement, mais la sélection de "app-store" en tant que méthode à la 2e étape permet de signer correctement la distribution et d'inclure le profil de distribution en tant que "embedded.mobileprovision".
J'espère que cela t'aides.
J'envisage une autre option que je n'ai pas encore vue mentionnée ici. Configurez deux cibles identiques, qui ne diffèrent que par leurs paramètres de signature.
L'inconvénient est que vous devez gérer deux objectifs identiques. Vous pouvez tirer parti des avantages de la signature automatique pour le développement, sans avoir à gérer des scripts potentiellement fragiles qui modifient votre projet juste avant la génération.
Si vous utilisez Xcode 8.x et Jenkins pour CI. Ensuite, vous rencontrerez probablement un problème avec "La signature de" Votre nom de projet "nécessite une équipe de développement. Sélectionnez une équipe de développement dans l'éditeur de projet.
La signature de code est requise pour le type de produit 'Application' dans le SDK 'iOS 10.1' ”. ** BUILD FAILED ** lors de l'exécution du travail.
Quelle est la solution?.
La solution est:
définissez le profil d'approvisionnement sur Aucun dans les paramètres de construction du projet Xcode.
Dans Jenkins, créez un shell exécutable avant le paramètre Xcode et écrivez la commande ci-dessous.
sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' ProjectName.xcodeproj/project.pbxproj
Rappelez-vous: conservez cette exécution Shell avant les paramètres Xcode dans la section Construction de Jenkins.
Cela marche.
Pour moi, rien n'a fonctionné. J'ai résolu mon problème en modifiant un fichier dans l'application Xcode installée sur votre Mac Mini (serveur CI avec Jenkins), comme indiqué dans ce lien:
https://www.jayway.com/2015/05/21/fixing-your-ios-build-scripts/
De plus, j'ai désactivé la signature automatique à partir de Xcode.
Terminé! Enfin fonctionne!
J'ai remarqué que ma version Unity n'a jamais ajouté de clé ProvisioningStyle à mon projet XCode. J'ai ensuite trouvé un moyen d'ajouter manuellement le ProvisioningStyle à l'aide d'un script de génération "PostProcessBuild". c'est-à-dire une unité de code appelée après la construction du projet XCode IOS par Unity.
J'ai tout d'abord regardé à quoi devrait ressembler le fichier project.pbxproj - lorsqu'il est défini sur Approvisionnement manuel:
/* Begin PBXDictionary section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
attributes = {
TargetAttributes = {
1D6058900D05DD3D006BFB54 /* Unity-iPhone */ = {
ProvisioningStyle = Manual;
};
5623C57217FDCB0800090B9E /* Unity-iPhone Tests */ = {
TestTargetID = 1D6058900D05DD3D006BFB54 /* Unity-iPhone */;
};
};
};
Ensuite, j'ai créé mon code pour répliquer la "structure" du fichier vu ci-dessus. (en utilisant le projet XCodeEditor trouvé ici: XCodeEditor )
[PostProcessBuild]
public static void OnPostProcessBuild(BuildTarget target, string path)
{
// Create a new project object from build target
XCProject project = new XCProject(path);
if (target == BuildTarget.iOS)
{
//Add Manual ProvisioningStyle - this is to force manual signing of the XCode project
bool provisioningSuccess = AddProvisioningStyle(project, "Manual");
if (provisioningSuccess)
project.Save();
}
}
private static bool AddProvisioningStyle(XCProject project, string style)
{
var pbxProject = project.project;
var attr = pbxProject.data["attributes"] as PBXDictionary;
var targetAttributes = attr["TargetAttributes"] as PBXDictionary;
var testTargetIDGuid = FindValue(targetAttributes, "TestTargetID");
if (!string.IsNullOrEmpty(testTargetIDGuid))
{
var settings = new PBXDictionary();
//here we set the ProvisioningStyle value
settings.Add("ProvisioningStyle", style);
targetAttributes.Add(testTargetIDGuid, settings);
var masterTest = FindValue(targetAttributes, "ProvisioningStyle");
if (masterTest == style)
{
return true;
}
}
return false;
}
private static string FindValue(PBXDictionary targetAttributes, string key)
{
foreach (var item in targetAttributes)
{
var ma = item.Value as PBXDictionary;
foreach (var di in ma)
{
var lookKey = di.Key;
if (lookKey == key)
{
return di.Value.ToString();
}
}
}
return "";
}
Il existe un outil appelé fastlane qui facilite beaucoup l’utilisation de xcodebuild et qui est maintenu: les nouvelles mises à jour continueront de prendre en charge les modifications apportées à xcode. Cela facilite beaucoup la création de scripts et la configuration pour la construction et la signature de codes de votre application parmi de nombreux autres outils d'automatisation xcode pris en charge. Je recommanderais d'y jeter un coup d'oeil.
Ce qui a résolu le problème pour moi, c'est ceci: http://code-dojo.blogspot.jp/2012/09/fix-ios-code-signing-issue-when-using.html
... copie des certificats du trousseau de connexion au trousseau système . Vous pouvez également définir tous les certificats de développement sur "Autoriser toutes les applications à accéder à cet élément" (clic droit/Obtenir des informations/Contrôle d'accès).