Electron应用上架Mac App Store配置说明

由于业务需要Electron应用需要打包上架到Mac App Store,特做以下记录说明

1、下载所需证书文件

证书文件需要有:
  • 3rd Party Mac Developer Application
  • 3rd Party Mac Developer Installer
  • Developer ID Application
  • Apple Distribution
  • provisionprofile文件(苹果开发者后台生成并导出Sign In - Apple
  • Mac Developer(此证书为本地测试,非必要)
将证书安装到构建mac电脑上面,在钥匙串中显示如图:

如显示证书不受信任或者无效,安装Apple全球开发者关系认证媒介中间证书AppleWWDRCA
证书链接
https://developer.apple.com/certificationauthority/AppleWWDRCA.cer
https://www.apple.com/certificateauthority/AppleWWDRCAG3.cer
https://www.apple.com/certificateauthority/AppleWWDRCAG4.cer

2、准备构建文件

2.1:创建entitlements.mas.inherit.plist文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
2.1:创建entitlements.mas.plist文件(文件中替换自己的的团队id和项目构建id,团队ID一般为证书括号中的数据(2M******),项目构建id为appid(com.***.***))
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>团队id.项目构建id</string>
</array>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
2.3、准备provisionprofile文件,苹果导出的文件

3、配置构建文件package.json文件或者build.config.js(具体信息根据项目替换)

// bundleVersion 为 bundleNumber
// target 需要包括 mas
// extendInfo 需要增加 TeamId
// asarUnpack aras 压缩时过滤.node文件,否则无法对.node文件签名
// .provisioningProfile 文件在开发者网站下载
mas: {
hardenedRuntime: false,
type: 'distribution',
category: 'public.app-category.productivity',
entitlements: 'build/mas/entitlements.mas.plist',
entitlementsInherit: 'build/mas/entitlements.mas.inherit.plist',
provisioningProfile: 'build/mas/*****.provisionprofile',
},
buildVersion: '7',

mac: {
icon: 'build/icons/icon.icns',
extendInfo: {
ElectronTeamID: '2M********',
},
target: [
{
target: 'mas',
arch: 'x64',
},
],
entitlementsInherit: 'build/mas/entitlements.mas.inherit.plist',
type: 'distribution',
},

项目因为原来生成的dmg文件需要公证,已经指向了全局的env证书位置,而mas商城签名是根据provisionprofile自动调用的钥匙串中的证书,所以我另启了一个build.config.mas.js来构建mas

4、mas构建成功后添加auth.js对编译好的app进行文件权限操作(上传苹果商店可能会提示某些文件被root权限了),auth.js内容如下(具体信息根据项目替换)

var shell = require('child_process')
var path = './dist/mas/****.app'
var strRun = 'chmod -R 777 ' + path
shell.exec(strRun, function (code, stdout, stderr) {
console.log('Exit code:', code)
console.log('Program output:', stdout)
console.log('Program stderr:', stderr)
})

5、编写pkg构建文件bash.sh重新打包验签(具体信息根据项目替换)

#!/bin/bash

# 你的应用名称
APP="****"
# 要签名的应用路径
APP_PATH="./dist/mas/*****.app"
# APP_PATH="./dist/mas-arm64/*****.app"
# 生成安装包路径
RESULT_PATH="./dist/$APP.pkg"
# 开发者应用签名证书
APP_KEY="3rd Party Mac Developer Application: ****. (2M****)"
INSTALLER_KEY="3rd Party Mac Developer Installer: ***. (2M******)"
# 授权文件路径
CHILD_PLIST="./build/mas/entitlements.mas.inherit.plist"
PARENT_PLIST="./build/mas/entitlements.mas.plist"

FRAMEWORKS_PATH="$APP_PATH/Contents/Frameworks"
LIBRARY_PATH="$APP_PATH/Contents/Library"

oldIFS=$IFS
IFS=$'\n'
 
#递归循环验签
read_dir(){
for file in `ls $1`
do
if [ -d $1"/"$file ]
then
read_dir $1"/"$file
else
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$1/$file"
#echo $1"/"$file
fi
done
}
# 注意如果有用到 .node 文件,就需要签名。如果没有可以去掉
# codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/Resources/app.asar.unpacked/node_modules/XXX/XXX.node"


codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Electron Framework"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libEGL.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libGLESv2.dylib"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework/Versions/A/Libraries/libvk_swiftshader.dylib"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper (GPU).app/Contents/MacOS/$APP Helper (GPU)"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper (Plugin).app/Contents/MacOS/$APP Helper (Plugin)"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper (Renderer).app/Contents/MacOS/$APP Helper (Renderer)"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$LIBRARY_PATH//LoginItems/$APP Login Helper.app/Contents/MacOS/$APP Login Helper"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/Electron Framework.framework"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/Contents/MacOS/$APP Helper"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/Contents/MacOS/$APP Helper EH"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper EH.app/"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/Contents/MacOS/$APP Helper NP"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$FRAMEWORKS_PATH/$APP Helper NP.app/"



#ALibrariesPath="$APP_PATH/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries"
#read_dir $ALibrariesPath

AResourcesPath="$APP_PATH/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources"
read_dir $AResourcesPath

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/Resources/app.asar"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/Resources/icon.icns"
codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/embedded.provisionprofile"

codesign -s "$APP_KEY" -f --entitlements "$CHILD_PLIST" "$APP_PATH/Contents/MacOS/$APP"
codesign -s "$APP_KEY" -f --entitlements "$PARENT_PLIST" "$APP_PATH"

productbuild --component "$APP_PATH" /Applications --sign "$INSTALLER_KEY" "$RESULT_PATH"

IFS=$oldIFS
其中codesign为shell命令,除了以上的文件验签,可能还有别的文件需要验签,根据提交到苹果商店显示的错误和邮件进行添加和修改

6、编写上传到appstore的js文件uploadappstore.js,如下(具体信息根据项目替换)

//appstore 上传
var username = '***'
var password = '***'
// var shell = require('shelljs')
var shell = require('child_process')
var path = './dist/****.pkg'
var strUploading =
'xcrun altool --upload-app --file ' +
path +
' --type osx' +
' -u ' +
username +
' -p ' +
password
// var result = shell.exec(strUploading)
// console.log(result.stdout)
console.log('start----------uploading appstore')
shell.exec(strUploading, function (code, stdout, stderr) {
console.log('Exit code:', code)
console.log('Program output:', stdout)
console.log('Program stderr:', stderr)
console.log('end----------uploaded appstore')
})

构建并上传(上传之前需要先在苹果后台构建版本号)

"build:mas": "npm run clean && npm run build:web && npm run build:appmas",
.........
.........
"build:appmas": "electron-builder -p never -c build.config.mas.js",
(一系列的构建)
"upload:appstore":"node ./auth.js && bash ./build/mas/bash.sh && node ./uploadappstore.js"
(重新验签上传)

--------------------------------------------------

成功后可以在App Store后台中看到上传的app

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值