您如何为Mac App Store编码框架包?


81

最近提交之后,出现以下错误:

无效的签名-嵌套的应用程序捆绑包(FooBar.app/Contents/Frameworks/GData.framework)未签名,签名无效或未使用Apple提交证书签名。有关更多信息,请参考《代码签名和应用程序沙箱指南》。

无效的签名-嵌套的应用程序捆绑包(FooBar.app/Contents/Frameworks/Growl.framework)未签名,签名无效或未使用Apple提交证书签名。有关更多信息,请参考《代码签名和应用程序沙箱指南》。

无效的签名-嵌套的应用程序捆绑包libcurl(FooBar.app/Contents/Frameworks/libcurl.framework)未签名,签名无效或未使用Apple提交证书签名。有关更多信息,请参考《代码签名和应用程序沙箱指南》。

因此,我按照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

Technote 2206说:

签名框架

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

#这是错误的方式:

代码签名-s我的签名身份../FooBarBaz.framework

#这是正确的方法:

代码签名-s我的签名身份../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

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

任何猜测为何将其视为无效?我使用了与我的应用进行代码签名相同的证书-过去一直有效。

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


我在提交我的应用程序时也发现了这一点。值得庆幸的是,苹果没有拒绝它,但指出我们以后必须签署框架。我认为最好在Growl谷歌代码问题页面上发布,很快人们就会遇到同样的问题。
koo

2
使用Growl框架提交应用程序时,也会遇到此问题。我猜想您将必须将growl.framework捆绑包标识符更改为您自己的标识符,然后对其进行代码签名。
安德鲁

这很奇怪:我已经发布了一个应用程序,其中包括两个未签名的框架(CorePlot和MacRuby)。我只对应用程序捆绑包运行一次code sign命令,并且该应用程序已被接受,对框架没有任何评论。现在,如果您查看应用程序捆绑包(bit.ly/charterapp),则两个框架似乎都已签名。您是否尝试过对整个应用程序进行签名?
p4010 2011年

@ p4010,我知道了-他们以前没有签名。例如,低吼只是他们分发的笔直捆。现在,我已经在商店中使用了此应用程序一段时间,因此我认为这与新的沙盒游戏有关。您何时提交您的应用程序?
csexton 2011年

@Andrew,更改捆绑包标识符对您有用吗?
csexton 2011年

Answers:


45

根据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. 在“复制嵌入式框架”构建阶段之后立即添加“运行脚本”构建阶段。
    • 您可以将其称为“ Codesign嵌入式框架”。
  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日更新:解决了包含(嵌套)框架的框架的代码签名问题。这是通过向中添加-depth选项来完成的find,从而导致find进行深度优先遍历。由于这里描述的问题,这已成为必要。简而言之:只有在其嵌套捆绑包已签名的情况下,才可以对其进行签名。

2014年6月28日更新:添加了实验捆绑包支持。

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

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

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

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

2015年8月7日更新:改善语义。

欢迎改进!


谢谢您,不过只是一个注释,如果您的目标名称中有空格,那么该注释将不起作用。我试图修复,但无法正常工作,因此更改了目标。
克雷格

当FRAMEWORK_DIR的名称中包含空格/特殊字符时,现在应该可以使用。
2012年

但是,我还需要通过在codesign命令的末尾添加“ --timestamp”来禁用timestamp选项。
Elmer Cat

有趣。您是@Elmer Cat,偶然地在未发布的OS X版本上执行此操作吗?手册页描述了具有“特定于系统的默认行为”的选项。
2013年

1
Elmer Cat-我不知道您正在运行的Xcode的版本,但是我使用的是5.0.1,它肯定不会自动对我的框架进行签名。我一直在撕头发,直到找到这个脚本。
布莱恩

11

您的注释显示您在捆绑软件的版本目录中的对象上签名。技术说明显示对目录本身进行签名。

以下内容更符合Technote:

codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./Growl.framework/Versions/A
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./GData.framework/Versions/A

4

这就是我修复它的方式;

  • 输入目标的构建设置
  • 找到“其他代码签名标志”行
  • 在发布参数中输入--deep
  • 关闭XCode
  • 输入Mac上的派生数据文件夹,然后删除旧的派生数据(默认路径为:/ Users / YOUR_USER_NAME / Library / Developer / Xcode / DerivedData)
  • 打开Xcode并构建

构建存档后,再次提交应用程序...


3
在梦想世界中,“-deep”会按预期工作,但我们并不生活在梦想世界中……
Mike

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.