From 473ad0a970438fd3414139f197f26aa47a370edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adin=20=C4=86ebi=C4=87?= Date: Thu, 23 Jan 2025 16:46:31 +0100 Subject: [PATCH] Support bundling live activities extensions with ios_app_clip (#2630) Per [Apple's documentation](https://developer.apple.com/documentation/appclip/offering-live-activities-with-your-app-clip) we are allowed to bundle extensions with app clips but only live activities. --------- Signed-off-by: Adin Cebic --- apple/internal/ios_rules.bzl | 17 +++++++-- doc/rules-ios.md | 9 ++--- test/starlark_tests/ios_app_clip_tests.bzl | 11 ++++++ .../targets_under_test/ios/BUILD | 35 +++++++++++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/apple/internal/ios_rules.bzl b/apple/internal/ios_rules.bzl index 8bf3584b24..b3cb85385f 100644 --- a/apple/internal/ios_rules.bzl +++ b/apple/internal/ios_rules.bzl @@ -557,7 +557,11 @@ def _ios_app_clip_impl(ctx): suffix_default = ctx.attr._bundle_id_suffix_default, shared_capabilities = ctx.attr.shared_capabilities, ) - embeddable_targets = ctx.attr.frameworks + bundle_verification_targets = [struct(target = ext) for ext in ctx.attr.extensions] + embeddable_targets = ( + ctx.attr.frameworks + + ctx.attr.extensions + ) executable_name = ctx.attr.executable_name features = features_support.compute_enabled_features( requested_features = ctx.features, @@ -717,7 +721,7 @@ def _ios_app_clip_impl(ctx): platform_prerequisites = platform_prerequisites, provisioning_profile = getattr(ctx.file, "provisioning_profile", None), rule_descriptor = rule_descriptor, - targets = ctx.attr.deps + ctx.attr.frameworks, + targets = ctx.attr.deps + ctx.attr.extensions + ctx.attr.frameworks, ), partials.resources_partial( actions = actions, @@ -725,6 +729,7 @@ def _ios_app_clip_impl(ctx): bundle_extension = bundle_extension, bundle_id = bundle_id, bundle_name = bundle_name, + bundle_verification_targets = bundle_verification_targets, environment_plist = ctx.file._environment_plist, executable_name = executable_name, launch_storyboard = ctx.file.launch_storyboard, @@ -2707,6 +2712,14 @@ The `.storyboard` or `.xib` file that should be used as the launch screen for th provided file will be compiled into the appropriate format (`.storyboardc` or `.nib`) and placed in the root of the final bundle. The generated file will also be registered in the bundle's Info.plist under the key `UILaunchStoryboardName`. +""", + ), + "extensions": attr.label_list( + providers = [[AppleBundleInfo, IosExtensionBundleInfo]], + doc = """ +A list of ios_extension live activity extensions to include in the final app clip bundle. +It is only possible to embed live activity WidgetKit extensions. +Visit Apple developer documentation page for more info https://developer.apple.com/documentation/appclip/offering-live-activities-with-your-app-clip. """, ), }, diff --git a/doc/rules-ios.md b/doc/rules-ios.md index 63533ce502..7bd289188a 100644 --- a/doc/rules-ios.md +++ b/doc/rules-ios.md @@ -9,10 +9,10 @@
 ios_app_clip(name, deps, resources, additional_linker_inputs, app_icons, bundle_id,
              bundle_id_suffix, bundle_name, codesign_inputs, codesignopts, entitlements,
-             entitlements_validation, executable_name, exported_symbols_lists, families, frameworks,
-             infoplists, ipa_post_processor, launch_storyboard, linkopts, locales_to_include,
-             minimum_deployment_os_version, minimum_os_version, platform_type, provisioning_profile,
-             shared_capabilities, stamp, strings, version)
+             entitlements_validation, executable_name, exported_symbols_lists, extensions, families,
+             frameworks, infoplists, ipa_post_processor, launch_storyboard, linkopts,
+             locales_to_include, minimum_deployment_os_version, minimum_os_version, platform_type,
+             provisioning_profile, shared_capabilities, stamp, strings, version)
 
Builds and bundles an iOS App Clip. @@ -36,6 +36,7 @@ Builds and bundles an iOS App Clip. | entitlements_validation | An `entitlements_validation_mode` to control the validation of the requested entitlements against the provisioning profile to ensure they are supported. | String | optional | `"loose"` | | executable_name | The desired name of the executable, if the bundle has an executable. If this attribute is not set, then the name of the `bundle_name` attribute will be used if it is set; if not, then the name of the target will be used instead. | String | optional | `""` | | exported_symbols_lists | A list of targets containing exported symbols lists files for the linker to control symbol resolution.

Each file is expected to have a list of global symbol names that will remain as global symbols in the compiled binary owned by this framework. All other global symbols will be treated as if they were marked as `__private_extern__` (aka `visibility=hidden`) and will not be global in the output file.

See the man page documentation for `ld(1)` on macOS for more details. | List of labels | optional | `[]` | +| extensions | A list of ios_extension live activity extensions to include in the final app clip bundle. It is only possible to embed live activity WidgetKit extensions. Visit Apple developer documentation page for more info https://developer.apple.com/documentation/appclip/offering-live-activities-with-your-app-clip. | List of labels | optional | `[]` | | families | A list of device families supported by this rule. At least one must be specified. | List of strings | required | | | frameworks | A list of framework targets (see [`ios_framework`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-ios.md#ios_framework)) that this target depends on. | List of labels | optional | `[]` | | infoplists | A list of .plist files that will be merged to form the Info.plist for this target. At least one file must be specified. Please see [Info.plist Handling](https://github.com/bazelbuild/rules_apple/blob/master/doc/common_info.md#infoplist-handling) for what is supported. | List of labels | required | | diff --git a/test/starlark_tests/ios_app_clip_tests.bzl b/test/starlark_tests/ios_app_clip_tests.bzl index 6649ec7967..07ea87304c 100644 --- a/test/starlark_tests/ios_app_clip_tests.bzl +++ b/test/starlark_tests/ios_app_clip_tests.bzl @@ -212,6 +212,17 @@ def ios_app_clip_test_suite(name): tags = [name], ) + # Tests inclusion of extensions. + archive_contents_test( + name = "{}_contains_ios_extension".format(name), + build_type = "device", + target_under_test = "//test/starlark_tests/targets_under_test/ios:app_clip_with_ext", + contains = [ + "$BUNDLE_ROOT/PlugIns/swift_ios_app_clip_ext.appex/swift_ios_app_clip_ext", + ], + tags = [name], + ) + native.test_suite( name = name, tags = [name], diff --git a/test/starlark_tests/targets_under_test/ios/BUILD b/test/starlark_tests/targets_under_test/ios/BUILD index aff534cd81..3a255f403e 100644 --- a/test/starlark_tests/targets_under_test/ios/BUILD +++ b/test/starlark_tests/targets_under_test/ios/BUILD @@ -1516,6 +1516,22 @@ ios_extension( ], ) +ios_extension( + name = "swift_ios_app_clip_ext", + bundle_id = "com.google.example.clip.ext", + entitlements = "//test/starlark_tests/resources:entitlements.plist", + families = ["iphone"], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = common.min_os_ios.baseline, + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = common.fixture_tags, + deps = [ + "//test/starlark_tests/resources:swift_main_lib", + ], +) + ios_extension( name = "extensionkit_ext", bundle_id = "com.google.example.ext", @@ -4502,6 +4518,25 @@ ios_app_clip( ], ) +ios_app_clip( + name = "app_clip_with_ext", + bundle_id = "com.google.example.clip", + entitlements = "//test/starlark_tests/resources:entitlements.plist", + extensions = [":swift_ios_app_clip_ext"], + families = ["iphone"], + infoplists = [ + "//test/starlark_tests/resources:Info.plist", + ], + minimum_os_version = common.min_os_ios.appclip_support, + provisioning_profile = "//test/testdata/provisioning:integration_testing_ios.mobileprovision", + tags = common.fixture_tags, + deps = [ + ":objc_lib_with_ios_framework", + ":swift_lib_with_ios_framework", + "//test/starlark_tests/resources:objc_main_lib", + ], +) + # --------------------------------------------------------------------------------------- # Targets for importing XCFramework tests.