skip to Main Content

Context:

  • We have an Xcode projet that builds an iOS app and a few app extensions.
  • We also have some shared code in Xcode frameworks, that have the flag APPLICATION_EXTENSION_API_ONLY on (so that we can use it in the app extensions).
  • We are currently in the process of modularising the app through SPM modules, and this implies converting these frameworks into SPM modules.

Problem:

The SPM module is not marked as app extension safe, and therefore a warning is emitted for every SPM module linked to an app extension, for each app extension (that makes quite a few warnings).

Comment:

I haven’t found a way to set this flag on an SPM module.

The only thing I have found so far is a way to disable the warning completely, by setting the no_application_extension linker flag to the SPM target — but then I don’t get any warning or error if I use an API unavailable in an app extension (I have tried to use UIApplication.shared in the module and I didn’t get any warning or error; if I try to do that on my existing framework I immediately get a compiler error).

And if on the contrary I set the application_extension linker flag to the SPM target, then not only do I not get any warning or error either when using an API unavailable in app extensions, but I also get a whole lot of warnings when building the app, as many other frameworks that the app uses are not available for use in app extensions.

Question:

How do I get my SPM module to have the same behaviour as we used to have when setting the APPLICATION_EXTENSION_API_ONLY flag in the Xcode target?

This means:

  • not getting any warning when using in an app extension a module marked as safe for use in app extensions
  • while still getting an error when such module uses an API unavailable in app extensions

Ideally, there is a simple way to just set the APPLICATION_EXTENSION_API_ONLY flag on an SPM module and get back the familiar behaviour.

Thanks

2

Answers


  1. Although I’m not sure about this, but I read something here that it’ll be a pain to integrate everything using SPM

    Basically as stated in the Xcode 13 beta 3 release notes:

    Linking Swift packages from application extension targets or watchOS
    applications no longer emits unresolvable warnings about linking to
    libraries not safe for use in application extensions. This means that
    code referencing APIs annotated as unavailable for use in app
    extensions must now themselves be annotated as unavailable for use in
    application extensions, in order to allow that code to be used in both
    apps and app extensions. (66928265)

    You can add the:

    @available(iOSApplicationExtension, unavailable)

    attribute to declarations using app extension unavailable APIs in order to get them to compile in a way that works for both apps and app extensions.

    Login or Signup to reply.
  2. We figured out to use

    swiftSettings: [
                    .unsafeFlags(["-Xfrontend", "-application-extension"])
                ],
    linkerSettings: [
                    .unsafeFlags(["-Xlinker", "-application_extension"])
                ]
    

    The first setting is for giving you a nice red compile error in Xcode on the spot if you try to use some unsafe API. The second setting tells the linker ‘this is an extension safe package’ so you won’t get warnings if you link the package to an extension target or another framework that is extension safe.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search