您如何为 Mac App Store 设计框架包? [英] How do you codesign framework bundles for the Mac App Store?

查看:34
本文介绍了您如何为 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 说:

Technote 2206 says:

签名框架

将框架视为捆绑包,因此得出您可以直接签署框架的结论似乎是合乎逻辑的.然而,这种情况并非如此.为避免签署框架时出现问题,请确保您签署的是特定版本而不是整个框架:

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 my-signing-identity ../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.

我唯一的猜测是与现有的 plist(我是否需要拥有框架的 Info.plist 中的标识符?)或权利有关——有什么建议吗?

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

  1. 将其保存到项目中的文件中.我将副本保存在项目根目录的 Scripts 子目录中.
    • 我的名为 codesign-frameworks.sh.
  1. 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.
  • 您可以将其称为代码设计嵌入式框架".

如果您仍然收到Identity: ambiguous (matches: ...") 错误,请在下方评论.这种情况不应再发生.

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-01-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-06-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-06-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-09-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-08-07 更新:改进语义.

Updated 2015-08-07: Improving semantics.

欢迎改进!

这篇关于您如何为 Mac App Store 设计框架包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆