使用框架在app扩展中使用Cocoapods [英] Using Cocoapods in an app extension using a framework

查看:200
本文介绍了使用框架在app扩展中使用Cocoapods的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用Swift编写的应用程序(我们称之为MyApp),其中包含以下目标:

I have an app (let's call it MyApp) written in Swift with the following targets :


  • MyApp :主要目标

  • MyAppKit :构建应用程序之间共享代码的框架的目标及其扩展,主要是API后端和数据库处理

  • MyAppWidget :一个今日视图小部件(或者现在叫做的任何东西) )它使用 MyAppKit 框架。

  • MyApp : the main target
  • MyAppKit : a target building a framework for code that is shared between the app and its extension(s), mainly the API backend and database handling
  • MyAppWidget : a Today View Widget (or whatever it's called now) which uses the MyAppKit framework.

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

The MyAppKit framework is linked into each target that uses it, namely MyApp and MyAppWidget. Enter Cocoapods : I used to have the following Podfile structure :

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(例如我不希望能够在主应用程序中导入Alamofire )。但是,从Cocoapods 1.2.0 RC开始, pod install 失败,出现以下错误: [!]'Pods-MyApp'目标有框架名称相互冲突:领域和realmswift。。它曾经工作,因为pods是为扩展名声明的,但只嵌入在主机应用程序中(请参阅此问题) 了解更多信息)。所以我从小部件的目标中删除了pod,只剩下一个空白的目标'MyAppWidget'行。

The aim here was to expose only the MyAppKit framework to the other parts and not all its pods (e.g. I don't want to be able to import Alamofire inside the main app). However, starting with the Cocoapods 1.2.0 RCs, pod install failed with the following error : [!] The 'Pods-MyApp' target has frameworks with conflicting names: realm and realmswift.. It used to work because the pods were declared for the extension but only embedded in the host app (see this issue for more info). So I removed the pods from the widget's target, leaving me with just a blank target 'MyAppWidget' line.

使用此配置, pod install 运行正常,但编译在 MyAppWidget 目标的链接阶段失败: ld:找不到框架体系结构x86_64 。这可以通过将 Realm.framework RealmSwift.framework 显式添加到Link Binary With Libraries部分来解决以及目标的 Pods-MyAppWidget中的以下构建设置。[debug / release] .xcconfig

With this configuration, pod install runs fine but compiling fails at the linking stage for the MyAppWidget target : ld: framework not found Realm for architecture x86_64. This can be fixed by explicitly adding both Realm.framework and RealmSwift.framework to the "Link Binary With Libraries" section and the following build setting in the target's Pods-MyAppWidget.[debug/release].xcconfig :

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

然而,每当我运行 pod install 时,构建设置自然会被恢复,我必须再次添加构建设置。

However, whenever I run pod install, the build settings are naturally reverted and I have to add the build settings again.

我看到以下解决方案:


  • 添加 post_install hook每次都添加这些设置,但看起来确实hacky,经过几次误导尝试后,我发现没有API参考,也不知道如何将这些设置添加到 MyAppWidget 通过脚本定位。

  • 将Podfile更改为以下结构(甚至将其包装在一个抽象的目标):

  • Add a post_install hook adding these settings each time but it does seem "hacky" and after a few misguided tries, I have found no API reference and don't know how to add these settings to the MyAppWidget target through script.
  • Change the Podfile to the following structure (or even wrapping it in an abstract target) :

[...]
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

对于我而言,小部件应该知道在链接期间要查看的位置,但不需要pod本身,这似乎是合乎逻辑的,但这并没有添加上述构建设置(我可能会误解:search_paths 继承)(编辑:它实际上有效,但没有抽象目标)。这个想法来找我,因为在旧版本的CocoaPods中,解决方案显然是添加 link_with ,现已弃用。

Which seems logical to me in the sense of "the widget should know where to look during linking but doesn't need the pods per se" but this doesn't add the aforementioned build settings (I probably misunderstand the :search_paths inheritance) (edit: it actually works, but not with an abstract target). This idea came to me because in older versions of CocoaPods, the solution was apparently to add link_with, which is now deprecated.

所以,这是我的问题:在主要应用程序和扩展程序之间共享的框架中集成pod的最佳方法是什么,同时仍然能够编译,而无需调整并手动添加内容?

So, here's my question : what's the best way to integrate pods in a framework shared between the main app and the extension while still being able to compile, without tweaking around and manually adding stuff?

提前干杯谢谢!

关注 Prientus的评论我已经探索了抽象的可能性n和继承。我现在发现的潜在问题实际上是多方面的:

Following Prientus' comment I've explored the possibilities of abstraction and inheritance. The underlying issues I've now uncovered are actually manifold :


  • 它曾经在Cocoapods 1.2.0之前工作,因为在小部件的目标下声明了pod嵌入在主机应用程序中但仍链接到窗口小部件。不,它只是拒绝在主要与扩展关系中为不同目标设置相同名称的pod

  • 使用抽象目标是不够的,因为目标不能只继承搜索路径(从抽象目标继承!:search_paths )。

  • 搜索路径可以从真实目标继承,如 MyAppKit ,但是这会将所有这些pod暴露给 MyApp 的代码(我想避免),并且仍然存在链接领域的问题框架(因为实际上小部件使用最小的一个getter,因此需要它)。

  • It used to work before Cocoapods 1.2.0 because pods declared under the widget's target were embedded inside the host app yet still linked to the widget. No it simply refuses to have pods with the same name for different targets in a "main vs extension" relationship
  • Using abstract targets is insufficient because targets can't inherit only the search paths (inherit! :search_paths) from an abstract target.
  • Search paths can be inherited from a real target like MyAppKit, but this exposes all these pods to MyApp's code (which I want to avoid), and there still is the issue of linking the Realm framework (because actually the widget uses the tiniest bit of a getter and therefore needs it).

使用最后一个选项并手动链接Realm .framework有效,但对于我的意图和过去的工作而言并不是最理想的。根据各种 问题 Cocoapods的GitHub。我已经添加了我自己的问题,并会在有新闻时更新。

Using this last option and manually linking Realm.framework works but is suboptimal regarding my intents and what used to work. Some of these issues seem to be a bug according to various issues on Cocoapods' GitHub. I've added my own issue and will update when I have news.

推荐答案

所以,给出了什么:


  • 我的关注在目标之间分离pod是荒谬的,因为你仍然可以将它们导入任何地方。

  • 你必须手动链接问题由一个简单的导入RealmSwift修复声明。

  • My concern of "separating pods between targets" is absurd because you can still import them anywhere.
  • The "you have to manually link" issue is fixed by an easy import RealmSwift statement.

固定和工作的Podfile因此是:

The fixed and working Podfile therefore is :

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目标继承。我确实学到了很多东西。干杯!

And that's it. I would say that the old behaviour was more obvious and didn't require reading up on "podfile target inheritance". I did learn a lot though. Cheers!

这篇关于使用框架在app扩展中使用Cocoapods的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆