Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExtensionKit App Extensions not supported #1943

Open
maustinstar opened this issue Apr 12, 2023 · 7 comments
Open

ExtensionKit App Extensions not supported #1943

maustinstar opened this issue Apr 12, 2023 · 7 comments

Comments

@maustinstar
Copy link

App extensions like Background Assets are of type EXAppExtension, instead of NSExtension, and have some different build settings. An EXAppExtension is of product type com.apple.product-type.extensionkit-extension and installed into the Extensions directory instead of PlugIns.

Trying to configure a Background Asset downloader extension with current Bazel rules will run into validation errors, since PlugIns expect an NSExtension dictionary in Info.plist, but the extension point com.apple.background-asset-downloader-extension disallows that property.

For now, we can work around this simply by moving the .appex bundle from PlugIns to Extensions.

@qyang-nj
Copy link
Contributor

The new ExtensionKit Extension is very similar to the current App Extension, just with a few differences.

App Extension ExtensionKit Extension
xcode project type com.apple.product-type.app-extension com.apple.product-type.extensionkit-extension
Info.plist NSEXtensions EXAppExtensionAttributes
bundle folder *.app/PlugIns *.app/Extensions

There are two potential approaches to implement this:

  1. Add a parameter (maybe called "extension_type"?) to the existing ios_extension rule, but it looks we have "one product type per rule" convention in rules_apple.
  2. Add a new rule called ios_extensionkit_extension. This will be extremely similar to ios_extension. We probably also need to rename ios_extension to ios_app_extension for claritrty.

We're happy to implement this, but want to start the discussion beforehand. cc: @keith

@maustinstar
Copy link
Author

maustinstar commented Apr 14, 2023

I noticed the watchos_extension has an attribute to change the product type and linking flags. It's used by setting application_extension = True on watchos_extension. We could follow a similar pattern with setting extensionkit_extension = True

@BalestraPatrick
Copy link
Member

Thanks for the extensive and detailed proposal! I think going with an attribute like you did in the linked PR probably makes sense. From what I understand, all extensions support both types except the new "Background Assets" which only supports EXAppExtension? We should make sure that we disallow making the mistake of creating a Background Assets extension but not setting extensionkit_extension = True (either if some Apple validation tool would fail during compilation, or in our rules).

@maustinstar
Copy link
Author

I'm not sure which extension types are valid for ExtensionKit vs older app extensions, but I agree that an error would be helpful to surface this to consumers. I agree a disallow-list will be more helpful than an allow-list, since Apple will release new extension types, and consumers shouldn't need to wait for updates.

We've noticed that creating a Background Asset extension as an older extension type (NSExtension and app-extension) will compile, but fails App Store validation and won't install to a device/simulator.

To your recommendation of confirming the extension points are valid with ExtensionKit - can we check Info.plist values while building with Bazel? I wasn't sure if Starlark had the ability to read input files. The extension point string defining the extension point is either in the NSExtension Info.plist dictionary or EXAppExtensionAttributes dictionary.

@maustinstar
Copy link
Author

Oh, I see. We can follow a similar pattern as plisttool to run a script and validate fields.

I think some validation warnings/errors can be useful, but we should be cautious not to block future legitimate use cases. Should we create any rule attributes to silence these warnings?

Furthermore, should we use the plist to set the product type instead of expecting extensionkit_extension = True/False from the rule? (i.e. switch the product type from the presence of NSExtension or EXAppExtensionAttributes in the plist)

@BalestraPatrick
Copy link
Member

BalestraPatrick commented Apr 16, 2023

I just tried quickly to create an Intents extension for iOS (which isn't iOS 16 only), and I could't find a way to have Xcode add it into Extensions instead of PlugIns. I tried setting the deployment target to iOS 16.2, so it sounds like only the new extensions which are released and available from iOS 16 onwards support this way of bundling. Have you seen differently? If so, it might be difficult for someone to know to what value they need to set extensionkit_extension to. It might be better to infer the value from the type of extension, but I'm not sure if there's a way to do that today. I agree with the fact that it might make it more painful in the long-term to support multiple extension types, but it's a tradeoff. I don't have a strong opinion here.

I remembered that we also have something called entitlements_validation_mode but that's more for provisioning profiles, we could have something similar. Whether an attribute or a flag makes more sense, I'm not sure yet. If we can prevent users from submitting builds which aren't accepted by Apple, I'm all for it (we ran into a few over the last few months and they quite annoying to figure out).

@maustinstar
Copy link
Author

maustinstar commented Apr 16, 2023

From Info.plist docs, it looks like these are supported NSExtension extension points, and EXExtensionPointIdentifiers aren't documented online, but I scanned Xcode's templates (/Applications/Xcode.app/Contents/Developer/Platforms/*.platform/Developer/Library/Xcode/Templates/Project\ Templates/*/Application\ Extension/) and found this short list of extension types, and macOS supports third part extension points through ExtensionKit.

I started this commit to plisttool with the following logic:

  • If the extension point string matches a known extension point string for a different App Extension product identifier (e.g. building with ExtensionKit, but recognized the extension as an NSExtension), log a warning, but do not raise an error
  • If the extension has a mismatched plist key (e.g. building with ExtensionKit, but found NSExtension in Info.plist), raise an error, and provide tips to fix.
  • If the extension is missing the expected plist key (e.g. building with ExtensionKit, but missing EXAppExtensionAttributes in Info.plist), raise an error, and provide tips to fix.

I think this should provide discoverability to the correct build settings without blocking valid use cases, such as:

  • Apple creates a new extension point
  • Apple changes an extension point to support both NSExtension and ExtensionKit
  • Third party ExtensionKit extension point identifiers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants