Skip to content

Commit 19816b7

Browse files
authored
iOS: Support for Extensions (#785)
1 parent b1bdaaf commit 19816b7

File tree

1 file changed

+112
-3
lines changed

1 file changed

+112
-3
lines changed

platform/resources/iPhonePackageApp.lua

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,6 @@ local function getLiveBuildCopyIconScript(src, dest, options)
319319
end
320320

321321
--------------------------------------------------------------------------------
322-
323322
local function getCodesignScript( entitlements, path, identity, developerBase )
324323

325324
codesign_allocate = xcodetoolhelper['codesign_allocate']
@@ -350,6 +349,82 @@ export PATH="$DEVELOPER_BASE/Platforms/iPhoneOS.platform/Developer/usr/bin:$DEVE
350349
return devbase_shell .. export_path .. script .. cmd
351350
end
352351

352+
local function getCodesignAPPXScriptAndPackage(path, identity, entitlements, developerBase, bundleId, isBuildForDistribution)
353+
354+
local codesign_allocate = xcodetoolhelper['codesign_allocate']
355+
local codesign = xcodetoolhelper['codesign']
356+
357+
-- Remove extended attributes that may interfere with codesign
358+
local appxPath = path:gsub('["\']', "") .. "/PlugIns"
359+
local removeXattrs = "/usr/bin/xattr -cr " .. quoteString(appxPath)
360+
361+
-- Quote paths to handle spaces
362+
codesign_allocate = quoteString(codesign_allocate)
363+
codesign = quoteString(codesign)
364+
developerBase = quoteString(developerBase)
365+
366+
-- Shell script setup
367+
local devbase_shell = "DEVELOPER_BASE=" .. developerBase .. "\n"
368+
local export_path = [==[
369+
export PATH="$DEVELOPER_BASE/Platforms/iPhoneOS.platform/Developer/usr/bin:$DEVELOPER_BASE/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
370+
]==]
371+
372+
local script = 'export CODESIGN_ALLOCATE=' .. codesign_allocate .. '\n'
373+
374+
-- Start command with attribute cleanup
375+
local cmd = removeXattrs
376+
377+
-- Check if PlugIns folder exists and sign each .appex file
378+
if lfs.attributes(appxPath, "mode") == "directory" then
379+
for file in lfs.dir(appxPath) do
380+
if file:match("%.appex$") then
381+
local appexPath = appxPath .. "/" .. file
382+
local infoPlist = quoteString(appexPath .. "/Info.plist")
383+
384+
-- Extract CFBundleIdentifier and get the last component
385+
local getBundleIdCmd = "/usr/bin/plutil -extract CFBundleIdentifier xml1 -o - " .. infoPlist ..
386+
" | sed -n 's/.*<string>\\(.*\\)<\\/string>.*/\\1/p' | awk -F'.' '{print $NF}'"
387+
388+
-- Set new CFBundleIdentifier
389+
local setBundleIdCmd = "newBundleId=\"" .. bundleId .. ".$(" .. getBundleIdCmd .. ")\" && " ..
390+
"/usr/bin/plutil -replace CFBundleIdentifier -string \"$newBundleId\" " .. infoPlist
391+
392+
local bundleIdOutput = io.popen(getBundleIdCmd):read("*a"):gsub("%s+", "") -- Clean up any extra spaces
393+
394+
-- Run the command to update CFBundleIdentifier
395+
runScript(setBundleIdCmd)
396+
397+
-- Determine which mobile provision profile to use based on `isBuildForDistribution`
398+
local mobileProvisionPath = path:gsub('["\']', "") .. "/iOSAppxFiles/" .. bundleIdOutput .. "/"
399+
local selectedProvision = isBuildForDistribution and
400+
(mobileProvisionPath .. "embedded.mobileprovision") or
401+
(lfs.attributes(mobileProvisionPath .. "embedded_dev.mobileprovision", "mode") == "file" and
402+
mobileProvisionPath .. "embedded_dev.mobileprovision" or
403+
mobileProvisionPath .. "embedded.mobileprovision")
404+
405+
if not lfs.attributes(selectedProvision, "mode") then
406+
print("Warning: Cannot find mobile provision profile for " .. bundleIdOutput ..
407+
" at " .. selectedProvision .. " This may cause issues with your app.")
408+
else
409+
-- Copy the mobile provision profile to the .appex bundle and delete the old one
410+
local copyMobileProvisionCmd = "cp " .. quoteString(selectedProvision) .. " " ..
411+
quoteString(appexPath .. "/embedded.mobileprovision") ..
412+
" && rm -rf " .. quoteString(mobileProvisionPath)
413+
runScript(copyMobileProvisionCmd)
414+
415+
-- Append signing command for .appex
416+
cmd = cmd .. " && " .. codesign .. " --verbose -f -s " .. quoteString(identity) ..
417+
" --entitlements " .. entitlements .. " " .. quoteString(appexPath)
418+
end
419+
end
420+
end
421+
end
422+
423+
return devbase_shell .. export_path .. script .. cmd
424+
end
425+
426+
427+
353428

354429
local function getCodesignFrameworkScript( path, identity, developerBase )
355430

@@ -439,6 +514,26 @@ end
439514

440515
--------------------------------------------------------------------------------
441516

517+
-- check if app has any appx in app folder
518+
local function checkAppHasAPPX( appPath )
519+
local pluginsPath = appPath:gsub('["\']', "") .. "/PlugIns"
520+
521+
-- Check if PlugIns folder exists
522+
if lfs.attributes(pluginsPath, "mode") == "directory" then
523+
524+
-- Find .appex files inside PlugIns
525+
for file in lfs.dir(pluginsPath) do
526+
if file:match("%.appex$") then
527+
return true
528+
end
529+
end
530+
else
531+
return false
532+
end
533+
end
534+
535+
--------------------------------------------------------------------------------
536+
442537
-- Assumes pwd is same as this script's directory
443538

444539
local templateXcent = [[
@@ -1020,10 +1115,20 @@ local function packageApp( options )
10201115
return errMsg
10211116
end
10221117

1023-
10241118
local entitlements = quoteString( options.tmpDir .. "/entitlements.xcent" )
10251119
setStatus("Signing application with "..tostring(options.signingIdentityName))
10261120

1121+
-- codesign embedded appx (iOS Extension Files)
1122+
if(checkAppHasAPPX(options.appBundleFile)) then
1123+
1124+
local result, errMsg = runScript( getCodesignAPPXScriptAndPackage( options.appBundleFile:gsub('["\']', ""), options.signingIdentity, entitlements, iPhoneSDKRoot, options.bundleid, builtForAppStore ) )
1125+
if result ~= 0 then
1126+
errMsg = "ERROR: code signing embedded appx failed: "..tostring(errMsg)
1127+
return errMsg
1128+
end
1129+
end
1130+
1131+
10271132
local result, errMsg = runScript( getCodesignScript( entitlements, appBundleFileUnquoted, options.signingIdentity, iPhoneSDKRoot ) )
10281133

10291134
if result ~= 0 then
@@ -1388,6 +1493,7 @@ function iPhonePostPackage( params )
13881493
local osPlatform = params.osPlatform
13891494
local err = nil
13901495

1496+
local iPhoneSDKRoot = sdkRoot or "/Applications/Xcode.app/Contents/Developer"
13911497
-- Make available globally
13921498
xcodetoolhelper = params.xcodetoolhelper
13931499

@@ -1564,6 +1670,7 @@ function iPhonePostPackage( params )
15641670
end
15651671
end
15661672

1673+
15671674
-- inject live build settings
15681675
if options.liveBuild then
15691676
-- 1. set options.settings.iph one.plist.NSAppTransportSecurity.NSAllowsArbitraryLoads
@@ -1590,11 +1697,13 @@ function iPhonePostPackage( params )
15901697
return result
15911698
end
15921699

1593-
result = packageApp( options )
15941700

1701+
result = packageApp( options )
1702+
15951703
if result then
15961704
return result
15971705
end
1706+
15981707
end
15991708

16001709
return err

0 commit comments

Comments
 (0)