您如何为Mac App Store编码框架包? [英] How do you codesign framework bundles for the Mac App Store?
问题描述
最近提交后,出现以下错误:
After a recent submission I have gotten the following error:
无效签名-嵌套的应用程序捆绑包(FooBar.app/Contents/Frameworks/GData.framework)未签名,签名无效或未使用Apple提交证书签名.有关更多信息,请参考《代码签名和应用程序沙箱指南》.
Invalid Signature - the nested app bundle (FooBar.app/Contents/Frameworks/GData.framework) is not signed, the signature is invalid, or it is not signed with an Apple submission certificate. Refer to the Code Signing and Application Sandboxing Guide for more information.
无效签名-嵌套的应用程序捆绑包(FooBar.app/Contents/Frameworks/Growl.framework)未签名,签名无效或未使用Apple提交证书签名.有关更多信息,请参考《代码签名和应用程序沙箱指南》.
Invalid Signature - the nested app bundle (FooBar.app/Contents/Frameworks/Growl.framework) is not signed, the signature is invalid, or it is not signed with an Apple submission certificate. Refer to the Code Signing and Application Sandboxing Guide for more information.
无效签名-嵌套的应用程序捆绑包libcurl(FooBar.app/Contents/Frameworks/libcurl.framework)未签名,签名无效或未使用Apple提交证书签名.有关更多信息,请参考《代码签名和应用程序沙箱指南》.
Invalid Signature - the nested app bundle libcurl (FooBar.app/Contents/Frameworks/libcurl.framework) is not signed, the signature is invalid, or it is not signed with an Apple submission certificate. Refer to the Code Signing and Application Sandboxing Guide for more information.
因此,我按照技术说明2206 签名了所有框架包:
So I signed all the framework bundles per Technote 2206:
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libcurl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libssh2.1.dylib
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./Growl.framework/Versions/A/Growl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./GData.framework/Versions/A/GData
技术说明2206说:
签名框架
由于框架是捆绑销售,因此可以得出结论,您可以直接签署框架似乎是合乎逻辑的.然而,这种情况并非如此.为了避免在签署框架时出现问题,请确保您签署的是特定版本而不是整个框架:
Seeing as frameworks are bundles it would seem logical to conclude that you can sign a framework directly. However, this is not the case. To avoid problems when signing frameworks make sure that you sign a specific version as opposed to the whole framework:
#这是错误的方式:
codesign -s my-signing-identity ../FooBarBaz.framework
codesign -s my-signing-identity ../FooBarBaz.framework
#这是正确的方法:
codesign -s我的签名身份../FooBarBaz.framework/Versions/A
codesign -s my-signing-identity ../FooBarBaz.framework/Versions/A
当我尝试验证结果时,对我来说看起来不错:
And when I try to verify the results, it looks good to me:
% codesign -vvv FooBar.app/Contents/Frameworks/libcurl.framework
FooBar.app/Contents/Frameworks/libcurl.framework: valid on disk
FooBar.app/Contents/Frameworks/libcurl.framework: satisfies its Designated Requirement
% codesign -vvv FooBar.app/Contents/Frameworks/Growl.framework
FooBar.app/Contents/Frameworks/Growl.framework: valid on disk
FooBar.app/Contents/Frameworks/Growl.framework: satisfies its Designated Requirement
为了娱乐,我确实尝试直接签署框架包,但仍然被拒绝.但这正是文档所说的不做.
For fun, I did try signing the framework bundle directly and it was still rejected. But that is exactly what the documentation said not to do.
有人猜测为什么那会被认为是无效的?我正在使用与我的应用进行代码签名相同的证书-过去一直有效的证书.
Any guesses why that would be considered invalid? I am using the same cert that I use to code sign my app -- the one that has worked in the past.
我唯一的猜测是与现有的plists(我是否需要在框架的Info.plists中拥有标识符?)或权利有关-有任何建议吗?
My only guess would be something to do with the existing plists (do I need to own the identifiers in the framework's Info.plists?) or entitlements -- any suggestions?
推荐答案
基于baptr的回答,我开发了这个shell脚本,该脚本对我的所有框架和其他二进制资源/辅助可执行文件(当前受支持的类型:dylib,bundle和登录项):
Based on baptr’s answer, I have developed this shell script that codesigns all my frameworks and other binary resources/auxiliary executables (currently supported types: dylib, bundle, and login items):
#!/bin/sh
# WARNING: You may have to run Clean in Xcode after changing CODE_SIGN_IDENTITY!
# Verify that $CODE_SIGN_IDENTITY is set
if [ -z "${CODE_SIGN_IDENTITY}" ] ; then
echo "CODE_SIGN_IDENTITY needs to be set for framework code-signing!"
if [ "${CONFIGURATION}" = "Release" ] ; then
exit 1
else
# Code-signing is optional for non-release builds.
exit 0
fi
fi
if [ -z "${CODE_SIGN_ENTITLEMENTS}" ] ; then
echo "CODE_SIGN_ENTITLEMENTS needs to be set for framework code-signing!"
if [ "${CONFIGURATION}" = "Release" ] ; then
exit 1
else
# Code-signing is optional for non-release builds.
exit 0
fi
fi
ITEMS=""
FRAMEWORKS_DIR="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -d "$FRAMEWORKS_DIR" ] ; then
FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle" | sed -e "s/\(.*framework\)/\1\/Versions\/A\//")
RESULT=$?
if [[ $RESULT != 0 ]] ; then
exit 1
fi
ITEMS="${FRAMEWORKS}"
fi
LOGINITEMS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems/"
if [ -d "$LOGINITEMS_DIR" ] ; then
LOGINITEMS=$(find "${LOGINITEMS_DIR}" -depth -type d -name "*.app")
RESULT=$?
if [[ $RESULT != 0 ]] ; then
exit 1
fi
ITEMS="${ITEMS}"$'\n'"${LOGINITEMS}"
fi
# Prefer the expanded name, if available.
CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then
# Fall back to old behavior.
CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}"
fi
echo "Identity:"
echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}"
echo "Entitlements:"
echo "${CODE_SIGN_ENTITLEMENTS}"
echo "Found:"
echo "${ITEMS}"
# Change the Internal Field Separator (IFS) so that spaces in paths will not cause problems below.
SAVED_IFS=$IFS
IFS=$(echo -en "\n\b")
# Loop through all items.
for ITEM in $ITEMS;
do
echo "Signing '${ITEM}'"
codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" --entitlements "${CODE_SIGN_ENTITLEMENTS}" "${ITEM}"
RESULT=$?
if [[ $RESULT != 0 ]] ; then
echo "Failed to sign '${ITEM}'."
IFS=$SAVED_IFS
exit 1
fi
done
# Restore $IFS.
IFS=$SAVED_IFS
- 将其保存到项目中的文件中.我将副本保存在项目根目录的
Scripts
子目录中.- 我的矿被称为
codesign-frameworks.sh
.
- 我的矿被称为
- Save it to a file in your project. I keep my copy in a
Scripts
subdirectory in my project’s root.- Mine is called
codesign-frameworks.sh
.
- Mine is called
- 您可以将其称为"Codesign嵌入式框架".
您是否仍会收到"身份":模棱两可(匹配:…"错误,请在下面评论.这种情况不再发生.
Should you still get an "Identity: ambiguous (matches: …" error, please comment below. This should not happen anymore.
2012年11月14日更新:在"codesign-frameworks.sh"中添加了对名称中带有特殊字符(不包括单引号)的框架的支持.
Updated 2012-11-14: Adding support for frameworks with special characters in their name (this does not include single quotes) to "codesign-frameworks.sh".
2013年1月30日更新:在"codesign-frameworks.sh"的所有路径(应包括单引号)中添加了对特殊字符的支持.
Updated 2013-01-30: Adding support for special characters in all paths (this should include single quotes) to "codesign-frameworks.sh".
2013年10月29日更新:添加了实验性dylib支持.
Updated 2013-10-29: Adding experimental dylib support.
2013年11月28日更新:添加了权利支持.改善实验性的dylib支持.
Updated 2013-11-28: Adding entitlements support. Improving experimental dylib support.
2014年6月13日更新:修复了包含(嵌套)框架的框架的代码签名问题.这是通过在find
中添加-depth
选项来完成的,这会导致find
进行深度优先遍历.由于此处描述的问题,这已成为必要.简而言之:一个包含包的捆绑包必须在其嵌套包已签名的情况下才能签名.
Updated 2014-06-13: Fixing codesigning issues with frameworks containing (nested) frameworks. This was done by adding -depth
option to find
, which causes find
to do a depth-first traversal. This has become necessary, because of the issue described here. In short: a containing bundle can only be signed if its nested bundles are signed already.
2014年6月28日更新:添加了实验包支持.
Updated 2014-06-28: Adding experimental bundle support.
2014-08-22更新:改进代码并防止还原IFS失败.
Updated 2014-08-22: Improving code and preventing failure to restore IFS.
2014年9月26日更新:添加了对登录项的支持.
Updated 2014-09-26: Adding support for login items.
2014年10月26日更新:引用目录检查.这样可以解决包括特殊字符在内的路径的第31/42行:参数过多"错误,以及导致的代码对象根本没有签名"错误.
Updated 2014-10-26: Quoting directory checks. This fixes the "line 31/42: too many arguments" errors and the resulting " code object is not signed at all" error for paths including special characters.
2014年11月7日更新:解决了在Xcode中使用自动身份解析时出现的含糊不清的身份错误(例如"Mac Developer:ambiguous…").您不必再显式设置身份,只需使用"Mac Developer"即可!
Updated 2014-11-07: Resolving the ambiguous identity error (like "Mac Developer: ambiguous …") when using automatic identity resolution in Xcode. You don’t have to explicitly set the identity anymore and can just use "Mac Developer"!
2015年8月7日更新:改进语义.
Updated 2015-08-07: Improving semantics.
欢迎改进!
这篇关于您如何为Mac App Store编码框架包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!