Unable to archive build with Share Extension and AFNetworking Cocoapod - ios

I've got a share extension set up for my app and I'm using AFNetworking through a cocoapods install.
I was able to build and run the app through simulator and my phone via debug builds but when I tried to archive to submit to the app store I ran into a warning:
linking against dylib not safe for use in application extensions
AFNetworking
Archive builds would complete but they would be corrupted and unusable.
My solution is to stop using cocoapods for my app extension and manually add the AFNetworking files to my Compile Resources build setting.
I'm just wondering if others have had this issue OR if they have had no problems using AFNetworking cocoapod to submit an extension to the store.
I have checked out the Apple Guidelines and was using arm64 architecture and had set the target’s “Require Only App-Extension-Safe API” build setting to Yes.

As far as i know the latest version of cocoapods should set automatically "Allow app extension API only" flags to all libs targets if pods library is properly linked to extension target(s) (check targets from Pods.xcodeproj). If it doesn't happen you can try to set it manually in post_install hook. You can try this one:
post_install do |installer_representation|
installer_representation.project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'YES'
end
end
end

Related

App dependeing on CocoaPod distributing as xcframework with its own dependencies crashes on startup with dyld error even if I use post install script

I'm developing a framework which will be distributed via CocoaPods as .xcframework. The framework is depending on some third party libraries and using CocoaPods to resolve that dependencies. To support the module stability feature in my framework I set BUILD_LIBRARY_FOR_DISTRUBUTION option to YES in build settings of the framework project.
I know that if my module-stable framework using some dependencies I should set BUILD_LIBRARY_FOR_DISTRUBUTION=YES setting for each dependency used by the framework. I achieving this by adding post install script to Podfile in app where the framework is integrated. This script looks like this:
post_install do |installer|
installer.pods_project.build_configurations.each do |config|
config.build_settings["BUILD_LIBRARY_FOR_DISTRIBUTION"] = "YES"
end
end
If I open some project that integrates my .xcframework via CocoaPods in Xcode with the same version that was used for the framework building (Xcode 12.5 in my case), everything will be fine on build and run. But if I try to build and run this project in Xcode with some other version (I tested it with Xcode 12.4), launched app will crash on startup with "dyld: Symbol not found..." error.
How to achieve true module stability for my framework even if it has some dependencies? And, if it possible, how to avoid forcing our clients to add post install script to their podfiles?
I ended up using static linking for the third party libraries. If you use CocoaPods, just write:
use_frameworks! :linkage => :static
Then, in the swift files you'll need to avoid exporting the third party symbols by:
#_implementationOnly import Alamofire

Excluding arm64 architecture leads to 'No such module: AWSAppSync'

I am currently working on a Swift 5.0 project (Xcode 12). I currently use an M! computer. For my project, I have a couple of pod dependencies that I need (AWS, Google, etc) to make my project work. When I run my code on a IOS device, I encounter no issues. But when I try to run the project on a simulator, I run into different errors involving the pod linking.
The Google places autocomplete FAQ says that if I have troubles building on an iOS simulator using Xcode 12, I should exclude the arm64 architecture for iOS simulators by altering the project build settings. But upon doing that, I get a warning of "No such module found: AWSAppSync".
In attempting to fix this, I've added 'x86_64' and 'x86' to architectures, set "Build Active Architecture Only" to "yes", and made sure my pod's build settings have the same "Build Active Architecture Only" value, which results in no change. I have also tried pod update, install, install --repo-update, cleaning the build folder, deleting derived data, and restarting Xcode.
When I set "Build Active Architecture Only" to "No" for both sets of build settings (pod and project), I get another error from a different non-AWS pod:
"Could not find module 'MultiSlider' for target 'x86_64-apple-ios-simulator'; found: arm64, arm64-apple-ios-simulator"
Removing any code references to the multi slider then lets the app fully build, but the app crashes before launching on the simulator with an error of "unrecognized selector sent to instance 0x60000067fd90".
Note that with any of these attempted fixes, the app continues to run on an actual iOS device as expected. I'm very new to pods and would really appreciate any help or insight anyone could offer! Thank you in advance.
I had to exclude the arm64 architecture for each of the pods when building for the simulator. See https://narlei.com/development/apple-m1-xcode-error-when-build-in-simulator/ for more details, but it seems that excluding arm64 from the project AND excluding it in the Podfile for each pod's target is necessary.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES'
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
end
end
end

iOS - watchOS App publishing issue CFBundleIdentifier collision

After the app uploading I receive the following email
We identified one or more issues with a recent delivery for your app,
XXX. Please correct the following issues, then upload again.
ITMS-90806: CFBundleIdentifier collision - Each bundle must have a
unique bundle identifier. The bundle identifier
'org.cocoapods.CocoaLumberjack' is used in the bundles
'[CocoaLumberjack.framework, CocoaLumberjack.framework]'
CocoaLumberjack is a third party library that I've already used in the past a lot of times without any problem, I am pretty confused.
It is not related to the framework's .plist keyword CFBundlePackageType
as it is specified in this question/answer Framework CFBundleIdentifier Collision. The CocoaLumberjack bundle package type is "Framework" (CFBundlePackageType = FMWK). CocoaLumberjack is a wide used third party library added to my project using cocoapods.
The issue is probably related to the watchOS target in my app bundle.
The CocoaLumberjack library is used in both iOS app and watchOS app and it is causing the issue about the bundle identifier duplication.
CFBundleIdentifier collision is detected by Apple Connect server if sharing framework between iOS target and Watch Extension.
target 'App' do
platform :ios, '9.0'
# Pods for App
...
pod 'CocoaLumberjack/Swift', '~> 3.5.3'
...
end
target 'AppWatch Extension' do
platform :watchos, '5.0'
# Pods for Watch Extension
...
pod 'CocoaLumberjack/Swift', '~> 3.5.3'
...
end
The iOS app is using the library and the watchOS extension is using the same library. They are using different libraries but CocoaLumberjack is the only one present in both.
I have already published my app a lot of times in the past without any issues with the same libraries configuration. I guess that the Apple has changed some constraints about bundle identifier in the last few days.
The same issue is present also using Carthage.
As a temporary workaround I have manually renamed the bundle identifier in the watchOS extension then the app publishing is working fine but it does not look like a nice solution, especially if you are running the build on a CI system.
A better option is to add a specific post install operation in pod file:
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == 'CocoaLumberjack-watchOS'
target.build_configurations.each do |config|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}-$(PLATFORM_NAME)'
end
end
end
end
or if you have to handle multiple libraries:
post_install do |installer|
watchosLibs = ['Lib1-watchOS', 'Lib2-watchOS', 'Lib3-watchOS']
installer.pods_project.targets.each do |target|
if watchosLibs.include? target.name
target.build_configurations.each do |config|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}.${PLATFORM_NAME}"
end
end
end
end
Pay attention to rename pods bundle identifier because some libraries don't behave correctly otherwise.
I suggest to rename only the libraries rejected by Apple in order to minimize the possible issues.
Currently there are some different open threads about this issue:
On Apple forum (currently no more available)
On Cocoapods github project
A similar issue is present also using Carthage instead of Cocoapods
On Carthage github project
If Apple will not change this new policy about bundle identifier then a more clean solution will probably come from cocoapods team.
Apparently Apple changed the validation process. It looks like they don't allow to platform specific frameworks within an app to have the same identifier.
There's a post on the forum about this as well: https://forums.developer.apple.com/thread/122048
If you're running into this issue because you're using Cocoapods you could patch your Podfile to append the Platform Name to the bundle identifier so that they'll be always unique (source):
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}-$(PLATFORM_NAME)'
end
end
end
If you have multiple targets in your app you can change the watchOS targets in your scheme in XCode and append .watchos to the identifier as well.
You don't need to change every target, its cleaner to write something like this:
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.platform_name == :watchos
target.build_configurations.each do |config|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}-$(PLATFORM_NAME)'
end
end
end
end
Here is how I've worked around the problem for Carthage.
1) create a Carthage build script that separates out the different Carthage build phases
2) when you do the actual framework builds; first build the problem frameworks for iOS (I only had one), then modify your project files to change the bundle identifier, then build those frameworks for watchOS, then build the rest of your frameworks
carthage bootstrap --no-checkout
carthage checkout
#undo previous CFBundleIdentifier changes
sed -i '' 's/com.someco.MyFramework.watchOS;/com.someco.MyFramework;/g' Carthage/Checkouts/MyFramework/MyFramework.xcodeproj/project.pbxproj
carthage build --cache-builds --platform iOS
#set a unique CFBundleIdentifier
sed -i '' 's/com.someco.MyFramework;/com.someco.MyFramework.watchOS;/g' Carthage/Checkouts/MyFramework/MyFramework.xcodeproj/project.pbxproj
carthage build --no-use-binaries --platform watchOS --configuration $CONF $VERBOSE MyFramework
One option is - you can add ".watchos"(abc.asd.alomofire.watchos) to the watch bundle identifier manually.
Just remove the embed frameworks build phase from your extension.
Click on extension in target section -> Build phases -> remove the embed pods frameworks
See attached picture:

Swift "Invalid Mach-O Format" Error [duplicate]

I just got this error when submitting an app to the app store.
Does this mean I need to set ENABLE_BITCODE for all dependencies? I tried that but then got errors saying the dependencies were not compatible with bitcode (or something like that)...
I had the same problem earlier this morning. In fact the answer is in the error : "Verify that all of the targets for a platform have a consistent value for the ENABLE_BITCODE build settings"
I had a target (with ENABLE_BITCODE set to NO), using multiple pods having ENABLE_BITCODE set to YES. So, all I had to, do is set ENABLE_BITCODE to YES in my project target. But I guess you have a choice, you can also set ENABLE_BITCODE to NO in all the libs your are using.
The easiest and most common fix:
You can uncheck "Include Bitcode" when submitting the app via Xcode.
If you use xcodebuild, you can use pass an exportOptionsPlist with the value of uploadBitcode set to false. In my case, we're using xctool to build the app and don't have the ability to pass an exportOptionsPlist, so we had to remove bitcode from all of our frameworks.
If anyone is using cocoapods and wants to disable bitcode for their frameworks, you can just add the following to your podfile:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
Via https://stackoverflow.com/a/32685434/1417922
To add a little more clarification as to what's going on with this issue:
It seems that apple just started enforcing this yesterday. If your main binary has bitcode disabled, but you include a static library or framework that has bitcode enabled, it will fail validation. It goes the other way too: if your main binary has bitcode enabled, but you include a library/framework that has bitcode disabled, it will fail validation.
I had a few dependencies from GoogleMaps and Amazon that made it non trivial to switch everything to enable bitcode, so I simply disabled it and removed bitcode from one static library I had imported in my project. You can strip bitcode from any binary by using this following command
$ xcrun bitcode_strip -r {Framework}.dylib -o tmp.dylib
$ mv tmp.dylib {Framework}.dylib
https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html
While the above are solutions to the problem, I don't agree that if the main binary has bitcode disabled that all of the included binaries should need it as well. Bitcode is just some IR code that Apple can use for app thinning--why don't they just strip it from other binaries (which I assume is what they previously did)? This doesn't make a ton of sense to me.
Apple thread https://forums.developer.apple.com/thread/48071
I just unchecked "include bitcode" and it started to upload
For Carthage
Open your libraries in your project folder (Carthage->Checkouts->[lib name])
Then open each lib in Xcode
Set Enable Bitcode - No in build settings
Do it for each lib in your list
Build carthage carthage build --platform xxx
Then you can archive and submit to the Appstore successfully
We were getting same error "Xcode - Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store" from last friday (3-june-2016) .. used the below mentioned 2 steps to get this done
Step 1:
Added code to pod file to mark 'ENABLE_BITCODE' = 'NO' in pods
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
Step 2:
Marked 'ENABLE_BITCODE' = 'NO' in pods for the project
Note: Tried with marking 'ENABLE_BITCODE' = 'YES' in pods and in my project too but as we are using twillio framework for calling which has a flag -read_only_relocs which does not allow compilation with 'ENABLE_BITCODE' = 'YES'. So if your app does not use any of such framework with -read_only_relocs then you can proceed with making 'ENABLE_BITCODE' = 'YES' as it will be good for your app.
For those who are having build error after setting "Enable BitCode" to Yes.
I have to update all the library.But,the easiest part is I use Cocoapods.So,please update all your pod project : (One by one) or All
Then set Enable BitCode to "No" before you archive.
Then Archive>>Upload>>It will pass this error.
Cheers.
I had the same issue with project "ENABLE_BITCODE = YES" and dependencies "ENABLE_BITCODE = YES" on my CI with Xcode 7.3.
Solution was updating Xcode to latest available version (7.3.1)

Xcode - Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store

I just got this error when submitting an app to the app store.
Does this mean I need to set ENABLE_BITCODE for all dependencies? I tried that but then got errors saying the dependencies were not compatible with bitcode (or something like that)...
I had the same problem earlier this morning. In fact the answer is in the error : "Verify that all of the targets for a platform have a consistent value for the ENABLE_BITCODE build settings"
I had a target (with ENABLE_BITCODE set to NO), using multiple pods having ENABLE_BITCODE set to YES. So, all I had to, do is set ENABLE_BITCODE to YES in my project target. But I guess you have a choice, you can also set ENABLE_BITCODE to NO in all the libs your are using.
The easiest and most common fix:
You can uncheck "Include Bitcode" when submitting the app via Xcode.
If you use xcodebuild, you can use pass an exportOptionsPlist with the value of uploadBitcode set to false. In my case, we're using xctool to build the app and don't have the ability to pass an exportOptionsPlist, so we had to remove bitcode from all of our frameworks.
If anyone is using cocoapods and wants to disable bitcode for their frameworks, you can just add the following to your podfile:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
Via https://stackoverflow.com/a/32685434/1417922
To add a little more clarification as to what's going on with this issue:
It seems that apple just started enforcing this yesterday. If your main binary has bitcode disabled, but you include a static library or framework that has bitcode enabled, it will fail validation. It goes the other way too: if your main binary has bitcode enabled, but you include a library/framework that has bitcode disabled, it will fail validation.
I had a few dependencies from GoogleMaps and Amazon that made it non trivial to switch everything to enable bitcode, so I simply disabled it and removed bitcode from one static library I had imported in my project. You can strip bitcode from any binary by using this following command
$ xcrun bitcode_strip -r {Framework}.dylib -o tmp.dylib
$ mv tmp.dylib {Framework}.dylib
https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html
While the above are solutions to the problem, I don't agree that if the main binary has bitcode disabled that all of the included binaries should need it as well. Bitcode is just some IR code that Apple can use for app thinning--why don't they just strip it from other binaries (which I assume is what they previously did)? This doesn't make a ton of sense to me.
Apple thread https://forums.developer.apple.com/thread/48071
I just unchecked "include bitcode" and it started to upload
For Carthage
Open your libraries in your project folder (Carthage->Checkouts->[lib name])
Then open each lib in Xcode
Set Enable Bitcode - No in build settings
Do it for each lib in your list
Build carthage carthage build --platform xxx
Then you can archive and submit to the Appstore successfully
We were getting same error "Xcode - Error ITMS-90635 - Invalid Mach-O in bundle - submitting to App store" from last friday (3-june-2016) .. used the below mentioned 2 steps to get this done
Step 1:
Added code to pod file to mark 'ENABLE_BITCODE' = 'NO' in pods
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
Step 2:
Marked 'ENABLE_BITCODE' = 'NO' in pods for the project
Note: Tried with marking 'ENABLE_BITCODE' = 'YES' in pods and in my project too but as we are using twillio framework for calling which has a flag -read_only_relocs which does not allow compilation with 'ENABLE_BITCODE' = 'YES'. So if your app does not use any of such framework with -read_only_relocs then you can proceed with making 'ENABLE_BITCODE' = 'YES' as it will be good for your app.
For those who are having build error after setting "Enable BitCode" to Yes.
I have to update all the library.But,the easiest part is I use Cocoapods.So,please update all your pod project : (One by one) or All
Then set Enable BitCode to "No" before you archive.
Then Archive>>Upload>>It will pass this error.
Cheers.
I had the same issue with project "ENABLE_BITCODE = YES" and dependencies "ENABLE_BITCODE = YES" on my CI with Xcode 7.3.
Solution was updating Xcode to latest available version (7.3.1)

Resources