当前位置: 首页 > 面试题库 >

使用框架在应用程序扩展中使用Cocoapods

芮瑾瑜
2023-03-14
问题内容

我有一个用Swift编写的应用程序(简称MyApp),其目标如下:

  • MyApp :主要目标
  • MyAppKit :一个目标,用于为应用及其扩展程序(主要是API后端和数据库处理)之间共享的代码构建框架
  • MyAppWidget:使用MyAppKit框架的Today View小部件(或现在称为的小部件)。

MyAppKit框架链接到使用它的每个目标,即MyAppMyAppWidget。输入Cocoapods:我以前具有以下Podfile结构:

platform :ios, '8.0'
use_frameworks!

target 'MyApp' do
    # Mostly UI or convenience pods
    pod 'Eureka', '~> 2.0.0-beta'
    pod 'PKHUD', '~> 4.0'
    pod '1PasswordExtension', '~> 1.8'
end

target 'MyAppKit' do
    # Backend pods for networking, storage, etc.
    pod 'Alamofire', '~> 4.0'
    pod 'Fuzi', '~> 1.0'
    pod 'KeychainAccess', '~> 3.0'
    pod 'RealmSwift', '~> 2.0'
    pod 'Result', '~> 3.0'
end

target 'MyAppWidget' do
    # Added here event though the target only imports MyAppKit but it worked
    pod 'RealmSwift', '~> 2.0'
end

这里的目的是仅将MyAppKit框架公开给其他部分,而不是将其所有pod 公开(例如,我不希望能够import Alamofire进入主应用程序)。但是,从Cocoapods 1.2.0 RC开始,pod install出现以下错误:[!] The 'Pods-MyApp' target has frameworks with conflicting names: realm and realmswift.。它之所以能够正常工作,是因为Pod是为扩展声明的,但仅嵌入在主机应用程序中(有关更多信息,请参见此问题)。因此,我从小部件的目标中删除了广告连播,只留下了一个空白target 'MyAppWidget'行。

使用此配置,pod install可以正常运行,但在MyAppWidget目标的链接阶段编译失败ld: framework not found Realm for architecture x86_64。可以通过在“链接二进制文件和库”部分中显式添加Realm.framework并将RealmSwift.framework其添加到目标的以下构建设置中来解决此问题Pods- MyAppWidget.[debug/release].xcconfig

FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Realm" "$PODS_CONFIGURATION_BUILD_DIR/RealmSwift"`

但是,无论何时运行pod install,构建设置都会自然还原,并且我必须再次添加构建设置。

我看到以下解决方案:

  • post_install每次添加一个添加这些设置的钩子,但看起来确实很“ hacky”,经过几次误导的尝试后,我没有找到API参考,也不知道如何MyAppWidget通过脚本将这些设置添加到目标中。
  • 将Podfile更改为以下结构(甚至将其包装在抽象目标中):
        [...]
    target 'MyAppKit' do
        # Backend pods for networking, storage, etc.
        pod 'Alamofire', '~> 4.0'
        pod 'Fuzi', '~> 1.0'
        pod 'KeychainAccess', '~> 3.0'
        pod 'RealmSwift', '~> 2.0'
        pod 'Result', '~> 3.0'

        target 'MyAppWidget' do
            inherit! :search_paths # Because else we get the "conflicting names" error
        end
    end

从“窗口小部件应该知道链接期间要看的位置,但本身不需要吊舱”的意义上看,这对我来说很合逻辑,
但这并没有添加上述构建设置(我可能会误解 :search_paths继承) (编辑:实际上有效,但不适用于抽象目标)。我想到这个主意是因为在较旧版本的CocoaPods中,解决方案显然要添加link_with,现在已弃用。

  • MyApp目标中也公开Realm ,但是这与我无法访问主代码中的“后端”代码(这可能纯粹是出于审美目的)相冲突。

所以,这是我的问题:将Pod集成到主应用程序和扩展之间共享的框架中,同时仍然能够进行编译而又不进行调整和手动添加内容的最佳方法是什么?

预先加油,谢谢!

在[Prientus发表评论之后,]我探索了抽象和继承的可能性。我现在发现的潜在问题实际上是多种多样的:

  • 它曾经在Cocoapods 1.2.0之前工作,因为在小部件目标下声明的Pod嵌入在主机应用程序内部,但仍链接到小部件。不,它只是拒绝在“主vs扩展”关系中为不同目标使用同名豆荚
  • 使用抽象目标是不够的,因为目标不能仅继承inherit! :search_paths抽象目标的搜索路径()。
  • 搜索路径可以从像这样的真实目标继承而来MyAppKit,但这会将所有这些pod暴露给MyApp的代码(我想避免),并且仍然存在链接Realm框架的问题(因为实际上该小部件使用的是最细微的吸气剂,因此需要它)。

使用最后一个选项并手动链接Realm.framework可以工作,但就我的意图和过去的工作而言不是最佳选择。根据Cocoapods的GitHub上的各种
问题
,其中一些问题似乎是一个错误。我已经添加了自己的问题,并且在有新闻时会更新。


问题答案:

因此,产生了什么:

  • 我对“在目标之间分隔吊舱”的担心是荒谬的,因为您仍然可以将它们导入任何地方。
  • 一个简单的import RealmSwift语句解决了“您必须手动链接”的问题。

因此,固定的工作Podfile是:

platform :ios, '8.0'
use_frameworks!

target 'MyApp' do
    pod 'Eureka', '~> 2.0.0-beta'
    pod 'PKHUD', '~> 4.0'
    pod '1PasswordExtension', '~> 1.8'
end

target 'MyAppKit' do
    pod 'Fuzi', '~> 1.0'
    pod 'RealmSwift', '~> 2.0'
    pod 'Alamofire', '~> 4.0'
    pod 'KeychainAccess', '~> 3.0'
    pod 'Result', '~> 3.0'

    target 'MyAppWidget' do
        inherit! :search_paths
    end
end

就是这样。我会说旧的行为更加明显,不需要阅读“ podfile目标继承”。我确实学到了很多东西。干杯!



 类似资料:
  • 问题内容: 我正在尝试在扩展弹出窗口中使用Google开发人员AngularJS库,但出现错误。 错误:在k(chrome-extension:// jambnlbfljcfpomlclcgphfmkjfiphkb / lib / lib)的功能(未知源)处,Jb(chrome- extension://jambnlbfljcfpomlclcgphfmkjfiphkb/lib/angular.js

  • 问题内容: 后来的AngularJS(1.3 beta 19)使用。铬萃取中禁止这样做。 如何在 不允许评估的情况下 解决问题? 错误信息: 拒绝将字符串评估为JavaScript,因为在以下内容安全策略指令:“ script-src’self’chrome-extension- resource:”中不允许使用’unsafe-eval’作为脚本源。 堆栈跟踪: 更新:请参阅https://doc

  • 我一直在探索构建我的ColdFusion应用程序的不同方法,我正在寻找一些关于提供应用范围UDF的最佳方式的意见。 对于我的每一个应用程序,我通常都会使用一些不属于任何特定对象的额外功能。主要是数据操作。我希望这些功能在我的整个应用程序中都可用,既可以在CFM模板中使用,也可以在应用程序实例化的CFC中使用。 在我看来,有各种各样的方法来实现这一点,但它们都有自己的局限性: > 创建一个基本的Ut

  • 如何使用appium/python/robot框架在android原生应用程序中滚动到页面底部?我尝试了以下方法,但无法使用driver.execute_脚本(“window.scrollTo(1441532)”)和driver.execute_脚本('mobile:scroll',{'duration':1,'startX':48,'startY':892,'endX':144,'endY':1

  • 问题内容: 我正在使用一个Spark数据框,该数据框可能正在从三个不同架构版本之一加载数据: 我可以通过检查架构是否包含字段“ C”以及是否不向数据框添加新列来处理其他“ C”。但是我不知道如何为子对象创建一个字段。 问题答案: JSON源不是非常适合具有不断发展的模式的数据(而不是Avro或Parquet),但是简单的解决方案是对所有源使用相同的模式,并使新字段为可选/可为空: 您可以像这样传递

  • 2.5.应用程序框架 应用程序框架是Android程序的执行环境,也是开发者的强大工具箱。另外,它也拥有Android平台中最全面最完善的文档。良好的文档可以激发广大开发人员的创意,也可以为他们构建优秀的应用程序提供有力的支持。 在应用程序框架中,你可以发现很多为Android设计的Java库。除此之外,也有系统服务的支持,比位置、传感器、WiFi、电话等等。 在后面的学习与实践中,将把我们的主要