我知道这很长,所以这里有一个真正的简短摘要:
我正在尝试构建一个应用程序并将其他预构建的脚本或文件复制到
.app/Contents/MacOS
目录中。我可以得到一些有用的东西,仍然提示用户访问麦克风,但它不会通过公证(说签名不好)。我不知道我是否以不正确的方式构建 DMG 和/或 PKG,或者可能将文件复制到安装目标软管中?
如果我将预建文件复制到位,然后在归档后重新签署我的应用程序,我可以通过 Apple 的公证,但随后麦克风访问失败并因侵犯隐私而崩溃(就好像我从未指定权利一样)。
这是详细的较长版本:
我有一个应用程序myApp,它使用我从命令行构建的麦克风作为存档xcodebuild -scheme myApp archive -archivePath myApp.archive
。
如果我要在这里停下来,该应用程序就可以工作。我有适当的权利,启用代码强化并且NSMicrophoneUsageDescription
在我的 plist 中。
但是,我有各种其他资源必须包含在我的应用程序中。我想把它们放在myApp.app/Contents/MacOS
目录中。这些资源包括用于调试的 shell 脚本、辅助 Swift 工具等。
我发现不可能使用正确的签名和麦克风访问权限以及通过 Apple 的公证来构建此应用程序。
我通过在 Xcode 中为我的方案中的存档操作指定操作前和操作后脚本,将这些辅助应用程序复制到目标目录中。
行动前存档脚本
预操作脚本使用我的Developer ID 应用程序证书对所有辅助对象进行签名:
APP_SIGN_ID="Developer ID Application: MyCompany Inc. (XXXXXXXXXX)"
LOG="/tmp/archive.log"
rm -f $LOG
echo "Pre-action for archive" > $LOG
function sign_and_verify() {
echo "signing $1" >> $LOG
codesign --force --options runtime --verify --verbose --sign "$APP_SIGN_ID" "$1"
if [ $? -ne 0 ]; then
echo "failed signature" >> $LOG
exit 1
fi
}
# sign these things as a pre-action to archive and copy them to the Contents/MacOS in the post-action
sign_and_verify "${HOME}/src/bin/mydebugtool"
sign_and_verify "${HOME}/src/bin/myscript.sh"
动作后存档脚本
我的方案中存档的后操作脚本将这些已签名的资产复制到适当的位置(副本必须作为后操作 b/c 完成,存档目标目录在操作前阶段不存在):
LOG="/tmp/archive.log"
TARGETDIR="${ARCHIVE_PRODUCTS_PATH}/Applications/myApp.app/Contents/MacOS/"
function my_copy() {
echo "copying $1 to $2" >> $LOG
cp "$1" "$2"
if [ $? -eq 0 ]; then
echo "copy success" >> $LOG
else
echo "copy failure" >> $LOG
fi
}
my_copy "${HOME}/src/bin/mydebugtool" "${TARGETDIR}"
my_copy "${HOME}/src/bin/myscript.sh" "${TARGETDIR}"
然后我建立这个档案。如果我运行open <path-to-archive>/myApp.app
它会正确打开并提示访问麦克风。存档中的其他工具正确无误。
公证输出
但是,当我将存档内容捆绑到 DMG 或 PKG 中时,它无法通过以下方式进行公证:
{
"logFormatVersion": 1,
"jobId": "5a225fdb-d85d-41fa-8bde-1026xx92331a",
"status": "Invalid",
"statusSummary": "Archive contains critical validation errors",
"statusCode": 4000,
"archiveFilename": "myApp.dmg",
"uploadDate": "2019-08-20T20:22:08Z",
"sha256": "d93da550d2617246aead790a13afc6360ff5198764cfb779b785e06d463d4e32",
"ticketContents": null,
"issues": [
{
"severity": "error",
"code": null,
"path": "myApp.dmg/myApp.app/Contents/MacOS/myApp",
"message": "The signature of the binary is invalid.",
"docUrl": null,
"architecture": "x86_64"
}
]
}
很遗憾它失败了,因为它在 Mojave 上运行良好。未经公证,它永远不会在 Catalina 上运行。
所以我无法判断它是否因为我构建 DMG 或 PKG 的方式而失败,或者它是否因为我将内容放入Contents/MacOS目录而失败(即使它们已签名?)。
我如何构建 DMG
为了清楚起见,这是我用来组装 DMG 的小脚本,我正试图得到公证:
BASE_DIR=`pwd`"/myapp.archive.xcarchive/Products/Applications"
function create_dmg() {
echo "creating DMG"
rm -f temp.dmg
rm -f myApp.dmg
title=myApp
size=240
umount /Volumes/myApp
hdiutil create -srcfolder "${BASE_DIR}" -volname "${title}" -fs HFS+ \
-fsargs "-c c=64,a=16,e=16" -format UDRW -size ${size}m temp.dmg
device=$(hdiutil attach -readwrite -noverify -noautoopen temp.dmg | \
egrep '^/dev/' | sed 1q | awk '{print $1}')
mkdir /Volumes/"${title}"/.background
cp background.png /Volumes/"${title}"/.background/background.png
ln -s /Applications /Volumes/"${title}"/"Applications"
rm -rf /Volumes/"${title}"/.fseventsd
sleep 2
echo '
tell application "Finder"
tell disk "'${title}'"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {400, 100, 950, 500}
set theViewOptions to the icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to 150
set background picture of theViewOptions to file ".background:'background.png'"
set position of item "myApp" of container window to {120, 150}
set position of item "Applications" of container window to {430, 150}
set position of item ".background" of container window to {120, 525}
set position of item ".Trashes" of container window to {220, 525}
set position of item ".DS_Store" of container window to {320, 525}
set position of item ".fseventsd" of container window to {430, 525}
update without registering applications
delay 5
end tell
end tell
' | osascript
sync
sync
我如何构建 PKG
我还在构建一个也未能通过公证的 PKG。这是我构建 PKG 的脚本:
PKG_SIGN_ID="Developer ID Installer: My Company Inc. (XXXXXXXXX)"
BASE_DIR=`pwd`"/myapp.archive.xcarchive/Products/Applications"
function create_pkg() {
echo "creating pkg"
rm -f myApp.pkg
# generate plists
cd $BASE_DIR
pkgbuild --analyze --root ./myApp.app myApp.plist
# pkgbuild myApp
pkgbuild --scripts /tmp/installer-scripts --root "./myApp.app" --component-plist "./myApp.plist" --identifier "com.mycompany.myapp.myApp" --version "$VERSION" --install-location "/Applications/myApp.app" ./myApp.pkg
if [ $? -ne 0 ]; then
echo "failed pkgbuild for myApp.pkg"
rm -f myApp.pkg
exit 1
fi
# copy the installer resources
cp -r ../../res ./
# --synthesize will generate the Distribution.xml file
productbuild --synthesize --resources ./res --package myApp.pkg Distribution.xml
if [ $? -ne 0 ]; then
echo "failed productbuild synthesize for Distribution.xml"
rm -f myApp.pkg
exit 1
fi
# add our title to the Distribution.xml that was generated
# I can't believe I have to splice this in after the synthesize but I couldn't find another way
cat Distribution.xml | sed $'3i\\\n<title>MyApp</title>\n' > mod.xml
mv mod.xml Distribution.xml
cat Distribution.xml | sed $'3i\\\n<welcome file="welcome.html"/>\n' > mod.xml
mv mod.xml Distribution.xml
cat Distribution.xml | sed $'3i\\\n<background file="background.png" mime-type="image/png" scaling="tofit"/>\n' > mod.xml
mv mod.xml Distribution.xml
cat Distribution.xml | sed $'3i\\\n<background-darkAqua file="background.png" mime-type="image/png" scaling="tofit"/>\n' > mod.xml
mv mod.xml Distribution.xml
productbuild --resources ./res --sign "$PKG_SIGN_ID" --distribution Distribution.xml myApp.$VERSION.pkg
if [ $? -ne 0 ]; then
echo "failed signature"
rm -f myApp.pkg
exit 1
else
echo "Successfully built and signed myApp.$VERSION.pkg"
mv myApp.$VERSION.pkg ../../../
# remove the unsigned package so we don't accidentally distribute that
rm -f myApp.pkg
fi
}
我希望这不会太长以至于可以提供帮助的人停止阅读。我尽量简明扼要,但也要尽可能多地包含我认为合适的细节。
更新:为了验证我是否不正确地构建了 DMG,我注释掉了操作后存档脚本,构建了应用程序和 DMG 并对其进行了公证。因此,作为存档后操作的一部分,我将文件放入 Contents/MacOS 目录的某些事情破坏了签名。
**