我如何生成我的客户可以在他们的终端上签名的 iOS 发布版本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7449087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I produce an iOS Release Build that my client can sign on their end?
提问by RickDT
My scenario
我的场景
I wrote an iOS app for a client. The project is almost over and now it's time for them to put it in the App Store. I've been sending them development builds throughout the development process. Those builds had a bundle id based on my company and my client's project like so: com.mycompany.clientname.projectname
. I signed those Ad Hoc builds with an Ad Hoc Distribution Provisioning Profile that I created in my own Provisioning Portal account.
我为客户编写了一个 iOS 应用程序。该项目快结束了,现在是他们将其放入 App Store 的时候了。在整个开发过程中,我一直在向他们发送开发版本。那些建立了基于我公司与喜欢,所以我的客户的项目捆绑ID: com.mycompany.clientname.projectname
。我使用我在自己的供应门户帐户中创建的 Ad Hoc 分发供应配置文件签署了这些 Ad Hoc 构建。
Now that it's time to go to the App Store, I need to do a Release Build and send that for them to sign with their own App Store Distribution Provisioning Profile. This also implies setting a new Bundle ID for the project.
现在是去 App Store 的时候了,我需要做一个 Release Build 并将其发送给他们,以便他们使用他们自己的 App Store Distribution Provisioning Profile 进行签名。这也意味着为项目设置一个新的 Bundle ID。
My problem
我的问题
I need to get a compiled app to the client for them to sign with their provisioning profile. However, I need to set the Bundle ID to what they're going to use first. Let's say it's com.bestclientever.appname
. Xcode 4 won't let me archive the project now because doing so requires code signing. I can not code sign it because I can not create a provisioning profile with the same Bundle ID as what they have set up in their Provisioning Portal (the Provisioning Portal enforces uniqueness—as it should).
我需要向客户端获取一个编译的应用程序,以便他们使用他们的配置文件进行签名。但是,我需要将 Bundle ID 设置为他们首先要使用的 ID。让我们说它是com.bestclientever.appname
。Xcode 4 现在不允许我归档项目,因为这样做需要代码签名。我无法对其进行代码签名,因为我无法创建与他们在其供应门户中设置的捆绑 ID 相同的供应配置文件(供应门户强制执行唯一性 - 应该如此)。
Have I made any incorrect assumptions or misunderstandings here? ie. Do I really have to set the Bundle ID to what they're going to sign with?
我是否在这里做出了任何不正确的假设或误解?IE。我真的必须将 Bundle ID 设置为他们将要签名的内容吗?
The Question
问题
Is there any way to archive, or otherwise build, an iOS app without code signing it? Like a "sign later" setting or something?
有没有办法存档或以其他方式构建 iOS 应用程序而无需对其进行代码签名?像“稍后签名”设置之类的?
Or, is there a way to build the app with one bundle id but then someone else be able to sign it with a provisioning profile for another bundle id (either by changing the bundle id of the compiled app or some other signing method)?
或者,有没有办法使用一个包 ID 构建应用程序,但其他人可以使用另一个包 ID 的配置文件对其进行签名(通过更改已编译应用程序的包 ID 或其他一些签名方法)?
How can I build the final release build but have someone else sign the app for distribution to the App Store?
如何构建最终发布版本但让其他人签署应用程序以分发到 App Store?
What I've tried or explored
我尝试过或探索过的
- Acting for the client.
- With other, less savvy clients, I've ended up just getting their Provisioning Portal and iTunesConnect credentials and just doing the final build as them. That won't fly with this client. It's a big company with strict security guidelines and a lot of red tape.
- Spoofing as the client.
- This is similar to the one above and won't work for the same reasons. It sounds really fishy to ask my client "can you export your privatekeys and send them to me"? This technique is described in this answer: How can I send iOS app to client, for them to code-sign
- Sending the client my project source code and letting them do the release build.
- A license to the source code was not in our agreement. Additionally, this client does not want to get involved with source code (hence outsourcing it). I would entertain this as a last-resort option, but there's gotta be a better way!
- Getting set up as an Admin-level developer in their Developer Member Center.
- Unfortunately, only the Agent-level user can create a Provisioning Profile (as far as I can tell). It seems like there ought to be a way to either let me create a profile that I can use to sign the build or generate a profile for me. I can't find either option.
- 为客户代理。
- 对于其他不太精明的客户,我最终只获得了他们的 Provisioning Portal 和 iTunesConnect 凭据,并像他们一样进行最终构建。这不会与这个客户一起飞行。这是一家拥有严格安全准则和大量繁文缛节的大公司。
- 欺骗客户。
- 这与上面的类似,并且由于相同的原因而不起作用。问我的客户“你能导出你的私钥并将它们发送给我吗”听起来很可疑?此答案中描述了此技术:如何将 iOS 应用程序发送到客户端,以便他们进行代码签名
- 将我的项目源代码发送给客户并让他们进行发布构建。
- 源代码的许可不在我们的协议中。此外,该客户不想参与源代码(因此将其外包)。我会将其视为最后的选择,但必须有更好的方法!
- 在其开发人员会员中心设置为管理员级别的开发人员。
- 不幸的是,只有代理级别的用户才能创建配置文件(据我所知)。似乎应该有一种方法让我创建一个配置文件,我可以用它来签署构建或为我生成一个配置文件。我找不到任何一个选项。
采纳答案by Richard Venable
Most of these answers seem complicated and out dated. I think the simple answer is to make an archive with a Developer profile.
这些答案中的大多数看起来都很复杂且过时。我认为简单的答案是使用 Developer profile 制作存档。
This is a solution which I am currently investigating for my own purposes (not fully tested):
这是我目前正在为自己的目的进行调查的解决方案(未经过全面测试):
You just need developer access (not team agent) to their account and create a Development provisioning profile that authorizes you to build the specified App ID (you need to specify the App ID, because it gets compiled in). Then Archive the app with the Development profile, and share the archive with your client. They can then re-sign the archive with their own Distribution profile.
您只需要开发人员访问他们的帐户(而不是团队代理)并创建一个开发配置文件,该配置文件授权您构建指定的 App ID(您需要指定 App ID,因为它会被编译)。然后使用开发配置文件存档应用程序,并与您的客户共享存档。然后,他们可以使用自己的分发配置文件重新签署存档。
One complication is that when you build an archive with a developer profile, the entitlement attribute get-task-allow gets set to true, but needs to be set to false for distribution, so you have to work around that by setting it manually your Entitlements.plist - see my question here: Can I archive with a Developer certificate, then re-sign it during submission with a Distribution certificate?
一个复杂的问题是,当您使用开发人员配置文件构建存档时,权利属性 get-task-allow 将设置为 true,但需要将其设置为 false 以进行分发,因此您必须通过手动设置您的权利来解决这个问题.plist - 在此处查看我的问题:我可以使用开发人员证书存档,然后在提交期间使用分发证书重新签名吗?
回答by RickDT
I just confirmed at WWDC 2012 that the following technique works. It best satisfies my constraints of little client involvement, low client expertise, a simple signing process, and source code ownership.
我刚刚在 WWDC 2012 上确认以下技术有效。它最能满足我对客户参与少、客户专业知识低、签名过程简单和源代码所有权的限制。
- Client invites developer to their team in the Member Center as an Admin
- Developer accepts the invite (should be in your email)
- Developer opens Xcode's Organizer -> Devices Tab -> Provisioning Profiles and hits Refresh in the lower-right corner. Make sure you choose the right team and you should get a few new items.
- In Xcode, leave Code Signing Identity settings to their default values (or reset them to iPhone Developer for Any iOS SDK)
- Archive the app
- In Organizer, right-click the archive and select Show in Finder
- Send the .xcarchive file to your client
- Client must have Xcode installed
- Client double-clicks the .xcarchive file which should open it in Organizer
- Client clicks Distribute and signs the app with their identity
- Profit
- 客户在会员中心邀请开发人员以管理员身份加入他们的团队
- 开发人员接受邀请(应该在您的电子邮件中)
- 开发人员打开 Xcode 的 Organizer -> Devices Tab -> Provisioning Profiles 并点击右下角的 Refresh。确保您选择了正确的团队,您应该会获得一些新物品。
- 在 Xcode 中,将 Code Signing Identity 设置保留为默认值(或将它们重置为 iPhone Developer for Any iOS SDK)
- 归档应用程序
- 在管理器中,右键单击存档并选择在 Finder 中显示
- 将 .xcarchive 文件发送给您的客户端
- 客户端必须安装 Xcode
- 客户端双击应在管理器中打开它的 .xcarchive 文件
- 客户单击“分发”并使用其身份对应用程序进行签名
- 利润
This does require the client to use the Member Center on developer.apple.com and to use Xcode a little bit (but just the Organizer!). If your client has technical capability problems at this level then I recommend just taking over and doing it for them (and charging for it!). Ask for their developer login and password and just act on their behalf as if you were an employee.
这确实需要客户使用 developer.apple.com 上的会员中心并稍微使用 Xcode(但只是管理器!)。如果您的客户在这个级别有技术能力问题,那么我建议您接管并为他们做这件事(并为此收费!)。询问他们的开发人员登录名和密码,然后就好像您是员工一样代表他们行事。
Ed note: Trading keys around is a terrible compromise because it's more technical and involved for the client and more hacky and risky for the developer. It should be considered a non-option given these two better options.
编者注:交换密钥是一种可怕的妥协,因为它更具技术性,涉及客户,而对开发人员而言则更具技巧性和风险性。鉴于这两个更好的选择,它应该被视为非选择。
回答by jimmyg
I had the same problem. This was how I finally solved it:
我有同样的问题。这就是我最终解决它的方式:
- Client created a developmentcertificate.
- Client created a developmentprovisioning file using the same App ID as the distribution provisioning file.
- Client exported development certificate (.p12).
- Client sent me the .p12 file and the development mobile provisioning file.
- I imported the clients p12 file into my keychain
- I imported the client's provisioning file into Xcode.
- Set the code signing Identity for my build configuration to use the client's provisioning file.
- I Archived the app.
- I Sent the Archive to the client.
- The client created their distribution build by signing the app with their distributionprovisioning file. (They were distributing the app internally for testing.)
- 客户创建了开发证书。
- 客户端使用与分发配置文件相同的 App ID创建了开发配置文件。
- 客户端导出的开发证书 (.p12)。
- 客户向我发送了 .p12 文件和开发移动配置文件。
- 我将客户端 p12 文件导入到我的钥匙串中
- 我将客户端的配置文件导入到 Xcode 中。
- 为我的构建配置设置代码签名标识以使用客户端的配置文件。
- 我归档了应用程序。
- 我将档案发送给客户。
- 客户端通过使用其分发配置文件对应用程序进行签名来创建其分发版本。(他们在内部分发应用程序进行测试。)
The client was not so concerned with sharing a developmentcertificate as they would be sharing their distribution certificate.
客户不太关心共享开发证书,因为他们会共享他们的分发证书。
I also had to create entitlements.plist
with "Can be debugged" (get-task-allow) set to NO, and reference it in the build configuration (under Code Signing, Code Signing Entitlements).
我还必须在entitlements.plist
“可以调试”(get-task-allow) 设置为 NO 的情况下创建,并在构建配置中引用它(在代码签名、代码签名权利下)。
回答by Piwaf
I believe I have found a way to do exactly what you want, I haven't done extensive testing or tried to upload to the app store but from the testing I have done it seems to be good. The resign and the addition of my provisioning profile is working as I can install it on my devices defined in the AdHoc profile with no manual profile installation needed. Second test was I got an iPad and an iPhone version of an app with the same bundle ID from xCode, at first I could not have both in iTunes but after the resign and bundle ID change I was able to have both installed. I also tried changing the app name and that worked as well, it showed on the device and in iTunes with the new name. Below is my script, it's designed to resign a specific app for me, so the profile and bundleID are hardcoded. I flip between an iPhone and iPad version of the app so I added that as a parameter to the script. But you should be able to take the principles I have here and refine them for yourself.
我相信我已经找到了一种方法来做你想做的事,我没有做过广泛的测试或尝试上传到应用商店,但从我所做的测试来看,它似乎很好。辞职和添加我的配置文件正在起作用,因为我可以将它安装在 AdHoc 配置文件中定义的设备上,而无需手动安装配置文件。第二个测试是我从 xCode 获得了一个具有相同捆绑 ID 的应用程序的 iPad 和 iPhone 版本,起初我无法在 iTunes 中同时拥有这两个版本,但在辞职和捆绑 ID 更改后,我能够同时安装两者。我还尝试更改应用程序名称,效果也很好,它以新名称显示在设备和 iTunes 中。下面是我的脚本,它旨在为我放弃特定的应用程序,因此配置文件和 bundleID 是硬编码的。我在应用程序的 iPhone 和 iPad 版本之间切换,因此我将其添加为脚本的参数。但是你应该能够接受我在这里的原则,并为自己完善它们。
The guts of this builds upon articles like Further adventures in resigning for iOS from Dan's Dev Diaryand very similar to Erica Sadun's App Signer listed above. The main addition I made was the editing of the Info.plist prior to resigning.
这篇文章的内容基于Dan 的 Dev Diary 中的进一步冒险为 iOS 辞职,并且与上面列出的 Erica Sadun 的 App Signer 非常相似。我所做的主要补充是在辞职之前编辑了 Info.plist。
#!/bin/sh
DestFile="Signed_"
SigningCertName="YOUR DISTROBUTION CERT NAME HERE FROM KEYCHAIN"
AppInternalName="APP NAME FROM INSIDE PAYLOAD FOLDER.app"
echo
echo "Going to take the app and resign it as $DestFile"
echo
if [ "" = "iphone" ] ; then
echo "Using iPhone Profile"
echo
BundleID="com.YOURCOMPANY"
ProvProfile="/Users/YOURNAME/Library/MobileDevice/Provisioning Profiles/PROVISIONINGPROFILE.mobileprovision"
elif [ "" = "ipad" ] ; then
echo "Using iPad Profile"
echo
BundleID="com.YOURCOMPANY.ipad"
ProvProfile="/Users/YOURNAME/Library/MobileDevice/Provisioning Profiles/PROVISIONINGPROFILE_iPad.mobileprovision"
else
echo "You must enter either iphone or ipad as the second parameter to choose the profile to sign with."
echo
exit 1
fi
rm -f Resigned.ipa
unzip -q -d temparea
cd temparea/Payload
echo "*** Original Signing ***"
echo "************************"
codesign -d -vv $AppInternalName/
cp "$ProvProfile" ./$AppInternalName/embedded.mobileprovision
export EMBEDDED_PROFILE_NAME=embedded.mobileprovision
export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
#Update the Info.plist with the new Bundle ID
sed 's/>ORIGINAL BUNDLEID HERE</>'$BundleID'</' ./$AppInternalName/Info.plist >./$AppInternalName/Info.plist.new
mv -f ./$AppInternalName/Info.plist.new ./$AppInternalName/Info.plist
# this will do a rename of the app if needed
# sed 's/>ORIGINAL APP NAME</>NEW APP NAME</' ./$AppInternalName/Info.plist >./$AppInternalName/Info.plist.new
# mv -f ./$AppInternalName/Info.plist.new ./$AppInternalName/Info.plist
# echo "Hit enter to proceed with signing."
# read TMP
codesign -f -vv -s "$SigningCertName" -i $BundleID $AppInternalName
echo
echo "*** New Signing ***"
echo "*******************"
codesign -d -vv $AppInternalName/
cd ..
zip -r -q ../Resigned.zip .
cd ..
rm -R temparea
mv Resigned.zip $DestFile
echo
echo "New IPA Created, $DestFile"
回答by Saurabh Passolia
Best alternative way would be to ask the client to export his distribution certificate private key into .p12 file and send it across to you alongwith the distribution profile with which you can generate a App Store distribution build for your client.
最好的替代方法是要求客户将其分发证书私钥导出到 .p12 文件中,然后将其与分发配置文件一起发送给您,您可以使用该文件为您的客户生成 App Store 分发版本。
Best of luck!!
祝你好运!!
Regards, Sam
问候, 山姆
回答by hasvn
Ok, found a way to do it without sharing provisioning profiles or certificates.
好的,找到了一种无需共享配置文件或证书的方法。
The idea is to insert a "run script" build phase to trick XCode into signing an App it didn't compile, so you can send a compiled (unsigned) App to the client, and then their XCode signs that App with their cert and profile.
这个想法是插入一个“运行脚本”构建阶段来欺骗 XCode 签署一个它没有编译的应用程序,这样你就可以向客户端发送一个编译(未签名)的应用程序,然后他们的 XCode 用他们的证书和轮廓。
How to do it:
怎么做:
Step 1: Make XCode generate an unsigned Release .app (I'll call this "App A"). See "To Disable Code Signing" here: https://stackoverflow.com/a/10171462/375486
第 1 步:让 XCode 生成一个未签名的 Release .app(我称之为“App A”)。请参阅此处的“禁用代码签名”:https: //stackoverflow.com/a/10171462/375486
Step 2: Create a new XCode iOS project and remove from it all build phases you can, so it creates an empty .app file (I'll call this "App B")
第 2 步:创建一个新的 XCode iOS 项目并从中删除所有构建阶段,因此它会创建一个空的 .app 文件(我将其称为“App B”)
Step 3: Add a "run script" build phase to Project B which copies the contents of "App A" into "App B". In my case I used this:
第 3 步:将“运行脚本”构建阶段添加到项目 B,将“App A”的内容复制到“App B”中。在我的情况下,我使用了这个:
cp -r A.app/* "$CODESIGNING_FOLDER_PATH"
Step 4: Send the "B" XCode project to the client, with all the necessary files.
第 4 步:将“B”XCode 项目连同所有必要的文件发送给客户端。
Step 5: The client builds the B project. Under the hood, XCode will run the "run script" command, then sign the resulting app, and the client gets a perfectly signed App.
第五步:客户端构建B项目。在幕后,XCode 将运行“运行脚本”命令,然后对生成的应用程序进行签名,客户端将获得一个完美签名的应用程序。
And that's it :)
就是这样:)
回答by funroll
iResignworks quite well.
iResign工作得很好。
It allows you to change the bundle id and add entitlements when signing. Probably would work for your use case.
它允许您在签名时更改捆绑包 ID 并添加权利。可能适用于您的用例。
That being said, the xcarchive solution is more canonical. Be aware that sharing the xcarchive file gives them the dsym.
话虽如此,xcarchive 解决方案更规范。请注意,共享 xcarchive 文件会为他们提供 dsym。
If you have any #ifdef DEBUG statements in your code, make sure they are disabled in the build you give them.
如果您的代码中有任何 #ifdef DEBUG 语句,请确保在您提供的构建中禁用它们。
回答by Popmedic
Huh, all these look way more complicated then they have to. I use this this:
嗯,所有这些看起来都比他们必须要复杂得多。我用这个:
xcodebuild -scheme "$SCHEME" clean archive \
-archivePath "build/$SCHEME" \
-workspace $PRODUCT_NAME.xcworkspace \
-allowProvisioningUpdates \
-configuration Release \
PRODUCT_NAME="$SCHEME" \
PRODUCT_BUNDLE_IDENTIFIER="$BUNDLE_ID" \
EXECUTABLE_NAME="$SCHEME" \
DISPLAY_NAME="$DISPLAY_NAME" \
CODE_SIGN_IDENTITY="" \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGN_ENTITLEMENTS="" \
CODE_SIGNING_ALLOWED=YES
回答by Jean-Denis Muys
I've been there. Options 2 or 3 are out of question. Option 4 would be ideal, but as you wrote, Apple will not let the agent delegate her privileges to create distribution profiles.
我去过那儿。选项 2 或 3 是不可能的。选项 4 是理想的,但正如您所写的,Apple 不会让代理委托她创建分发配置文件的权限。
So basically, your only option is for you to get the distribution profile defined with their account. In order for you to handle it, you would need to login as their agent, which is not an option.
因此,基本上,您唯一的选择是获取使用他们的帐户定义的分发配置文件。为了让您处理它,您需要以他们的代理身份登录,这不是一个选项。
So theywill have to do it. There is no way around that.
所以他们将不得不这样做。没有办法解决这个问题。
They will also have to invite you as a member of their product development team on their account. You will need to be an admin. That's mean you will have to send a signing certificate request as outlined by Apple.
他们还必须邀请您成为他们的产品开发团队的成员。您将需要成为管理员。这意味着您必须按照 Apple 的规定发送签名证书请求。
Finally, they will have to download and send you the distribution provisioning profiles they created.
最后,他们必须下载并向您发送他们创建的分发配置文件。
With all that, you will be able to sign your application with their resources.
有了所有这些,您将能够使用他们的资源签署您的应用程序。
回答by Joshua Smith
I just got off the phone with Apple. They say this is the only way to do it: https://developer.apple.com/library/ios/#qa/qa1763/_index.html
我刚刚和苹果通了电话。他们说这是唯一的方法:https: //developer.apple.com/library/ios/#qa/qa1763/_index.html
The client adds you to their team, and gives you specific privileges.
客户将您添加到他们的团队中,并为您提供特定的权限。