Carthage: CFBundleIdentifier collision if sharing framework between iOS target and Watch Extension

Created on 3 Sep 2019  Â·  9Comments  Â·  Source: Carthage/Carthage

  • carthage install method: [ ] .pkg, [X] homebrew, [ ] source
  • which carthage: /usr/local/bin/carthage
  • carthage version: 0.33.0
  • xcodebuild -version: Xcode 11.0 Build version 11M392r
  • Are you using --no-build? No
  • Are you using --no-use-binaries? Yes
  • Are you using --use-submodules? Yes
  • Are you using --cache-builds? No
  • Are you using --new-resolver? No

Cartfile

github "SVProgressHUD/SVProgressHUD"
github "AliSoftware/Reusable" "master"
github "onevcat/Kingfisher"
github "kishikawakatsumi/KeychainAccess"
github "mac-cain13/R.swift.Library"
github "SnapKit/SnapKit"
github "ReactiveX/RxSwift"
github "RxSwiftCommunity/RxDataSources"
github "Swinject/Swinject"
github "Swinject/SwinjectStoryboard"
github "Swinject/SwinjectAutoregistration"

binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json"
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseMessagingBinary.json"
binary "https://building42.github.io/Specs/Carthage/iOS/Crashlytics.json"
binary "https://building42.github.io/Specs/Carthage/iOS/Fabric.json"

Carthage Output

[17:33:02]: â–¸ *** Checking out Swinject at "2.6.2"
[17:33:02]: â–¸ *** Checking out Reusable at "3f2491cdda55c5f2ac4b216f5877049000012c26"
[17:33:02]: â–¸ *** Checking out R.swift.Library at "v5.0.1"
[17:33:02]: â–¸ *** Checking out Kingfisher at "5.7.1"
[17:33:02]: â–¸ *** Checking out SVProgressHUD at "2.2.5"
[17:33:02]: â–¸ *** Checking out SwinjectStoryboard at "2.2.0"
[17:33:02]: â–¸ *** Checking out KeychainAccess at "v3.2.0"
[17:33:02]: â–¸ *** Checking out SwinjectAutoregistration at "2.6.1"
[17:33:02]: â–¸ *** Checking out RxDataSources at "4.0.1"
[17:33:02]: â–¸ *** Checking out SnapKit at "5.0.1"
[17:33:02]: â–¸ *** Checking out RxSwift at "5.0.1"
[17:33:02]: â–¸ *** xcodebuild output can be found in /var/folders/st/8gh5d43j1c97g360h7v89hpc0000gn/T/carthage-xcodebuild.yPL6gz.log
[17:33:02]: â–¸ *** Valid cache found for Crashlytics, skipping build
[17:33:03]: â–¸ *** Valid cache found for Fabric, skipping build
[17:33:03]: â–¸ *** Valid cache found for FirebaseAnalyticsBinary, skipping build
[17:33:03]: â–¸ *** Valid cache found for FirebaseMessagingBinary, skipping build
[17:33:03]: â–¸ *** Valid cache found for KeychainAccess, skipping build
[17:33:03]: â–¸ *** Valid cache found for Kingfisher, skipping build
[17:33:03]: â–¸ *** Valid cache found for R.swift.Library, skipping build
[17:33:03]: â–¸ *** Valid cache found for Reusable, skipping build
[17:33:04]: â–¸ *** Valid cache found for RxSwift, skipping build
[17:33:04]: â–¸ *** Valid cache found for RxDataSources, skipping build
[17:33:04]: â–¸ *** Valid cache found for SnapKit, skipping build
[17:33:04]: â–¸ *** Valid cache found for SVProgressHUD, skipping build
[17:33:04]: â–¸ *** Valid cache found for Swinject, skipping build
[17:33:04]: â–¸ *** Valid cache found for SwinjectAutoregistration, skipping build
[17:33:04]: â–¸ *** Valid cache found for SwinjectStoryboard, skipping build

Unable to share framework between iOS and Watch Extension. After upload to App Store Connect, I receive an email with CFBundleIdentifier collision error.

Similar ticket for CocoaPods https://github.com/CocoaPods/CocoaPods/issues/9135

stale

Most helpful comment

@abdullah-s Here is a script adapted from the one I use:

#!/bin/sh -e

carthage $1

for framework in Carthage/Build/watchOS/*.framework
do
    [ -e "$framework" ] || continue

    EXISTING_BUNDLE_IDENTIFIER=`plutil -extract CFBundleIdentifier xml1 -o - "./$framework/Info.plist" | sed -n "s/.*<string>\(.*\)<\/string>.*/\1/p"`
    NEW_BUNDLE_IDENTIFIER="watchos.$EXISTING_BUNDLE_IDENTIFIER"

    plutil -replace CFBundleIdentifier -string "$NEW_BUNDLE_IDENTIFIER" "$framework/Info.plist"
done

All 9 comments

This is happening to us too – someone posted a great workaround for Cocoapods that lets us specify a bundle identifier after the dependency is installed.

Is there a way to do something similar with Carthage?

Edit: we ended up editing the bundle identifiers in our dependency after Carthage had downloaded the dependency, but before it attempted to build. Slightly tricky because there was some dynamic code, but it seems to be working

I don't think carthage should attempt to modify any bundle identifier

Here is how I've worked around the problem.
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, then modify your project files to change the bundle identifier, then build those frameworks for watchOS, then build the reset 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

We use a wrapper shell script around Carthage. After building the dependencies our script loops over each watchOS framework and uses plutil to add watch. to the beginning of each of our watchOS framework Info.plist files.

@DavidBrunow can you please share that shell script

@abdullah-s Here is a script adapted from the one I use:

#!/bin/sh -e

carthage $1

for framework in Carthage/Build/watchOS/*.framework
do
    [ -e "$framework" ] || continue

    EXISTING_BUNDLE_IDENTIFIER=`plutil -extract CFBundleIdentifier xml1 -o - "./$framework/Info.plist" | sed -n "s/.*<string>\(.*\)<\/string>.*/\1/p"`
    NEW_BUNDLE_IDENTIFIER="watchos.$EXISTING_BUNDLE_IDENTIFIER"

    plutil -replace CFBundleIdentifier -string "$NEW_BUNDLE_IDENTIFIER" "$framework/Info.plist"
done

@DavidBrunow you are a legend, i appreciate your time.

i ended up writing my own script but it is so undynamic:

thanks to @dvshelley

`

!/bin/bash

WORKING_DIR=$(pwd)

carthage bootstrap --no-checkout

carthage checkout

carthage build --cache-builds --platform iOS

echo "----start renaming----"

RxSwift and RxCocoa

sed -i '' 's/io.rx.\$(PRODUCT_NAME:rfc1034identifier)/io.rx.\$(PRODUCT_NAME:rfc1034identifier).watchOS/g' $WORKING_DIR/Carthage/Checkouts/RxSwift/Rx.xcodeproj/project.pbxproj

Alamofire

sed -i '' 's/org.alamofire.Alamofire;/org.alamofire.Alamofire.watchOS;/g' $WORKING_DIR/Carthage/Checkouts/Alamofire/Alamofire.xcodeproj/project.pbxproj

AlamofireObjectMapper

sed -i '' 's/com.tristanhimmelman.\$(PRODUCT_NAME:rfc1034identifier)/com.tristanhimmelman.\$(PRODUCT_NAME:rfc1034identifier).watchOS/g' $WORKING_DIR/Carthage/Checkouts/AlamofireObjectMapper/AlamofireObjectMapper.xcodeproj/project.pbxproj

ObjectMapper

sed -i '' 's/com.hearst.$(PRODUCT_NAME:rfc1034identifier)/com.hearst.$(PRODUCT_NAME:rfc1034identifier).watchOS/g' $WORKING_DIR/Carthage/Checkouts/ObjectMapper/ObjectMapper.xcodeproj/project.pbxproj

Swinject

sed -i '' 's/com.el-eleven.Swinject/com.el-eleven.Swinject.watchOS/g' $WORKING_DIR/Carthage/Checkouts/Swinject/Swinject.xcodeproj/project.pbxproj
echo "----done renaming----"

carthage build --no-use-binaries --platform watchOS $VERBOSE

I am experiencing the same issue with the GM build as well. Thanks @DavidBrunow for the script - it did the trick.

Hopefully the issue will be fixed soon.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings