如何抑制“warning: linking against dylib not safe for use in application extensions”警告?

76
我有一个动态框架,在iOS应用程序和扩展之间共享。在那个框架中有一些代码引用了UIApplication,当然在扩展中无法使用。这些调用是完全隔离的,所以我不担心它们会导致我的扩展出现问题。
由于警告消息中没有指定标志,也许没有办法做到,但是在构建项目时如何抑制warning: linking against dylib not safe for use in application extensions

8
在您的扩展目标中,有一个“生成选项”部分中的构建设置 - “仅要求App扩展安全API”。如果尚未启用,请尝试启用它... - Toastor
2
顺便说一句 - 即使你的扩展程序没有使用不允许的API,并且一切都正常运行,苹果仍有可能因为与之相关的链接而拒绝批准你的扩展程序。请参阅应用程序扩展编程指南中的“处理常见情况”部分。 - Toastor
16
禁用Require Only App-Extension-Safe API解决了这个问题! - loretoparisi
3
这并没有帮助到我 :( - Dmitry
在我的情况下,问题很简单,因为我没有将一个特定的框架添加到我的扩展程序所使用的库中。添加了该框架后,问题就解决了。 - Chris Prince
8个回答

50

针对您的手表/今日小部件扩展目标(而不是您的应用程序或库目标),进入项目设置并更改构建设置APPLICATION_EXTENSION_API_ONLY / 仅需要App-Extension安全APINO


19
这只会关闭警告。在苹果应用审核期间,任何使用Extension不可用的API都将被拒绝。如果您打算通过App Store发布此应用程序,则最好保持警告开启并删除任何不允许使用的API。 - skim
1
这是正确的答案。我刚刚消除了20多个警告,非常感谢!@skim FYI使用API“不可用”来扩展不会导致拒绝。我多年来一直使用UIApplication.openURL从我的扩展中打开容器应用程序,它们不仅始终按预期工作,而且从未引起任何App Store审核拒绝。 - Jonny
非常好的答案!整个早上都在尝试弄清楚为什么在使用@testable import MyApp时无法在我的测试中使用EventKitUI。将开关切换到“否”就解决了问题。 - Taz
10
从 XCode 12.5 开始,它将强制你将 Require Only App-Extension-Safe API 设置为 YES,以确保应用程序仅使用安全的 API。 - Frank
这是一种风险较高的方法,因为它没有检查非安全 API 的使用情况,因此可能会被应用商店拒绝。你可以通过将“Require Only App-Extension-Safe API”设置为“YES”来移除警告并保持 Xcode 检查,该设置针对框架目标进行。 - Robin Stewart
在我的情况下,当我将“是”设置为“否”后,我收到了一个严重的警告。当我将其重新设置为“是”以便无论如何构建项目时,这个简单的警告就消失了。我不知道为什么。 - Hajime

44

我认为你可以使用嵌入式框架来在应用扩展和其所包含的应用程序之间共享代码。但是,你必须小心,确保你的框架不包含对扩展不可用的API。请参见一些API对应用程序扩展不可用使用嵌入式框架共享代码

如果你的框架不包含这样的api,请不要忘记在你的框架目标的构建设置(Build Settings)中将Require Only App-Extension-Safe API设置为YES

输入图像描述

作为共享应用和扩展源文件的第二种方式,你不必创建一个单独的框架目标。你可以通过同时针对两个项目来共享源文件。

输入图像描述


1
这实际上比为Widget目标设置NO更有意义。将框架限制为扩展友好型是正确的做法。 - Eneko Alonso

11

我的框架没有使用任何受限制的API,但我仍然收到了警告......这个方法解决了我的问题。 在此输入图像描述


2
这是正确的答案。 - xcodefriend
这需要在任何使用应用程序扩展的动态库上启用,以确保您仅使用应用程序扩展安全的API。当我向tvOS顶部架构应用程序扩展添加框架时,遇到了这个警告。从XCode 14.2开始,此设置位于“目标>构建设置”下。 - CudB

8

简短回答:实际上没有办法。

我的解决方法是重构代码,将扩展和动态框架共同的部分分离出来,以便扩展能够安全地引用这些部分而独立于特定手机代码。

我这样做是因为在未来的某个时候,我需要将其提交到App Store,而苹果公司的指南似乎非常明确,使用UIApplication是一个相当大的不允许。


4
你把公共代码放在哪里了?我们将其放在框架中,并在应用程序和扩展中引用它。但这会引发警告... - blackjacx

3
有时候,“保姆”并不是最好的选择。
您可以避免链接到UIApplication.shared,而只需在您的框架中动态调用方法。
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
    }
}

这使得你可以有效地调用UIApplication.shared(只需调用Application.Shared),而无需使链接器混乱。
如果你试图从扩展中调用它,你将会崩溃。

0

将以下内容添加到您的Podfile中,将'ExtensionName'替换为您的扩展目标名称

 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

0

我尝试使用这个use_frameworks! :linkage => :static,但请确保您的项目能够成功构建并且单元测试能够成功运行。


-1

所有上述解决方案在我的情况下都不起作用。我正在使用一个框架,当将其添加到任何项目中时,需要每次都将相关项目中的“仅需要应用程序扩展安全API”设置为“否”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接