Embedded framework in release mode only - ios

I'm trying to track down a confusing xcodebuild issue. I have a carthage dynamic framework project that includes another dynamic framework. When I do a debug build (which seems to be what carthage does)
xcodebuild -sdk iphonesimulator9.0 ONLY_ACTIVE_ARCH=NO -configuration release
My resultant framework has a /Frameworks directory inside of it.
When I do a debug build this /Frameworks directory does not exist. This is causing issues because you can't submit an app to apple that has embedded frameworks.
I'm sorry this question is a little open ended but does anybody have any ideas what settings I should be looking at in my build file?
When I did an xcodebuild -showBuildSettings i see the following:
FRAMEWORKS_FOLDER_PATH = GDL90.framework/Frameworks
Which I'm assuming is probably the culprit. But i'm not sure how to fix/change this guy. I'm assuming if i made it GDL90.framework/../../Frameworks that would likely get it outside of my framework - but .... a little unclear how to do this.

Related

How to prevent the stripping of symbols using the xcodebuild archive action?

On my hand is an Xcode project, comprising of a number of static libraries, and an iOS application that consumes them (we do not intend to release the libraries). Part of it is a crash reporting implementation based on Google Breakpad.
An issue that we've found is that we aren't getting line number information in crash reports for the libraries, from our releases. These are generated using xcodebuild archive -project ${PROJECT_PATH} -scheme ${SCHEME_NAME} -archivePath ${OUTPUT_PATH} -UseModernBuildSystem=NO -IDEBuildingContinueBuildingAfterErrors=YES. EDIT: using Xcode 12.
If, instead of archive, I run the xcodebuild build action with the same options (exc. archivePath of course) - or build the project in the IDE -, then I get complete symbol information and everything works (at least testing on iOS Simulator). This seems to be the only difference - of course then I'd still need to produce an .ipa somehow.
The build options are shared between all libraries and application, and include the following:
COPY_PHASE_STRIP = YES
DEPLOY_POSTPROCESSING = YES
SEPARATE_STRIP = YES # tried to change each of these to NO in various permutations; no difference.
STRIP_STYLE = non-global
What is the difference between the steps that the build and the archive actions perform, with regards to stripping?
How can I create the .ipa from the artifact of the xcodebuild build, or otherwise coerce xcodebuild archive to omit / delay stripping, so that I may perform that manually once I've dumped the symbols?
It might be worth mentioning that I've tried combinations of the xcodebuild actions as well, i.e. clean build archive in one or separate steps - makes no difference.
(FWIW, I realise that the PackageApplication command of xcrun was deprecated as of Xcode 8.3.)

Building for iOS Simulator, but the linked framework '****.framework' was built for iOS

I cannot run my app on simulators anymore. Online suggested that I edit my project.pbxproj, but that does not appear to work. How do I reclaim the ability to run my project on my simulator (and remain able to do so on a device)? I am working on another project that uses many of the same frameworks, but it runs on a simulator. What would cause a similar framework to work in one project but not in another?
Xcode 12.3
In my case I solved this problem by simply setting Validate Workspace to Yes in the Build Settings tab
No doubt that the fix in case of Xcode 12.3 is to setup the Validate Workspace property in the target's build setting. However if you check the diff after this change, the reason of the build error is the missing parameter (VALIDATE_WORKSPACE) from the project file, not the value of the parameter.
So you don't need the value to be YES. You need to add the value to the project settings and you can leave it on the default value (NO). At the first time, it shows up in the Build Settings with NO, but only because that is the default value of the missing parameter.
TLDR;
Without changing your project setup, go to your target's build settings, find "Validate Workspace", set it to YES, then set back to NO.
It happened to me when I added my custom framework into the project and after I updated my Xcode, I encountered the same issue.
Solution : under build settings in project search for Validate workspace Just
change to yes which is by default set to no
Use a .xcframework rather than a "fat" .framework containing an iOS and iOS simulator slice.
This also obviates the need to use a build phase to strip the iOS simulator slice when building for the App Store.
"Fat" frameworks, which are typically created using lipo as they cannot be built directly by Xcode, are not supported (source: Developer Technical Support Apple Developer forum). .xcframework is the only supported mechanism to ship a single framework supporting both iOS and the iOS simulator.
Also .xframework's is the only supported way to ship a binary Swift framework (source: Developer Technical Support on Apple Developer forum).
In Xcode 12.3, the fact that "fat" frameworks are non supported is enforced, as Xcode verifies the frameworks during build, which is why a lot of projects suddenly started to see build errors.
Most answers here are for consumers of universal binaries to work around the new restrictions. But, as in noted elsewhere, it's time to migrate to Apple's XCFramework format for framework authors.
If you were running a custom build script to create universal binary before with an aggregate target and lipo, it's straightforward to migrate to producing .xcframework files
First, in build settings make sure "Build Libraries for Distribution" (BUILD_LIBRARY_FOR_DISTRIBUTION) is set to YES
Then, replace your existing aggregate target build script that used lipo with something like the following which is simple for showing how to make "release" frameworks only:
# Universal Script
set -e
FRAMEWORK_NAME="your_framework_name"
IOS_SCHEME_NAME="your_scheme_name"
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
SIMULATOR_ARCHIVE_PATH="${SRCROOT}/build/${FRAMEWORK_NAME}-iphonesimulator.xcarchive"
DEVICE_ARCHIVE_PATH="${SRCROOT}/build/${FRAMEWORK_NAME}-iphoneos.xcarchive"
OUTPUT_DIR="${SRCROOT}/framework_out_universal/"
# Simulator xcarchieve
xcodebuild archive \
-scheme ${IOS_SCHEME_NAME} \
-archivePath ${SIMULATOR_ARCHIVE_PATH} \
-configuration Release \
-sdk iphonesimulator \
SKIP_INSTALL=NO
# Device xcarchieve
xcodebuild archive \
-scheme ${IOS_SCHEME_NAME} \
-archivePath ${DEVICE_ARCHIVE_PATH} \
-sdk iphoneos \
-configuration Release \
SKIP_INSTALL=NO
# Clean up old output directory
rm -rf "${OUTPUT_DIR}"
# Create xcframwork combine of all frameworks
xcodebuild -create-xcframework \
-framework ${SIMULATOR_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \
-framework ${DEVICE_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \
-output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework
# Delete the most recent build.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
You can tweak the above to have different output dirs, different deletion behavior, support multiple configurations (Release vs Debug) but this works for me.
Finally, as a one time step, delete the your_framework_name.framework universal binary that caused you the error as mention in this project. Copy the newly built your_framework_name.xcframework and add it to the project and the error should go away.
possible reason would be
framework which you are using may not be built for simulator architecture(x86_64), you can check the compatibility by going to framework folder (framework_name.framework --> modules --->framework_name.swiiftModule-->) in this path you should see arm/i386/x86_64 support files
if you have updated to new Xcode, the frameworks you are using are not compatible to the newer compiler version, so vendor needs to share the recent compatible one, in this case you will not be able to run on both device and simulator
To be honest, the only approach that you guys should follow is to convert .framework to .xcframework, as this is what Apple enforces from XCode version 12.3 and above. Validating workspace and other quick fixes may be temporary and cause problems in the future - like archiving the app for appstore release or testflight.
To convert .framework to .xcframework follow the steps described in the article, starting from paragraph Commands:
https://medium.com/strava-engineering/convert-a-universal-fat-framework-to-an-xcframework-39e33b7bd861
I ran in this error on Xcode v12.3 and Universal(fat) Framework(.framework)
Building for iOS Simulator, but the linked and embedded framework was built for iOS + iOS Simulator.
Solution 1: is Toggle/Toggle Validate Workspace(not default)
Solution 2: use XCFramework[About]
If you are using Carthage, make sure you use the copy-frameworks script rather than using Embed & Sign as embedded content. I was getting this same error because I forgot about that.
I suppose the framework you are linking was built only for arm architecture. You won't be able to run it in a simulator. You will need an author of the framework to build a "universal framework".
If you are new to Xcode and using Xcode just to launch emulator to run appium tool the above steps might be complex. Just use xcode version less than 11 for beginners.
This link helps to download xcode 10.3
Xcode10.3
If you try to download from AppStore we need to have free storage up to 40 GB the above `xip file will won't cause storage errors.
You can Thank me later if this works!!

Automatically clean the project on Run in Xcode

I am working on a CocoaPods iOS framework that will be later published and used via CocoaPods. I am in the middle of development. I have an Example project within, that points back to my framework via static path in the Podfile and which facilitates in the development.
Now every time I fix/change something in my framework, I need to clean the project and run Xcode to see my changes. Otherwise, changes don't take affect.
I am looking a way to automatically clean my project when I hit Run on Xcode.
My Xcode version is 11.1.
Add a run script in your build phases and do
xcodebuild -sdk "${TARGET_SDK}" -xcconfig "${CONFIG_FILE_PATH}" -configuration Debug clean
A simple xcodebuild clean should do as well depending on your needs look at the Apple's documentation

Travis-CI with: ERROR: Cannot find schemes

This is my .travis.yml file
language: objective-c
osx_image: xcode7.2
script:
xctool -project ProjectName.xcodeproj -scheme ProjectName build -sdk iphonesimulator
While Travis is running I've got this error:
$ xctool -project ProjectName.xcodeproj -scheme ProjectName build -sdk iphonesimulator
ERROR: Cannot find schemes. Please consider creating shared schemes in Xcode.
TIP: This might happen if you're relying on Xcode to autocreate your schemes
and your scheme files don't yet exist. xctool, like xcodebuild, isn't able to
automatically create schemes. We recommend disabling "Autocreate schemes"
in your workspace/project, making sure your existing schemes are marked as
"Shared", and making sure they're checked into source control.
This problem is easy to solve:
Go to your project scheme and click Manage Schemes...
Tick Shared for your scheme
Click Close, commit and push.
Problem Solved. Now Travis is working without problems.
I also wrote a post in my blog about Travis-CI.
In addition to the answer by Gabriel.Massana, make sure the files are checked into version control (SVN/GIT).

Xcode Build for Profiling via Terminal

I'm trying to build my XCode project via the terminal. I'd like use Xcode's Product > Build for > Profiling option. So far I have:
xcodebuild -project "MyGame.xcodeproj" -target "MyGameEditor - Mac" -destination 'name=My Mac 64-bit' -configuration Profile
The project builds but not for profiling. I get an error that configuration 'Profile' does not exist.
Any help is appreciated.
What you are trying to sepcify with -configuration is the build configuration, not the build action. Unless you have added extra configurations to your project, you only have "Debug" and "Release" configurations.
What Xcode does when you tell it to profile is it builds the configuration that your scheme specifies to use when profiling, launches the simulator, installs the app, then launches Instruments.
So you need to do a similar thing with two command line calls, one to xcodebuild, one to instruments.
Some helpful links that should help you figure out what you need to do:
http://blog.manbolo.com/2013/04/09/launching-uiautomation-tests-in-command-line
Can the UI Automation instrument be run from the command line?
It is also worth noting that rather than specifying a target and configuration, you should just specify a scheme which provides both and other optional additional features.

Resources