Hello!
Thank you very much for nw.js!
Me and my colleagues are currently trying to prepare our nwjs app for Mac App Store distribution. But there is a lack of information on how to do it properly.
We use NWJS 0.27.1 on Mac OS 10.13.2. The documentation suggests to use MAS helper script, but it seems to be designed for nwjs 0.19.5, whereas our project uses latest nwjs features such as importNWBin.
Still, we've tried to sign our app with that script with entitlements relevant to our app features. Unfortunately the application signed with build_mas.py silently crashes upon start regardless of signing identity set in the configuration file. Here is a crash log that was captured via OS X Console app:
app-signed-via-build_mas-crash-log.txt
We have tested build_mas.py with these kinds of identity:
All the necessary certificates and provision profiles were properly installed on the system that has been used for a code signing.
We have also tried signing our product with the following self-made script:
#!/bin/sh
APP_IDENTITY="Mac Developer: Our Identity (...)"
ENTITLEMENTS_CHILD="entitlements-child.plist"
ENTITLEMENTS_PARENT="entitlements-parent.plist"
APP="Our App Name.app"
sign () {
OBJECT=$1
ENTITLEMENTS=$2
codesign --force --verbose --verify --sign "$APP_IDENTITY" --entitlements "$ENTITLEMENTS" --deep "$OBJECT"
codesign --verify --deep --strict --verbose=2 "$OBJECT"
}
sign "$APP/Contents/Versions/63.0.3239.84/nwjs Framework.framework/libnode.dylib" "$ENTITLEMENTS_CHILD"
sign "$APP/Contents/Versions/63.0.3239.84/nwjs Framework.framework/Helpers/crashpad_handler" "$ENTITLEMENTS_CHILD"
sign "$APP/Contents/Versions/63.0.3239.84/nwjs Framework.framework/XPCServices/AlertNotificationService.xpc" "$ENTITLEMENTS_CHILD"
sign "$APP/Contents/Versions/63.0.3239.84/nwjs Framework.framework/nwjs Framework" "$ENTITLEMENTS_CHILD"
# sign "$APP/Contents/Versions/63.0.3239.84/nwjs Framework.framework" "$ENTITLEMENTS_CHILD"
sign "$APP/Contents/Versions/63.0.3239.84/nwjs Helper.app" "$ENTITLEMENTS_CHILD"
sign "$APP/Contents/Versions/63.0.3239.84/libffmpeg.dylib" "$ENTITLEMENTS_CHILD"
sign "$APP" "$ENTITLEMENTS_PARENT"
The instructions listed above work correctly and the codesign validation shows valid on disk / satisfies its Designated Requirement status for every resource it is applied to (except nwjs Framework.framework that will be mentioned further). However the application signed with this script crashes in the same way as described earlier. This time the crash log differs from the one attached above, but it also has a lot in common:
app-signed-for-development-crash-log.txt
It is also worth to note that both of the above scripts (build_mas.py and the one we created ourselves) have displayed a following error after the attempt to sign nwjs Framework.framework
Our App Name.app/Contents/Versions/63.0.3239.84/nwjs Framework.framework: unsealed contents present in the root directory of an embedded framework
I suppose that the reason of this error is that the nwjs Framework.framework itself consists of a large number of resources each of which should be signed on it's own as described in the apple documentation https://developer.apple.com/library/content/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html.
Additionally we have tried to manually sync our app's bundle identifier and display name with PlistBuddy utility but it doesn't seem to solve our problem as well.
BUNDLE_ID="our.app.bundle.id"
APP_NAME="Our App Name"
sed -i '' "s#(CFBundleDisplayName[^\"]\")[^\"](\")#\1$APP_NAME\2#g" "$APP/Contents/Resources/en.lproj/InfoPlist.strings"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID" "$APP/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $APP_NAME" "$APP/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID.helper" "$NWJS_HELPER/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $APP_NAME Helper" "$NWJS_HELPER/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups $BUNDLE_ID" "$ENTITLEMENTS_PARENT"
Is there a way to make it work? We would really appreciate if someone shared some experience or advice on how to do MAS code signing properly. We will be happy for any help. Thanks in advance!
Good news everyone!
The reason of the crash was the usage of the apple sandbox entitlement. If it is set to false app starts normally.
However it would be nice to find out the problem that leads our app to crash while running in the sandbox. The log attached to the issue says much about sandbox errors. So any ideas on how to solve them are welcome!
This issue is obviously related to #6041
Ok, I've found a fix to the unsealed contents error. It is caused by a libnode.dylib placed in the root folder of nwjs.app/Contents/Versions/63.0.3239.108/nwjs Framework.framework/.
According to Apple documentation:
...if a bundle has a Contents or Versions directory at its top level, there may be no other files or directories alongside them. The one exception is that alongside Versions, there may be symlinks to files in Versions/Current.
So the way to fix the problem is to move libnode.dylib to a nwjs.app/Contents/Versions/63.0.3239.108/nwjs Framework.framework/Versions/A/ folder and make a symbolic link to it in nwjs Framework.framework so its content will look like this:
drwxr-xr-x@ 8 user group 256 Dec 23 20:36 .
drwxr-xr-x@ 5 user group 160 Dec 23 20:36 ..
lrwxr-xr-x 1 user group 24 Dec 16 20:47 Helpers -> Versions/Current/Helpers
lrwxr-xr-x 1 user group 26 Dec 16 20:47 Resources -> Versions/Current/Resources
drwxr-xr-x@ 4 user group 128 Dec 16 20:47 Versions
lrwxr-xr-x 1 user group 28 Dec 16 20:47 XPCServices -> Versions/Current/XPCServices
lrwxr-xr-x 1 user group 24 Dec 23 20:36 libnode.dylib -> Versions/A/libnode.dylib
lrwxr-xr-x 1 user group 31 Dec 16 20:47 nwjs Framework -> Versions/Current/nwjs Framework
This fix helps to sign the application for a MAS distribution properly that can be proved via spctl utility:
spctl --assess --type execute Your app name.app
spctl --assess --verbose=4 Your app name.app
But unfortunately the application still can not be submitted to Mac App Store because the spctl will reject it whenever you replace an app bundle id with your own (keeping in mind that Info.plist can be edited strictly before the app will be signed).
Also the solution described above doesn't help to add the app sandbox capability. The application keeps crashing on start every time the sandbox option appears in entitlements.plist.
Looking forward for any help or advice.
Yesterday I have finally gained success with getting spctl accepted status for our application. Here's a very useful application that helped me to discover some more unsealed contents in the Resources folder inside the application.
But the final fix was to add our team id to the application bundle id in the app entitlements.
BTW the entitlements-parent.plist file distributed with build_mas.py has a little bit incorrect format. According to apple docs the com.apple.security.application-groups key should have a value of type array of strings even if there is only one string.
The value for this key must be of type array, and must contain one or more string values, each of which must consist of your development team ID, followed by a period, followed by an arbitrary name chosen by your development team.
So the correct format for this entitlement is
<key>com.apple.security.application-groups</key>
<array>
<string>TEAM_ID.your.app.bundle.id</string>
</array>
Unfortunately the issue with app sandboxed mode still remains unsolved. Still waiting for any help or feedback on this subject.
Thanks everyone for the attention. Merry xmas and sorry for my awful english.
@tankakatan thank you, I will try your solution. Spent a lot of hours with unsealed contents. Could you add commands that you do to fix problem. It will be nice
Also, did you build app with nw-builder?
@Arti3DPlayer here's my script for that:
# Set PATH_TO_YOUR_APP variable first
VERSION_NUMBER=`ls "${PATH_TO_YOUR_APP}/Contents/Versions/"`
NWJS_FRAMEWORK="$PATH_TO_YOUR_APP/Contents/Versions/$VERSION_NUMBER/nwjs Framework.framework"
LIBNODE_DYLIB="libnode.dylib"
LIBNODE_LINK_TO="Versions/A/$LIBNODE_DYLIB"
echo fixing nwjs Framework unsealed content
pushd "$NWJS_FRAMEWORK"
mv "$LIBNODE_DYLIB" "$LIBNODE_LINK_TO"
ln -s "$LIBNODE_LINK_TO"
popd
To synchronise bundle ids you can use PlistBuddy – a very handy tool for that. So my script is something like this:
# Set BUNDLE_ID variable with your app bundle id
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID" "$PATH_TO_YOUR_APP/Contents/Info.plist"
# Set PATH_TO_ENTITLEMENTS_PARENT_PLIST variable
# Set TEAM_ID variable with your team id
/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups:0 $TEAM_ID.$BUNDLE_ID" "$PATH_TO_ENTITLEMENTS_PARENT_PLIST"
Also i suggest you to update CFBundleIdentifier in all Info.plist files you will find inside your app's package. Add the corresponding postfix to the bundle id of each resource. For example, use $BUNDLE_ID.helper in Info.plist of nwjs Helper.app.
@tankakatan thanks, it works! But Users still get message that app from Unknown developer. i used mas.py script
And yes still crashing problem with Sandbox=Yes that makes impossible to upload app to Appstore
@Arti3DPlayer it is ok to see the unknown developer warning until your users do not have to manually allow gatekeeper to run your app. It means that as long as you need to go to the system security settings to open your application its code signature is incorrect.
Sadly i haven't found a solution to the sandbox issue yet. The apple console shows a number of different errors refer to crashpad_handler and nwjs Framework itself. Сurrently i'm trying to build nwjs from the sources to try to fix all that errors one by one.
@tankakatan I fixed my problem by set the full name of certificate in build.cfg file:
## [REQUIRED] Your Application Certificate Identity
ApplicationIdentity = Developer ID Application: MyComapny Name (TT666666)
And its weird because when I used only code from brackets in this line(TT666666) it used 3rd Party Mac Developer Application that needed for appstore, but doesn't work for outside app. For now after download my app gatekeeper only warn user that
App was downloaded from internet, do you want to open it?
I didn't test this with auto update yet. Hope I will be able to swap apps programmatically
Found a lot of useful info from electron documentation:
https://www.electron.build/code-signing
@tankakatan, @Arti3DPlayer and @rogerwang - does this all means that we can finally upload the latest NWJS to the MAS - or is still a special build needed?
@gpetrov nope, i have not succeed with MAS distribution so far. I also tried to build nwjs from the sources, but alas, failed to do so.
@Arti3DPlayer Have you successfully uploaded your app to MAS?
@tankakatan I have tried everything and getting this problem when trying to sign my app:
Warning: unable to build chain to self-signed root for signer
Have you found a solution to sign the app? I can't even sign the app for outside MAS use. I sign it with Developer ID and it gives unidentified developer warning, I sign with 3rd Party Mac Developer certificate and I get the above warning and the app crashes on launch.
Yes, I'm not able to upload to MAS too, but sign app works fine even with autoupdates, so I don't require mas for now
@denigada try to use https://itunes.apple.com/us/app/rb-app-checker-lite/id519421117?mt=12 to identify what problems do you have. You can open and compare some popular apps and yours. I did this with "docker" app to make sure that I have all the same certificates
@denigada @Arti3DPlayer i have built nwjs from the sources to find out the details of the sandboxed app crash and discovered that the reason of the problem is in the chromium itself. Here's the the google groups discussion where i have described it. Unfortunately i haven't got any feedback yet. Probably we should communicate with electron devs to ask them to share their experience.
@tankakatan thanks for all your effort!
reflecting your work on my code still gives me
./Contents/Versions/72.0.3626.121/nwjs Framework.framework: unsealed contents present in the root directory of an embedded framework
any chance you can post your script as a whole?
here is mine:
https://gist.github.com/gretel/99bc84729c9b5298c277dad326d578c6
thank you!
@gretel i haven't been working with nw.js since my last comment here or so, therefore i believe my script is completely outdated and useless now. But the idea of solving your issue is pretty simple. That is to find all the unsigned items in the contents of your app. RB App Checker will help you to accomplish that (it seems being distributed outside of MAS now, but still available for download). This extremely useful tool will show you every unsealed item of your app's content, and you'll be able to sign them all just the same way as you do with other resources. You can find an example of signing script in the initial post of this thread.
@tankakatan thanks for getting back to me!
i have been using the tool you mentioned prior to asking.. it does show only one "red" issue:

leaving me confused, still.
@tankakatan updating to nwjs 0.42.2 and applying https://gist.github.com/gretel/99bc84729c9b5298c277dad326d578c6 does get rid of the unsealed contents present warning - still "rejected" - but does open using the ctrl trick. thanks again.
I able to distribute my app manually and have managed to get signing working. However, now I want to distribute via MAS and I'm hitting a bunch of interesting issues
ERROR ITMS-90511: "CFBundleIdentifier Collision. The Info.plist CFBundleIdentifier value 'io.nwjs.nwjs.framework.AlertNotificationService' of 'MYAPP.app/Contents/Frameworks/nwjs Framework.framework/Versions/78.0.3904.108/XPCServices/AlertNotificationService.xpc' is already in use by another application."
ERROR ITMS-90511: "CFBundleIdentifier Collision. The Info.plist CFBundleIdentifier value 'io.nwjs.nwjs.helper' of 'MYAPP.app/Contents/Frameworks/nwjs Framework.framework/Versions/78.0.3904.108/Helpers/nwjs Helper (GPU).app' is already in use by another application."
ERROR ITMS-90511: "CFBundleIdentifier Collision. The Info.plist CFBundleIdentifier value 'io.nwjs.nwjs.helper' of 'MYAPP.app/Contents/Frameworks/nwjs Framework.framework/Versions/78.0.3904.108/Helpers/nwjs Helper.app' is already in use by another application."
any suggestions on how to avoid the bundleid collisions?
@rogerwang is there any documentation available on getting an NWJS app into MAS? Theres some comments spread across multiple GitHub issues, but nothing definitive. Also, the comments seem relative to disparate versions of NWJS, so its difficult to tell how to get the latest version into MAS (if even possible)
I don't think the latest version supports MAS because Chromium upstream doesn't support MAS. The latest version is mentioned in https://nwjs.readthedocs.io/en/latest/For%20Users/Advanced/Support%20for%20Mac%20App%20Store/
Thank you for the update
After much wrangling I can get past everything EXCEPT the sandbox flag.
As soon as you turn the sandbox flag on, MAS is satisfied, but the app won't actually run - it crashes on startup
@zkrige To fix the collision, I followed the Mac instructions in https://nwjs.readthedocs.io/en/nw28/For%20Users/Package%20and%20Distribute/#platform-specific-steps
(They are out of date. The helpers are now in a Helpers directory.)
So, I renamed CFBundleDisplayName and CFBundleExecutable in each plist file and while I was there I parsed the name and got the part in the parenthesis and added it to the CFBundleIdentifier.
For example: io.nwjs.nwjs.helper for nwjs Helper.app and io.nwjs.nwjs.helper.gui for nwjs Helper (GUI).app
Seems to have fixed the collision for me
Using a lot from https://github.com/nwjs/nw.js/issues/7117#issuecomment-581738908:
const { exec, execSync } = require('child_process');
const { createWriteStream, readdirSync, statSync, move, readFile, writeFile } = require('fs-extra');
const path = require('path');
const plist = require('simple-plist');
const log = require('fancy-log');
const DEFAULT_ENTITLEMENTS_PATH = 'app entitlements file path';
const INTERNAL_ENTITLEMENTS_PATH = 'internal entitlements file path';
const IDENTITY = 'your signing identity here';
/**
* Code sign .app or .dmg
* @param {String} filePath path to .app or .dmg
* @param {String} [entitlementsFilePath=DEFAULT_ENTITLEMENTS_PATH] path to entitlements file
*/
function codesign(filePath, entitlementsFilePath=DEFAULT_ENTITLEMENTS_PATH) {
log(`Signing ${filePath}...`);
execSync(`codesign -s "${IDENTITY}" --timestamp --options runtime --entitlements ${entitlementsFilePath} --force --deep "${filePath}"`);
log('Signed');
}
/**
* NWJS helper apps can be renamed with app name
* We need to fix colliding CFBundleIdentifier
* @param {String} file
* @param {String} appName
* @param {String} currentVersionDir
* @return {Promise<String>}
* @private
*/
async function _fixNWJSHelperApp(file, appName, currentVersionDir) {
let newFileName = file.replace('nwjs', appName);
log(`Working on ${file}`);
for (const helperFile of readdirSync(`${currentVersionDir}/Helpers/${file}/Contents/MacOS`)) {
let newHelperFileName = helperFile.replace('nwjs', appName);
let plistFile = `${currentVersionDir}/Helpers/${file}/Contents/info.plist`;
let plistString = await readFile(plistFile);
let plistObject = plist.parse(plistString);
plistObject.CFBundleDisplayName = newHelperFileName;
plistObject.CFBundleExecutable = newHelperFileName;
plistObject.CFBundleIdentifier = 'io.nwjs.nwjs.helper';
if (/\([A-Za-z]*\)/.test(newHelperFileName)) {
plistObject.CFBundleIdentifier += `.${newHelperFileName.match(/\(([A-Za-z]*)\)/)[1].toLowerCase()}`;
}
await writeFile(plistFile, plist.stringify(plistObject));
await move(`${currentVersionDir}/Helpers/${file}/Contents/MacOS/${helperFile}`, `${currentVersionDir}/Helpers/${file}/Contents/MacOS/${newHelperFileName}`);
}
await move(`${currentVersionDir}/Helpers/${file}`, `${currentVersionDir}/Helpers/${newFileName}`);
return newFileName;
}
/**
* Code sign .app
* @param {String} appPath
*/
async function codesignNWJSApp(appPath) {
log(`Signing NWJS App ${appPath}...`);
const items = [];
let appName = path.basename(appPath, path.extname(appPath));
const frameworksDir = `${appPath}/Contents/Frameworks/nwjs Framework.framework`;
// find current version in frameworks
let currentVersionDir;
for (const dir of readdirSync(`${frameworksDir}/Versions`)) {
if (statSync(`${frameworksDir}/Versions/${dir}`).isDirectory()) {
currentVersionDir = `${frameworksDir}/Versions/${dir}`;
break;
}
}
if (!currentVersionDir) {
log(`couldn't find "${frameworksDir}/Versions/[version]"`);
throw new Error('No current version found');
}
// add files in frameworks to code sign
for (const file of readdirSync(`${currentVersionDir}`)) {
if (file.endsWith('.dylib')) {
items.push(`${currentVersionDir}/${file}`);
}
}
for (let file of readdirSync(`${currentVersionDir}/Helpers`)) {
if (/^[a-z0-9_]*$/.test(file) || file.endsWith('.app')) {
if (file.endsWith('.app')) {
file = await _fixNWJSHelperApp(file, appName, currentVersionDir);
}
items.push(`${currentVersionDir}/Helpers/${file}`);
}
}
for (const file of readdirSync(`${currentVersionDir}/Libraries`)) {
if (file.endsWith('.dylib')) {
items.push(`${currentVersionDir}/Libraries/${file}`);
}
}
for (const file of readdirSync(`${currentVersionDir}/XPCServices`)) {
if (file.endsWith('.xpc')) {
items.push(`${currentVersionDir}/XPCServices/${file}`);
}
}
items.push(frameworksDir);
// code sign each executable in NWJS
for (const itemPath of items) {
codesign(itemPath, INTERNAL_ENTITLEMENTS_PATH);
}
// code sign the application
codesign(appPath);
}
@zkrige To fix the collision, I followed the Mac instructions in https://nwjs.readthedocs.io/en/nw28/For%20Users/Package%20and%20Distribute/#platform-specific-steps
(They are out of date. The helpers are now in a Helpers directory.)
So, I renamed CFBundleDisplayName and CFBundleExecutable in each plist file and while I was there I parsed the name and got the part in the parenthesis and added it to the CFBundleIdentifier.
For example: io.nwjs.nwjs.helper for nwjs Helper.app and io.nwjs.nwjs.helper.gui for nwjs Helper (GUI).app
Seems to have fixed the collision for me
Thank You - I figured this out and managed to do the same. The only problem remaining is the sandbox issue
well done @jssuttles ! Just a small note if you are having also native node modules included you have to sign them as well - so all *.node files.
I've built a bash script that does more or less what @jssuttles script does, but it also signs .node files
echo "==UPDATING PLIST ENTRIES=="
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID.helper" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $NAME Helper" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper.app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID.helper.gpu" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper (GPU).app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $NAME Helper (GPU)" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper (GPU).app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID.helper.plugin" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper (Plugin).app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $NAME Helper (PLUGIN)" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper (Plugin).app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID.helper.renderer" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper (Renderer).app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $NAME Helper (RENDERER)" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/Helpers/nwjs Helper (Renderer).app/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID.framework.AlertNotificationService" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/XPCServices/AlertNotificationService.xpc/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleDisplayName $NAME AlertNotificationService" "${OUTDIRECTORY}/${NAME}.app/Contents/Frameworks/nwjs Framework.framework/XPCServices/AlertNotificationService.xpc/Contents/Info.plist"
/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups:0 ${TEAM_ID}.${BUNDLE_ID}" "./installer/mac/entitlements_parent.plist"
echo ""
ITEMS=""
FRAMEWORKS_DIR="${OUTDIRECTORY}/${NAME}.app/Contents"
if [[ -d "$FRAMEWORKS_DIR" ]] ; then
FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle" -or -name "*.node")
RESULT=$?
if [[ ${RESULT} != 0 ]] ; then
exit 1
fi
ITEMS="${FRAMEWORKS}"
fi
ITEMS="${ITEMS}"$'\n'"$OUTDIRECTORY/$NAME.app"
IFS=$'\n'
for ITEM in ${ITEMS};
do
echo "==Signing child '$ITEM'=="
codesign --deep --verify --force --options runtime --timestamp --entitlements "./installer/mac/entitlements_child.plist" -s "$APP_CERT" "${ITEM}"
RESULT=$?
if [[ ${RESULT} != 0 ]] ; then
echo "Failed to sign '${ITEM}'."
unset IFS
exit 1
fi
done
unset IFS
echo "==Signing '$OUTDIRECTORY/$NAME.app'=="
codesign --deep --verify --force --options runtime --timestamp --entitlements "./installer/mac/entitlements_parent.plist" -s "$APP_CERT" "$OUTDIRECTORY/$NAME.app"
echo ""
echo "==Validating code signature and subsequent resources=="
spctl --assess -v "$OUTDIRECTORY/$NAME.app"
echo ""
echo "==Building Package $PACKAGE_NAME =="
productbuild --component "$OUTDIRECTORY/$NAME.app" /Applications --sign "$INSTALLER_CERT" "$OUTDIRECTORY/$PACKAGE_NAME"
echo ""
@zkrige I see your are adjusting the plists with the new helper names - but you don't have the rename itself included?
I'm using https://github.com/evshiron/nwjs-builder-phoenix which handles the app rename, icon and a few other things
Most helpful comment
Good news everyone!
The reason of the crash was the usage of the apple sandbox entitlement. If it is set to
falseapp starts normally.However it would be nice to find out the problem that leads our app to crash while running in the sandbox. The log attached to the issue says much about sandbox errors. So any ideas on how to solve them are welcome!