-
-
Save damian-rzeszot/0b23ad87e5ab5d52aa15c095cbf43c59 to your computer and use it in GitHub Desktop.
| alias plistbuddy=/usr/libexec/PlistBuddy | |
| alias codesign=/usr/bin/codesign | |
| # | |
| # Bundle identifier | |
| # | |
| set_plist_bundle_identifier() { | |
| local bundle_identifier="$1" | |
| local plist_file="$2" | |
| plistbuddy \ | |
| -c "set :CFBundleIdentifier $bundle_identifier" \ | |
| "$plist_file" | |
| } | |
| set_appex_bundle_identifier() { | |
| local appex_target_name="$1" | |
| local bundle_identifier_suffix="$2" | |
| local bundle_identifier="$PRODUCT_BUNDLE_IDENTIFIER.$bundle_identifier_suffix" | |
| local plist_file="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/Info.plist" | |
| set_plist_bundle_identifier "$bundle_identifier" "$plist_file" | |
| } | |
| # | |
| # Bundle version | |
| # | |
| set_plist_bundle_version() { | |
| local bundle_version="$1" | |
| local plist_file="$2" | |
| plistbuddy \ | |
| -c "set :CFBundleShortVersionString $bundle_version" \ | |
| "$plist_file" | |
| } | |
| get_plsit_bundle_version() { | |
| local plist_file="$1" | |
| plistbuddy \ | |
| -c "Print :CFBundleShortVersionString" \ | |
| "$plist_file" | |
| } | |
| get_app_bundle_version() { | |
| local plist_file="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH" | |
| get_plsit_bundle_version "$plist_file" | |
| } | |
| set_appex_bundle_version() { | |
| local appex_target_name="$1" | |
| local bundle_version="$2" | |
| local plist_file="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/Info.plist" | |
| set_plist_bundle_version "$bundle_version" "$plist_file" | |
| } | |
| # | |
| # Bundle build | |
| # | |
| set_plist_bundle_build() { | |
| local bundle_build="$1" | |
| local plist_file="$2" | |
| plistbuddy \ | |
| -c "set :CFBundleVersion $bundle_build" \ | |
| "$plist_file" | |
| } | |
| get_plist_bundle_build() { | |
| local plist_file="$1" | |
| plistbuddy \ | |
| -c "Print :CFBundleVersion" \ | |
| "$plist_file" | |
| } | |
| set_appex_bundle_build() { | |
| local appex_target_name="$1" | |
| local bundle_version="$2" | |
| local plist_file="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/Info.plist" | |
| set_plist_bundle_build "$bundle_version" "$plist_file" | |
| } | |
| get_app_bundle_build() { | |
| local plist_file="$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH" | |
| get_plist_bundle_build "$plist_file" | |
| } | |
| # | |
| # Code signing | |
| # | |
| prepare_entitlements_file() { | |
| local appex_target_name="$1" | |
| local bundle_identifier_suffix="$2" | |
| local output_file="$3" | |
| local original_entitlements="$CONFIGURATION_TEMP_DIR/$appex_target_name.build/$appex_target_name.appex.xcent" | |
| local bundle_identifier="$DEVELOPMENT_TEAM.$PRODUCT_BUNDLE_IDENTIFIER.$bundle_identifier_suffix" | |
| cp "$original_entitlements" "$output_file" | |
| if [[ $CONFIGURATION == "Release" ]] | |
| then | |
| plistbuddy \ | |
| -c "set :application-identifier $bundle_identifier" \ | |
| "$output_file" | |
| plistbuddy \ | |
| -c "set :keychain-access-groups:0 $bundle_identifier" \ | |
| "$output_file" | |
| fi | |
| } | |
| copy_provisioning_profile() { | |
| local appex_target_name="$1" | |
| local provision_source="$2" | |
| local provision_destination="$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex/$EMBEDDED_PROFILE_NAME" | |
| cp "$provision_source" "$provision_destination" | |
| } | |
| resign_appex() { | |
| local appex_target_name="$1" | |
| local entitlements_file="$2" | |
| codesign \ | |
| --force \ | |
| --sign "$EXPANDED_CODE_SIGN_IDENTITY" \ | |
| --entitlements "$entitlements_file" \ | |
| --timestamp=none \ | |
| "$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME/$BUNDLE_PLUGINS_FOLDER_PATH/$appex_target_name.appex" | |
| } | |
| # | |
| # | |
| # | |
| # | |
| # | |
| set_appex_bundle_identifier \ | |
| "NotificationService" \ | |
| "notification-service" | |
| set_appex_bundle_version \ | |
| "NotificationService" \ | |
| `get_app_bundle_version` | |
| set_appex_bundle_build \ | |
| "NotificationService" \ | |
| `get_app_bundle_build` | |
| # Be careful if using `keychain-access-groups` entitlement | |
| prepare_entitlements_file \ | |
| "NotificationService" \ | |
| "notification-service" \ | |
| "$DERIVED_SOURCES_DIR/NotificationService-Entitlements.plist" | |
| copy_provisioning_profile \ | |
| "NotificationService" \ | |
| "$SOURCE_ROOT/../.github/appstore/$TARGET_NAME/profiles/notification-service.mobileprovision" | |
| resign_appex \ | |
| "NotificationService" \ | |
| "$DERIVED_SOURCES_DIR/NotificationService-Entitlements.plist" |
For one who originally did it wrong you figured it all out super quick. How do you do it?!
This whole build settings stuff is new to me. Took me a few rounds of reading to understand it. Also you should post more frequently on Stack Overflow or blog about stuff.
-
But if I understand correct, the
"$SOURCE_ROOT/../.github/appstore/$TARGET_NAME/profiles/notification-service.mobileprovisionis a predetermined path to the target's the provisioning profile. You just need to to figure out where to put it. You do that that in yourcopy_provisioning_profilefunc. Right? -
I like how you pulled in
$DEVELOPMENT_TEAMinto localbundle_identifier="$DEVELOPMENT_TEAM.$PRODUCT_BUNDLE_IDENTIFIER.$bundle_identifier_suffix". That helps you to sign with different teams. Right? -
My 'Notification Service Extension' for which I use to download images, doesn't have any entitlements, but I understand the need to modify the bundleId inside the entitlement's plist. Can I ask why yours needed certain entitlements? Is it because of keychain sharing?
-
That's right.
$SOURCE_ROOT/.../notification-service.mobileprovisionis there, because I use GitHub Actions for deploying the build to App Store. I didn't want to dig in target's build settings via e.g.xcodeproj. That's fair enough solution. -
Yeap. I don't like hardcoding things in scripts.
$DEVELOPMENT_TEAMis provided by Xcode. -
Xcode generates entitlements. The generated one for the notification service extension contains original [bundle] ids, so it has to be overridden.
Thank you. I also wanted to suggest that you can use plutil instead of PlistBuddy. Based on what an Apple Engineer told me plutil is actively updated, PlistBuddy seems to not be updated
Also was there a reason you did alias codesign=/usr/bin/codesign? Couldn't you just used codesign without doing that? It's already in the bin directory`
Sorry. One more thing what's the difference between .entitlements file and .xcent file?
plutil- good point ๐alias codesign- true, it's not needed ๐.xcent- I see no difference. Probably somebody decided to usexcprefixes there, as inxcconfig,xcproject, etc. Looks like legacy naming.
Can see my answer here and the steps I've written. The steps it has are not complete as yours. But I just don't get how you get yours is working given that you're updating the bundleId after 'embed App Extension' step. Based on my understanding that step should fail.
FYI this fails when I'm using a physical device. I haven't tried archiving yet...
Specifically the point I'm referencing from my answer:
Similarly the appex can't be embedded if the bundleId isn't prefixed with the parent app's bundleId.
i.e. I think bundleId should change before the 'embed App Extension' step.
Or is it that you're also updating the bundleId of the parent app in some other script before changing stuff for the appex ie you're able to embed the Appex's into the main app, but then later change the bundle Id for both the main app and appex?
Basically are you doing this?
- embed apppex
- update parent app bundleId and stuff
- update appex bundleId and stuff
Hi, I'm joining very late but I'm struggling to understand something.
I know that this needs to be after what it used to be "Embed App Extensions" which now I think is called "Embed Foundation Extensions"
But when I generate my (desired) only extension, this is only shown at Build Phases of the default target but not in the other ones. I'm trying to understand if that does not matter? If i build my app with target #2, and the script is between Build phases of target #1, still works? Thank you :)
@prohoney you're right, there is an issue with provisioning profile while uploading to App Store. I updated the script. Within this I was able to upload 2 apps to TestFlight.