How to suppress `warning: linking against dylib not safe for use in application extensions`?
Asked Answered
S

8

76

I have a dynamic framework that is shared between an iOS application and an extension. There is some code in that framework that references UIApplication, that is of course, not usable in an extension. Those calls are completely isolated and so I am not worried about them causing problems with my extension.

Since there isn't a flag specified in the warning message, perhaps there isn't way to do it, but how do I suppress warning: linking against dylib not safe for use in application extensions when building my project?

Sailor answered 21/2, 2015 at 22:24 Comment(5)
In the target for your extension there is a build setting in the "build options" section - "Require Only App-Extension-Safe API". If it isn't enabled already, try enabling it...Graupel
Oh by the way - even if everything is running fine by not using the disallowed apis in your extension, there is a good chance apple will reject your extension for linking against it anyway. See the "Handling Common Scenarios" section in the app extension programming guide.Graupel
@Graupel Disabling the Require Only App-Extension-Safe API solved this!Sharasharai
It doesn't help me :(Resurge
In my case, it was simply because I hadn't added a particular framework in to the libraries used by my extension. Did that and the issue went away.Buchan
H
50

For your watch/today-widget extension target (so not your app or libray target), go into the project settings and change the build setting APPLICATION_EXTENSION_API_ONLY / Require Only App-Extension-Safe API to NO.

Hummel answered 26/2, 2016 at 16:56 Comment(7)
This would only turn off the warning. Any use of API not available to Extension will result in rejection during Apple's app review. If you intend to release this app via App Store, it's best to keep the warning turned on and remove use of any APIs that are not allowed for Extensions.Aeolipile
This is the correct answer. I just get rid of 20+ warnings, huge thanks! @Aeolipile FYI use API "not available" to Extension won't result in rejection. I use UIApplication.openURL from my extensions to open container app for years, and not only they always work as expected but also never cause any App Store Review rejection.Stites
Excellent answer! Spent all morning trying to figure out why EventKitUI couldn't be used in my tests when using @testable import MyApp. Flicking the switch to No got it working.Louanneloucks
From XCode 12.5, it will force you to set Require Only App-Extension-Safe API to YES.Yean
This is a risky approach as it does not check for usage of non-safe API and thus App Store rejection. You can remove the warnings and maintain Xcode checks by setting the Require Only App-Extension-Safe API to YES on the Framework target.Firebug
In my case, after setting yes to no, I get a serious warning. When I set it back to yes to build the project anyway, the simple warning disappeared. I don't know why.Stringendo
I'm using some pods in app, and a xcframework in app and keyboard extension, need to set Require Only App-Extension-Safe API to No in app build setting, Yes in both project and keyboard extension setting, then my project could run.Confide
L
44

I think you can use embedded framework to share code between your app extension and its containing app. But you have to be careful that your framework doesn't contain apis which are unavailable to extensions. See Some APIs Are Unavailable to App Extensions and Using an Embedded Framework to Share Code.

If your framework doesn't contain such apis don't forget to set Require Only App-Extension-Safe API to YES in your framework target's Build Settings.

enter image description here

As a second way to share source files between application and extension, you don't have to create a separate framework target. You can just share source files by targeting both two projects.

enter image description here

Linguistic answered 19/2, 2018 at 9:52 Comment(1)
This actually makes more sense than setting NO for the Widget target. Restricting the framework to be extensions-friendly is the right way to go.Skate
B
11

My framework didn't use any restricted API and I was still getting the warning...this solved it for me. enter image description here

Bowler answered 3/11, 2020 at 13:38 Comment(2)
This is the correct answer.Shaven
This needs to be enabled on any dynamic library you're using with the app extension to ensure you're only using app extension safe APIs. I ran into this warning when adding a framework to a tvOS top shelf app extension. As of XCode 14.2 this setting is located under Target > Build Settings.Counter
S
8

Short answer: there isn't really a way to do.

What I ended up doing was refactoring my code to pull out the pieces that were common to my extension on and my dynamic frame so that my extension could safely reference those pieces independent of the phone-specific code.

I ended up doing this because sometime in the future I will need to submit this to the App Store and Apple's guidelines seem pretty clear that referencing UIApplication is a pretty big no-no.

Sailor answered 7/4, 2015 at 2:0 Comment(1)
Where did you place the common code? We have it in a framework and reference this in the app and the extension. But this raises the warning...Corrasion
S
3

Sometimes 'Nanny' doesn't know best.

You can avoid linking to UIApplication.shared and just call the methods dynamically in your framework.

class Application {
    static var shared: UIApplication {
        let sharedSelector = NSSelectorFromString("sharedApplication")
        guard UIApplication.responds(to: sharedSelector) else {
            fatalError("[Extensions cannot access Application]")
        }

        let shared = UIApplication.perform(sharedSelector)
        return shared?.takeUnretainedValue() as! UIApplication
    }
}

This allows you to effectively call UIApplication.shared (just call Application.Shared ) without making the linker freak out.

You will get a crash if you try to call this from an extension.

Sonneteer answered 10/9, 2018 at 12:29 Comment(0)
A
0

I try with this use_frameworks! :linkage => :static but please make sure that your project build successfully and unit tests run successfully.

Aec answered 19/7, 2022 at 15:44 Comment(0)
R
0

Add this to your Podfile, change 'ExtensionName' with your extension target name

 installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|

    if target.name == 'ExtensionName'
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'YES'
 else
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
end
end
end
Ruprecht answered 15/8, 2022 at 12:3 Comment(0)
H
-1

All above Solutions are not working in my case.. I'm working on a framework & when add it to any project then need first to set "Require Only App-Extension-Safe API" to "NO" each and every time into related project.

Havener answered 4/10, 2022 at 6:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.