xcode - 如何为 Mac App Store 协同设计框架包?

标签 xcode app-store-connect codesign mac-app-store

最近提交后,我收到以下错误:

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.

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.

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.

所以我按照 Technote 2206 签署了所有框架 bundle :

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 说:

Signing Frameworks

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:

# This is the wrong way:

codesign -s my-signing-identity ../FooBarBaz.framework

# This is the right way:

codesign -s my-signing-identity ../FooBarBaz.framework/Versions/A

当我尝试验证结果时,它对我来说看起来不错:

% 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

为了好玩,我尝试直接签署框架 bundle ,但它仍然被拒绝。但这正是文档所说不要做的事情。

你猜为什么这会被认为是无效的?我使用的证书与我用来对我的应用程序进行代码签名的证书相同——过去一直有效的证书。

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

最佳答案

根据 baptr 的回答,我开发了这个 shell 脚本,它对我的​​所有框架和其他二进制资源/辅助可执行文件进行了协同设计(当前支持的类型:dylib、bundle 和登录项):

#!/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
  2. 在“复制嵌入式框架”构建阶段之后添加“运行脚本”构建阶段。
    • 您可以将其称为“协同设计嵌入式框架”。
  3. ./codesign-frameworks.sh(或您在上面调用脚本的任何内容)粘贴到脚本编辑器文本字段中。如果您将脚本存储在子目录中,请使用 ./Scripts/codesign-frameworks.sh
  4. 构建您的应用。所有捆绑的框架都将进行协同设计。

如果您仍然遇到“身份:不明确(匹配:...”错误,请在下面发表评论。这种情况不应再发生。

2012 年 11 月 14 日更新:向“codesign-frameworks.sh”添加对名称中包含特殊字符(不包括单引号)的框架的支持。

更新于 2013 年 1 月 30 日:在“codesign-frameworks.sh”中添加对所有路径中特殊字符(应包括单引号)的支持。

2013 年 10 月 29 日更新:添加实验性 dylib 支持。

2013 年 11 月 28 日更新:添加权利支持。改进实验性 dylib 支持。

更新于 2014 年 6 月 13 日:修复包含(嵌套)框架的框架的协同设计问题。这是通过向 find 添加 -深度 选项来完成的,这会导致 find 进行深度优先遍历。这已成为必要,因为the issue described here 。简而言之:只有当其嵌套 bundle 已经签名时,才能对包含 bundle 进行签名。

2014-06-28 更新:添加实验性 bundle 支持。

2014-08-22 更新:改进代码并防止恢复 IFS 失败。

2014-09-26 更新:添加对登录项的支持。

更新于 2014 年 10 月 26 日:引用目录检查。这修复了“第 31/42 行:参数太多”错误以及包含特殊字符的路径导致的“代码对象根本没有签名”错误。

更新于 2014 年 11 月 7 日:解决在 Xcode 中使用自动身份解析时出现的不明确身份错误(例如“Mac Developer:不明确……”)。您不必再显式设置身份,只需使用“Mac Developer”即可!

2015-08-07 更新:改进语义。

欢迎改进!

关于xcode - 如何为 Mac App Store 协同设计框架包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7697508/

相关文章:

swift - 在应用内购买多个产品

xcode - 新的iTunes Connect-未找到合适的应用程序记录。验证您的 bundle 标识符

ios - 应用程序未通过代码设计验证。签名无效,包含不允许的权利,或者未使用分发签名

macos - 在 OS X 10.11 中,shell 脚本包装应用程序的签名是否已损坏?

macos - 如何在 Windows 机器的 ssh session 下签署 macOS 上的 Delphi 应用程序?

ios - 添加单元测试时 Mach-O 链接器错误 - XCode

iphone - 识别字符/手写字符

ios - Sierra : Keychain ignores access control settings and UI-prompts for permission 中的安全/代码设计

Xcode 6.1 对 git 的表现很奇怪

ios - 快速转换为可选值