32

I added a shared framework to share code between app and watch extension. Later I removed the shared framework since it cause lots of problems. I can build and run my app on iphone and watch. However when I submit to app store, I see these two errors:

ERROR ITMS-90205: "Invalid Bundle. The bundle at 'xxx WatchKit Extension.appex' contains disallowed nested bundles."

ERROR ITMS-90206: "Invalid Bundle. The bundle at 'xxx WatchKit Extension.appex' contains disallowed file 'Frameworks'."

I have tried all the solutions mentioned on stackoverflow(this , this, this) None of them works for me. How do I fix the error? Errors message from apple really doesn't give a clue what I should to.

lewis
  • 2,936
  • 2
  • 37
  • 72
WayneZhao
  • 1,517
  • 3
  • 13
  • 8

9 Answers9

17

I still do not fully understand what causes the issue, but I've stumbled upon an answer that has finally solved the issue for me.

https://github.com/CocoaPods/CocoaPods/issues/4203

Specifically, the post by mikehouse on Oct 12, 2015 was the solution to the the problem.

Add the following run script to ALL you embedded extension targets. In my case I had to add the run script as a build phase to my Today extension and my Apple Watch App extension.

cd "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/"
if [[ -d "Frameworks" ]]; then 
    rm -fr Frameworks
fi
Christian Gossain
  • 5,942
  • 12
  • 53
  • 85
  • 4
    I don't think this is the solution because the scrip will remove the folder named as frameworks and all its content and if the app is dependent on any framework that is removed your app will crash on runtime. As per my understanding you need to contact to developers of that framework. They can remove or rename the folder and rebuild the framework. – er.vish Jun 21 '16 at 07:18
  • 1
    The key point is to have the run script in the end of the build phase. – Rishabh Tayal Sep 22 '16 at 21:57
  • Excellent. Resolves the issue when you have a fw dependency graph as opposed to a tree. Saved my day. – Anton Tropashko Aug 02 '19 at 10:58
6

The "ITMS-90206" error was resolved in this post: Validation Error: Invalid Bundle. The bundle at ... contains disallowed file 'Frameworks'

The setting needs to be changed from Yes to No within the Build options of your WatchKit Extension:

Embedded Content Contains Swift Code: No
Community
  • 1
  • 1
tuc0w
  • 141
  • 1
  • 8
6

The above didn't work for me.

Embedded Content Contains Swift Code: NO

Didn't really do anything for me.

I experienced this issue using a dynamic framework. My dynamic framework contained other dynamic frameworks which made it OK to have:

Embedded Content Contains Swift Code: YES

And instead having the other dynamic frameworks set it to No instead. But instead of that I had to set

Always Embed Swift Standard Libraries: NO

under Build Phases.

Having this one set to YES generated the frameworks folder causing upload to ITC fail.

user023
  • 1,450
  • 2
  • 17
  • 21
  • 2
    This worked to pass the upload process (I was getting errors before finishing the upload) bu then got an email from Apple: We have discovered one or more issues with your recent delivery for "InstaStickers: Turn Instagram photos into stickers". To process your delivery, the following issues must be corrected: Invalid Bundle - One or more dynamic libraries that are referenced by your app are not present in the dylib search path. Once these issues have been corrected, you can then redeliver the corrected binary. Regards, The App Store team – Jorge Irún Oct 10 '16 at 18:53
5

In the main target add:

cd "${CODESIGNING_FOLDER_PATH}"
find ./PlugIns -type d -name Frameworks | xargs rm -rf

The problem is that adding SPM packages on multiple targets of the same project will duplicate the dependencies. The frameworks on this extension are probably on the main target so this should be enough. Otherwise use the full script below on the main target, which will deduplicate the frameworks if needed by moving them to the app.


Do NOT add this to your extension target. It tries to remove the duplicated framework but it has no effect because it runs before the framework is copied to the extension:

# this has no effect if you add it to your extension target
cd "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/"
if [[ -d "Frameworks" ]]; then 
    rm -fr Frameworks
fi

I ran into this problem in a project that uses Rx as a SPM package in the main target, frameworks, and extensions. If you have the same or similar problem (e.g. Firebase), you can fix it with the following script in the main target:

if ! [ "${CONFIGURATION}" == "Release" ] ; then

    echo "early exit"
    exit 0
fi

cd "${CODESIGNING_FOLDER_PATH}/Frameworks/"

# copy frameworks to TeamworkProjects.app/Frameworks
for framework in *; do
    if [ -d "$framework" ]; then
        if [ -d "${framework}/Frameworks" ]; then
            echo "Moving embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
            cp -R "${framework}/Frameworks/" .
            rm -rf "${framework}/Frameworks"
        fi
    fi
done

# remove leftover nested frameworks
for framework in *; do
    if [ -d "$framework" ]; then
        if [ -d "${framework}/Frameworks" ]; then
            echo "Removing embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
            rm -rf "${framework}/Frameworks"
        fi
    fi
done

# Remove Frameworks from PlugIns
cd "${CODESIGNING_FOLDER_PATH}"
find ./PlugIns -type d -name Frameworks | xargs rm -rf

# codesign for Debugging on device
if [ "${CONFIGURATION}" == "Debug" ] & [ "${SDKROOT}" != *Simulator* ] ; then

    echo "Code signing frameworks..."
    find "${CODESIGNING_FOLDER_PATH}/Frameworks" -maxdepth 1 -name '*.framework' -print0 | while read -d $'\0' framework
    do
        # only sign frameworks without a signature
        if ! codesign -v "${framework}"; then
            codesign --force --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --preserve-metadata=identifier,entitlements --timestamp=none "${framework}"
            echo "Added missing signature to '${framework}'"
        fi
    done
fi

Most of this script came from user pewe at forums.swift.org: Swift packages in multiple targets results in duplication of library code.

Jano
  • 62,815
  • 21
  • 164
  • 192
3

I had a framework that builded with the following build settings:

Always Embed Swift Standard Libraries: YES

Allow Non-Modular includes in Framework Modules: YES

So I changed both to NO and build framework again.

Always Embed Swift Standard Libraries: NO

Allow Non-Modular includes in Framework Modules: NO

I added new build of framework to my project so It uploaded to iTunes Connect successfully.

Vahid
  • 3,352
  • 2
  • 34
  • 42
3

I add a swift package, which is dynamic library, into sub-projects, and into my main project. When uploading to TestFlight, I encounter this issues too.

As the picture, I change Embed & Sign to Do Not Embed for the sub-project, and then this issue is resolved.

It keeps Embed & Sign for my main project. But in sub-projects, I change them to Do Not Embed.

enter image description here

AechoLiu
  • 17,522
  • 9
  • 100
  • 118
2

I had a today extension which uses a custom framework I implemented it.

I tried all the solutions but nothing worked for me.

I needed the custom framework only in the today extension, so I linked and embedded this framework in the today extension only.

What the error is saying is:

that the bundle contains disallowed frameworks

Today extension should not embed any framework, shall only link to it.

So I removed the framework from the today extension and added it to the parent app.

Note that:

the parent app should use this framework since it's added to it, an import shall do the job.

Ayman Ibrahim
  • 1,359
  • 15
  • 24
1

Just keep in mind that should not embed & sign the nested framework enter image description here Change Embed & Sign to Do not Embed will solve issue, I have solved it, thank for AechoLiu answer

0

In case anyone runs into this issue in 8 years after this post was posted, here's what worked for me after browsing through various threads:

I had a project with 5 frameworks attached to the project.

enter image description here

My main target (in this case - meteo-lt had all the frameworks embeded and ready for signing. Seems like okay here.

enter image description here

But the issue was that all the other frameworks were embedding each other too.

For example:

  • MeteoLTUI was embedding (with or without signing - same issue) MeteoLTDomain and MeteoLTUtilities.
  • MeteoLTNetwork was implementing MeteoLTDomain and MeteoLTUtilites.
  • MeteoLTUtilities was implementing MeteoLTDomain.
  • And so on..

All I had to do was to leave Embed & Sign for all frameworks on main target meteo-lt and set to Do not embed inside all other frameworks, so they wouldn't embed each other and create nested embedding.

In other words:

You can't nest B inside of A.

- .app
  - Frameworks
    - A.framework
      - Frameworks
        - B.framework

Instead, you need to do it like this:

- .app
  - Frameworks
    - A.framework
    - B.framework

P.S. In case this does not help, and you were planning and are heading to set all frameworks on main target to Do not embed, make sure to read these articles before:

https://holyswift.app/frameworks-embed-or-not-embed-thats-the-question/

https://pratheeshbennet.medium.com/static-library-vs-dynamic-library-in-ios-55478ed53a03

liudasbar
  • 173
  • 4
  • 11