iOS Umbrella Framework - codesign problem

3.1k Views Asked by At

I have an Umbrella Framework distributed throughs Cocoapods as vendored framework and compiled in release mode.

It works perfectly with simulator, but I have a problem with the code sign on the sub-framework nested in the umbrella layer.

This is the error:

dyld: Library not loaded: @rpath/Subframework.framework/Subframework
Referenced from: /private/var/containers/Bundle/Application/02AD328F-9E78-4D53-9C39-0C8639B00D81/sdkInteTest.app/Frameworks/Umbrella.framework/Umbrella
Reason: no suitable image found. Did find:
/private/var/containers/Bundle/Application/02AD328F-9E78-4D53-9C39-0C8639B00D81/sdkInteTest.app/Frameworks/Umbrella.framework/Frameworks/Subframework.framework/Subframework: code signature in (/private/var/containers/Bundle/Application/02AD328F-9E78-4D53-9C39-0C8639B00D81/sdkInteTest.app/Frameworks/Umnrella.framework/Frameworks/Subframework.framework/Subframework) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.

Then, if I launch the application to sign the sub-framework with the following script:

pushd ${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/Frameworks/Umbrella.framework/Frameworks
for EACH in *.framework; do
echo "-- signing ${EACH}"
/usr/bin/codesign --force --deep --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --entitlements "${TARGET_TEMP_DIR}/${PRODUCT_NAME}.app.xcent" --timestamp=none $EACH
done
popd

I get this error:

/Users/xxx/Library/Developer/Xcode/DerivedData/sdkInteTest-bbfpzsxuhjomfmaumywyncnbwbla/Build/Intermediates.noindex/sdkInteTest.build/Debug-iphoneos/sdkInteTest.build/Script-F9547ACC224017BF0030EA0B.sh: line 3: pushd: /Users/xxx/Library/Developer/Xcode/DerivedData/sdkInteTest-bbfpzsxuhjomfmaumywyncnbwbla/Build/Products/Debug-iphoneos/sdkInteTest.app/Frameworks/Umbrella.framework/Frameworks: No such file or directory
-- signing *.framework
*.framework: No such file or directory
/Users/xxx/Library/Developer/Xcode/DerivedData/sdkInteTest-bbfpzsxuhjomfmaumywyncnbwbla/Build/Intermediates.noindex/sdkInteTest.build/Debug-iphoneos/sdkInteTest.build/Script-F9547ACC224017BF0030EA0B.sh: line 8: popd: directory stack empty
1

There are 1 best solutions below

0
Andre On BEST ANSWER

The Solution

The problem is that the script was starting when the pod wasn't already attached. The script should be run when all the pod jobs are done.

I wrote a full guide to build an iOS Umbrella framework!

The solution I found is the following:

1) Step one:

In the podfile of the integration project (not the umbrella project) add the following line of code where you add dependencies:

script_phase :name => 'Sign', :script => './sign.sh'

like this:

target 'yourTarget' do

    # Pods for sdkInteTest
    #your pods goes here

    script_phase :name => 'Sign', :script => './sign.sh'
end

2) Step two:

Than in the terminal at the root of your test Integration project:

In the terminal type:

touch sign.sh
chmod 777 sign.sh
open sign.sh

And in the script file add this code:

echo "Signing subframeworks"
pushd "${TARGET_BUILD_DIR}"/"${PRODUCT_NAME}".app/Frameworks/YOURFRAMEWORKNAME.framework/Frameworks
for EACH in *.framework; do
echo "-- signing ${EACH}"
/usr/bin/codesign --force --deep --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --entitlements "${TARGET_TEMP_DIR}/${PRODUCT_NAME}.app.xcent" --timestamp=none $EACH
done
popd

echo "BUILD DIR ${TARGET_BUILD_DIR}"

remember to rename your framework name.

In this way you are telling to CocoaPods to run a script phase after the pod installation. Unfortunately this is a "client" solution, I tried to find a solution to apply at framework level without any luck.