Embedding a framework within a framework (iOS 8+) - ios

iOS applications built with Xcode 6 or higher allow embedding dynamic iOS frameworks within them. I am building a shared framework and would like to embed a sub-framework. How can I accomplish this?
Note: This is possible and is being used in production (for e.g., with Swift frameworks in CocoaPods).

Found the answer. Here's how it's done:
Navigate to Target > Build Phases
Click the small "+" icon and select "New Run Script Build Phase"
Paste the following:
cd $BUILT_PRODUCTS_DIR
mkdir $PROJECT_NAME.framework/Frameworks &>/dev/null
for framework in *.framework; do
if [ $framework != $PROJECT_NAME.framework ]; then
cp -r $framework $PROJECT_NAME.framework/Frameworks/ &>/dev/null
fi
done

#Vatsal Manot's answer was very helpful for me. I modified it a bit and also had a need to sign the copied embedded framework. My script is below.
cd $BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app/Frameworks/Custom.framework/Frameworks
for framework in *.framework; do
mv $framework $BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app/Frameworks/
/usr/bin/codesign --force --sign "iPhone Developer" --preserve-metadata=identifier,entitlements --timestamp=none $BUILT_PRODUCTS_DIR/$PRODUCT_NAME.app/Frameworks/$framework
done

To create a Umbrella Framework that contains a Sub-Framework you can follow the step-by-step guide written down here: Umbrella framework

Related

Failed to verify bitcode while exporting archive for ad hoc distribution - tried Xcode 8.3.3 & Xcode 9

Apps containing our framework complains about missing bitcode while exporting archive for Ad-hoc distribution.
I have gone through the documentation provided by Apple in this regard
Technical Note TN2432. The documentations' listed possible root causes do not resemble our scenario. (We are not using assembly instructions or have malformed info.plist file)
I have gone through following similar questions posted on SO
Error while exporting with Bitcode enabled (symbol not found for architecture armv7)
Is it possible to create a universal iOS framework using bitcode?
New warnings in iOS 9
But the provided solutions do not seem to work.
I have tried adding BITCODE_GENERATION_MODE flag in User-Defined build settings. I also tried adding -fembed-bitcode-marker & -fembed-bitcode in Other C flags in framework target.
I check if bitcode segments are present in my generated framework using the suggested command
otool -l -arch arm64 <framework_name> | grep __LLVM
It shows 2 segments
segname __LLVM
segname __LLVM
But while exporting the archive, Xcode still complains about absent bitcode.
I tried to upload app on App store to verify if this issue is due to Xcode versions (I tried 8.3.3. and 9.0), but I get following email about build import error from iTunes Store.
While processing your iOS app, APP_NAME 1.0(4), errors occurred in the app thinning process, and your app couldn’t be thinned. If your app contains bitcode, bitcode processing may have failed. Because of these errors, this build of your app will not be able to be submitted for review or placed on the App Store. For information that may help resolve this issue, see Tech Note 2432.
PS: Disabling bitcode is not an option for us as host app need to support bitcode.
The error description took me in the wrong direction to find the solution.
This error is not related to bitcode.
It appeared when the framework contained simulator slices (i386 x86_64)
Removing them before archiving resolved the issue.
Adding a run script phase to build phases of the target with following code helped in getting rid of the error.
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[#]}"
rm "${EXTRACTED_ARCHS[#]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
Credits: http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/
If you don't know how to add a run script phase to your Xcode project, because maybe you're building a project with Cordova or Ionic and you never were taught much about Xcode, here's how you do that:
Open your project in Xcode.
Make sure you're looking at your project in the "Project Navigator" by clicking on the left-most icon in the left pane of Xcode (the one that says "show Project Navigator" when you point at it.
Click on your project at the top of the navigator window, so that it is selected as your target
At that point, in the middle portion of the Xcode window, you'll see several things appear near the top. General, Capabilities, Resource Tags, Info, among others. One of them is Build Phases -- click on it.
Click the + that's near the top-left of the middle portion of the Xcode Window. It will say Add New Build Phase if you point at it long enough.
Select "New Run Script Phase" from the menu that popped up when you clicked on the +
Click on the arrow next to the Run Script that just appeared.
Copy and paste the above script into the appropriate area just below the word "Shell". You shouldn't have to change anything else.
Build/Archive your project like normal, only now you won't get those annoying "failed to verify bitcode" errors. :-)
I had to set Enable Bitcode to 'NO' in Build Settings
Try the following:
Make sure this framework is added under Copy Frameworks Script in Build Phases.
Use BITCODE_GENERATION_MODE instead of BITCODE_GENERATION_CODE
I was facing the same issue. But in my case, I found out after one day of struggle that my system was running out of memory. As soon as I created some space in the system all worked fine.

Cocoa Touch Framework fails to debug on simulator in embedding project

I've got a Cocoa Touch framework built with XCode 6 targetted towards iOS >= iOS8.
This framework's target architecture settings are default, meaning that I haven't changed anything.
The architectures are set to standard (which doesn't include x86_64, more on that later).
The framework itself contains both Swift and Objective-C code, so building it using the static library workaround from Ray Wenderlich won't work.
Now, if I create a new project and add the framework project to it, the project builds for both the device and simulator, which is fine.
However, if I take the .framework file and add it to a different project just like you'd add any other framework, the project won't build for the simulator. Well, it does build, but it crashes because it can't find the relevant classes. It works fine on the device and archiving works just as expected as well.
The framework project itself already gives me a warning;
"Apple Mach-O Linker Warning - Directory not found for option ....(Debug-ophoneos)".
Any help would be highly appreciated!
I have finally found the solution to this issue.
As it turns out, XCode no longer creates fat binaries out of the box. No idea what Apple's reasoning behind this might be, too me it just seems like sometimes the guys responsible for XCode like to make fun of the developers using their product...
Anyways, you can find the definitive guide as to how to create a fat binary for simulator and all iOS devices (yes, you even have to lipo different architectures in order to get a framework that works on newer and older devices): https://kodmunki.wordpress.com/2015/03/04/cocoa-touch-frameworks-for-ios8-remix/
In short;
Create a Cocoa Touch Framework
Set the Architectures to arm64, armv7, and armv7s
Set "Build Active Architecture" to "NO"
Set "Valid Architectures" to arm64, armv1, and armv7s
Add the following script to the framework's build Scheme as an Archive Post-action;
set -e
DEVICE_BIN="${OBJROOT}/UninstalledProducts/${TARGET_NAME}.framework"
SIMULATOR_BIN="${SYMROOT}/../../../../Products/Debug- iphonesimulator/${TARGET_NAME}.framework"
ARCHIVE_PATH="${SRCROOT}/_Archive"
rm -rf "${ARCHIVE_PATH}"
mkdir "${ARCHIVE_PATH}"
if [ "${CONFIGURATION}" = "Release" ]; then
if [ -d "${DEVICE_BIN}" ]; then
DEVICE_PATH="${ARCHIVE_PATH}/Release"
mkdir "${DEVICE_PATH}"
cp -r "${DEVICE_BIN}" "${DEVICE_PATH}"
fi
if [ -d "${SIMULATOR_BIN}" ]; then
SIMULATOR_PATH="${ARCHIVE_PATH}/Debug"
mkdir "${SIMULATOR_PATH}"
cp -r "${DEVICE_BIN}" "${SIMULATOR_PATH}"
lipo -create "${DEVICE_BIN}/${TARGET_NAME}" "${SIMULATOR_BIN}/${TARGET_NAME}" -output "${SIMULATOR_PATH}/${TARGET_NAME}.framework/${TARGET_NAME}"
fi
fi
exit 0;
This will create an _Archive directory in your project's directory where you can find the frameworks for both debug and release.
Important: As of today (May 22nd 2015) you'll have to build the project with the simulator first, and then archive with a device. Otherwise you won't get a universal binary!
This post has been created in order to avoid dead link errors, for updates regarding the packaging process, please ALWAYS try the steps posted on the kodmunki website I've linked above first as the steps in this post might have been outdated already!

Invalid Bundle, The bundle contains disallowed nested bundles, contains disallowed file 'Frameworks'

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.
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
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
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.
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.
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.
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.
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.

Integrate Linphone in own iOS project

I am creating a voip call based project with Linphone and I have also successfully build and run the Linphone project and successfully run audio and video call. Now I am integrating Linphone in my own project and I am facing many problems and issues with this. I have used some following links for help but nowhere are complete instructions. Can anyone provide me the complete running steps for this-
http://shallwelearn.com/blog/build-linphone-for-iphone-and-ipad/
Integrate Linphone app to my iOS app
How to integrate Linphone into an existing project (SIP in IOS)
http://www.linphone.org/technical-corner/linphone/overview
How to integrate Linphone into an existing project (SIP in IOS)
http://lists.gnu.org/archive/html/linphone-developers/2014-09/msg00109.html
http://www.successmonkey.co.nz/blog/building-linphone-for-ios
Download Liblinphone iPhone SDK from the link: http://www.linphone.org/releases/ios choose latest one.
Move two folders (include and lib) to your project folder
Add paths to these folders in your project Build settings - INCLUDE folder goes to headers and LIB folder goes to libraries.
In General tab in Linked frameworks add all files from LIB folder
Download/clone the repo https://github.com/BelledonneCommunications/linphone-iphone
Find 4 files: LinphoneManager.h/.m and Utils.h/.m , include them in your project folder and add them to the left pane to other class files also
Try to compile your project - xCode will spam you with errors - this is ok.
You need to inspect errors and just delete all file imports causing errors (Some Linphone Address book files/ some config store files and some helpers classes that you do not need for basic use in your project (because most likely you already implemented this features in your existing project))
Then compile again and inspect all errors in methods. Comment delete any problematic chunks of code (there will be about 10-15 of them).
LinphoneManager class already include many useful features - like good watch and use of linphone core with good logging and etc and etc, but not all of them (unfortunately).
With Xcode 11 using macos 10.15.6 Catalina
Linphone SDK 4.4.0 Using Cocoapod
https://github.com/BelledonneCommunications/linphone-sdk/blob/master/README.md
Using a local linphone SDK
Clone the linphone-sdk repository from out gitlab:
$ git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git --recursive
$ git submodule update --init --recursive
Or
$ git clone --recurse-submodules https://gitlab.linphone.org/BC/public/linphone-sdk.git
Rebuild the project:
PODFILE_PATH= pod install
where is your build directory of the linphone-sdk project, containing the linphone-sdk.podspec file and a linphone-sdk ouptut directory comprising built frameworks and resources.
Pod file looks like
source "https://gitlab.linphone.org/BC/public/podspec.git"
source "https://github.com/CocoaPods/Specs.git"
def common_pods
use_frameworks!
pod 'linphone-sdk', '4.4.0'
end
Then open linphone.xcworkspace with Xcode to build and run the app.
Linphone SDK 4.4.0 Using Compile
$ git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git -- recursive
$ git submodule update --init --recursive
Or
$ git clone --recurse-submodules https://gitlab.linphone.org/BC/public/linphone-sdk.git
Goto the build directory
$ mkdir build && cd build
———————————
https://gitlab.linphone.org/BC/public/linphone-cmake-builder/blob/ios-3.13.19/README.python.md
first, install brew
$ brew install cmake
$ brew install yasm
$ brew install pkg-config
Install pip ->
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py
$ python -m pip install pystache //Check by $ python -m pip list
$ brew install doxygen
———————————
$ cmake .. -G Xcode -DLINPHONESDK_PLATFORM=IOS -DENABLE_G729=YES -DENABLE_G729B_CNG=YES -DENABLE_VCARD=OFF -DENABLE_ILBC=OFF -DENABLE_SILK=OFF -DENABLE_ISAC=OFF -DENABLE_MKV=OFF -DENABLE_GSM=OFF -DENABLE_DOC=OFF -DENABLE_UNIT_TESTS=OFF -DENABLE_LIME=OFF -DENABLE_GPL_THIRD_PARTIES=OFF -DENABLE_NON_FREE_CODECS=OFF
Note - in this step we will also enable G729 dedec support in our linphone sdk.
$ cmake --build . --config RelWithDebInfo
The compilation process is done now need to integrate with Xcode
Compiled Linphone SDK integrates into Xcode.
Find compiled sdk in below directory
linphone-sdk -> build -> linphone-sdk -> apple-darwin
Frameworks and share folder add into xcode project, Frameworks have multiple universal architectures.
Frameworks path add into framework search in build settings
Every framework of Frameworks folder, should be type "embed and sign" (means embed framework.) instead of "do not embed" as default while adding into Xcode Framework setting. it's the most very important part.
apple-darwin -> Tools folder have deply.sh script, copy its contents and create a new run script in "build settings" and paste in it"
the tricky part is where to place the 4th point's script for upload app using archive with strip and slice. Edit Scheme -> Archive -> open dropdown -> post actions -> + to add new script -> copy and paste.
6 (Optional). If experience script causes application crash due to fat library used our project, There is a minor change in the script, I found a solution from this URL - Errors building Xcode Project after adding in Run Script fatal error: lipo: input file
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
# Start of Script modify - identify if the framework is FAT. If it is, then it skips it.
if [ ! -f "${FRAMEWORK_EXECUTABLE_PATH}" ]; then
continue
fi
if xcrun lipo -info "${FRAMEWORK_EXECUTABLE_PATH}" | grep --silent "Non-fat"; then
echo "Framework non-fat, skipping: $FRAMEWORK_EXECUTABLE_NAME"
continue
fi
echo "Thinning framework $FRAMEWORK_EXECUTABLE_NAME"
# end of Script modify
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[#]}"
rm "${EXTRACTED_ARCHS[#]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
If you are using pod then de integrate pod using terminal command "pod deintegrate" on your pod directory. also delete .xcworkspace file from the project.
Now install pod using terminal command "pod install"
Note: If your case was Adding script causes app crash as I mentioned in 6th point but every time adding the script, have to pod de integrate help me avoid it.
:) Now enjoy using linphone sdk in your project.
end of linphone sdk
Linphone SDK Configuration in our projects.
Enable Codec - To enable audio codec first enable defaultValue of g729_preference in the Audio.plist file and last step In Project -> Target -> Build Settings find "Preprocessor macros" and include HAVE_G729, it prints in sip log like Adding G729/8000 for compatibility, just in case.
#Update - add 5th point fo compile for upload the app to the app store and G729 codec configuration.

When added an embedded framework in an Xcode project, how do you differentiate between Debug and Release?

When I add a framework to my Xcode project, to be embedded in my app bundle, how do I make two different options for whether it's Debug or Release (I have two versions of the framework, one compiled for release and one for debug).
This is what I'm referring to:
As you see, with that configuration, it'll just copy the one on CEF/Debug regardless of whether it's in being compiled in Release or Debug mode.
Ideally I want something like you have for setting:
You can manage frameworks to embed with your custom Run Script in Build Phases:
#!/bin/bash
# Your frameworks to embed
FRAMEWORK="Debug.framework"
if [ $CONFIGURATION == "Release" ]; then
FRAMEWORK="Release.framework"
fi
# Destination to copy inside the app's frameworks folder
NAME=$(basename $FRAMEWORK)
DESTINATION=${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/$NAME
# Don't copy if it's already copied
if [ ! -d $DESTINATION ]; then
# Copy the framework to the app's frameworks folder
cp -r $FRAMEWORK $DESTINATION
# Sign (if needed)
codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements $DESTINATION
fi
Note that you can bring in different shared libraries (such as frameworks) by setting the environment var DYLD_IMAGE_SUFFIX for your app. So if inside your (one) framwork you had CEF.framework/Versions/Curent/CEF and CEF.framework/Versions/Curent/CEF_debug and you set the env var DYLD_IMAGE_SUFFIX=_debug it will load the second for that run.
You don't need to. Embedded frameworks will build according to the build of the consumer app.
You can test it by adding a build schema on the app (like Debug2) and then compiling. You will receive an error from the embedded because it tried to compile it with the Debug2 schema, which is not available in the embedded framework. Now duplicate some schema and call it Debug2. It will build.

Resources