Get Bundle ID from a different target
Asked Answered
T

3

25

In my Xcode project, I have 4 different schemes (prod, dev, staging, staging2) which changes the bundle identifier of the app that gets installed to the phone. That way I can have all 4 versions installed side by side, similar to this technique.

Now I'm building a Today Extension for iOS 8. It's a new Target requiring its own bundle identifier.

The Extension's Bundle Identifier must be prefixed with the Parent App's Bundle Identifier, or a warning is thrown:

error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.

    Embedded Binary Bundle Identifier:  com.company.app.TodayExtension
    Parent App Bundle Identifier:       com.company.app.staging

In this case, the Embedded Binary Bundle Identifier must be com.company.app.staging.TodayExtension.

Is there a way I can configure my Today Extension target to set its bundle identifier by first looking at the Parent target's bundle identifier? Perhaps through a custom Run Script Build Phase?

Tameika answered 11/9, 2014 at 18:27 Comment(6)
Can you explain in more detail how you solved this problem? In Jafar's answer below, were you somehow able to set PARENT_APP_BUNDLE_IDENTIFIER just by switching schemes, and if so how? Or otherwise what did you specify for the bundle ids and PARENT_APP_BUNDLE_IDENTIFIER in each target (including the extension target)? Thanks!Acuna
In Project Settings | Build Settings | User Defined, create a new entry called PARENT_APP_BUNDLE_ID. I have 4 configurations, I add a value for each one (com.company.app.staging, com.company.app.development, etc.). In you Main App Target's Info.plist, set Bundle Identifier to $(PARENT_APP_BUNDLE_ID). In your Extension Target's Info.plist, set it's Bundle Identifier to $(PARENT_APP_BUNDLE_ID).NameOfYourExtension.Tameika
Aha, completely missed the fact that you were doing this through additional custom build configurations (Project | Info | Configurations) and setting a different value of PARENT_APP_BUNDLE_ID for each config at the Project level, instead thinking you somehow did it by overriding individual target settings. So you're still able to switch schemes to build w/ different bundle ids, since each scheme uses a different set of build configs. Cool, works for me, and helps me clean up duplicate targets and plist files!Acuna
I'm so close! .. but how do I set "different value of PARENT_APP_BUNDLE_ID for each config at the Project level"??Incipit
when you add PARENT_APP_BUNDLE_ID to your build settings at the Project level, you should see all your configs underneath by clicking the triangle to the left. In my app, I have 4 configs (dev, prod, staging, staging2). After creating that user defined build setting, I see all 4 configs, and can assign each one a different value.Tameika
what if my extension embedded to multiple targets?Leonteen
S
33

The build settings of the targets are not available for the other targets. However the build settings of the PROJECT are available.

You can thus add a user-defined build setting in your project and call it PARENT_APP_BUNDLE_IDENTIFIER and set the correct bundle id for all your schemes.

Then in the info tab of the app extension target set the bundle id to

$(PARENT_APP_BUNDLE_IDENTIFIER).$(PRODUCT_NAME:rfc1034identifier)

It worked perfectly fine for me.

Shcherbakov answered 30/9, 2014 at 12:22 Comment(6)
Wonderful! This saves me so much frustration!Tameika
am running same issue.. i followed above osolution... but not suceeded.. i have updated ios 8.0.2 and xcode 6.0.1(officila one) previiously i have 8.0 in that it worked fine for me..Jard
Please clarify this part: "set the correct bundle id for all your schemes"Equipotential
@Tameika did it really solve your problem? Seems to me that the PARENT_APP_BUNDLE_IDENTIFIER will be present independently in your extension's info.plist and get default values from the PROJECT's info.plist which can be useful when using different schemes but it still doesn't solve the problem if you are using different application targets, does it?Aarau
Not work for me. $(PRODUCT_BUNDLE_IDENTIFIER) is defined by project and every target can set and read its value. In your app extension, you read the variable , you get and set itself. It does not make sense.Highlander
Alexis, following up the questions @Equipotential and others have asked, does this solve the problem when you have different targets? Surely I can set a different bundleID for each configuration. But if I have 3 targets then how can I know which target is selected? Can you clarify that in your answer or possibly add screenshots?Suburbanite
L
6

I have Siri extension and multiple targets, so to avoid duplicating extension for every target I added pre-action to every scheme that changes the BundleId of the extension's plist before build:

  1. Select 'Edit scheme'
  2. Click triangle near 'Build'
  3. Choose 'Pre-actions'
  4. Click '+', choose 'New Run Script Action'
  5. Choose target to provide build settings from
  6. In script field paste following with your BundleId and extension folder
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier 
YourDesiredBundleId" "$PROJECT_DIR/YourExtensionFolder/Info.plist"

And it works like a charm! You need to configure it for every scheme.

Lukelukens answered 12/8, 2019 at 13:46 Comment(4)
For me $PROJECT_DIR wasn't the correct directory. I had to use either BUILT_PRODUCTS_DIR or BUILD_DIR insteadSuburbanite
Thanks a lot, very helpful now that you have 1000s of extensions.Liew
Do we have to add above script in the app target scheme or extension scheme? I am having 5 app targets and want to use one service extension. So, where I have to add this run scripts?Velour
@KirtiNikam app target schemeLukelukens
D
3

In my project I need to build different versions of apps (differ in details, e.g. each application is branded with a different logo).

Let's say there is about 10 "app" targets, I can't imagine adding Notification Content and Notification Service extensions per each main target (in this case I would maintaining 30 targets in total - madness).

I run a script (https://gist.github.com/damian-rzeszot/0b23ad87e5ab5d52aa15c095cbf43c59) after "Embed App Extensions" phase. It overrides bundle id in app extension plists and re-signs the bundle.

Den answered 20/4, 2020 at 0:2 Comment(1)
Do you copy all this script and put it in new Run Script in Build Phases???Eyla

© 2022 - 2024 — McMap. All rights reserved.