2017-02-08 26 views
7

我有一个应用程序在一个应用程序扩展使用的CocoaPods(姑且称之为MyApp的)写在斯威夫特与以下目标:使用框架

  • MyApp:主要目标
  • MyAppKit:目标建设在应用程序及其扩展之间共享的代码框架,主要是API后端和数据库处理
  • MyAppWidget:使用MyAppKit框架的今日视图小部件(或任何现在称之为)的框架。

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框架暴露在其他地方,而不是它的所有吊舱(例如,我不希望能够import Alamofire在主应用程序内)。但是,从Cocoapods 1.2.0 RC开始,pod install失败,出现以下错误:[!] The 'Pods-MyApp' target has frameworks with conflicting names: realm and realmswift.。它曾经工作,因为这个豆荚是为扩展而声明的,但只嵌入在主机应用程序中(更多信息参见this issue)。所以我从小部件的目标中移除了豆荚,留下了一个空白的target 'MyAppWidget'行。

使用此配置,pod install可以正常运行,但在MyAppWidget目标的链接阶段编译失败:ld: framework not found Realm for architecture x86_64

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

但是,每当我跑pod install,构建设置自然恢复:这可以通过显式的增加都Realm.frameworkRealmSwift.framework的“链接二进制与图书馆”一节,并在目标的Pods-MyAppWidget.[debug/release].xcconfig下面的生成设置固定我必须再次添加构建设置。

我看到了以下解决方案:

  • 添加post_install钩每次添加这些设置,但它似乎“哈克”和一些误导尝试后,我没有发现任何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中,solution显然是增加link_with,现在已经弃用了。

  • 也在MyApp目标中暴露Realm,但是这与我在主代码中无法访问“后端”代码的目标相冲突(它可能纯粹是美观?)。

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

欢呼声,并提前致谢!


编辑

Prientus' comment我已经探索抽象和继承的可能性。根本问题现在我发现实际上是多方面的:

  • 它曾经因为小部件的目标下宣布豆荚嵌入宿主应用程序,但仍挂部件内的CocoaPods 1.2.0之前的工作。不,它只是拒绝在“主要”和“扩展”关系中为不同目标设置相同的名称
  • 使用抽象目标是不够的,因为目标不能只继承抽象目标的搜索路径(inherit! :search_paths)。
  • 搜索路径可以从像MyAppKit这样的真实目标继承,但是这会将所有这些窗格公开到MyApp的代码(我想要避免),并且仍然存在链接Realm框架的问题(因为实际上该窗口小部件使用最微小的吸气剂,因此需要它)。

使用这最后一个选项并手动链接Realm.framework工程,但对于我的意图和曾经工作的内容而言是不理想的。其中一些问题似乎是根据variousissueson Cocoapods的GitHub的错误。我添加了my own issue,并在有消息时更新。

+0

您提到在解决方案中使用抽象类,但我想知道你是否真的尝试过。你在这里提出了一个很好的问题,我遇到了自己。 – Prientus

+0

另外,我会尝试使用继承!方法,但目标是在父级之外声明的。我注意到这里的语法:https://guides.cocoapods.org/syntax/podfile.html#target,并认为它可能是有用的。 – Prientus

回答

7

那么,是什么赋予了:

  • 我的“分离的目标之间的豆荚”的担忧是荒谬的,因为你仍然可以导入任何地方。
  • “您必须手动链接”问题通过简单的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目标继承”。尽管我确实学到了很多东西。干杯!

+0

我照你说的做了,并使用'继承! :search_paths'只在建立到设备时才起作用。当我尝试归档应用程序时,失败的“没有这样的模块”,我尝试在扩展中使用每个窗格 – YichenBman

+0

@YichenBman我刚刚归档我的应用程序没有任何错误。也许你可以向我展示你的Podfile或在这里打开一个新的问题。一般来说,确保CocoaPods和Xcode是最新的。 –

+0

非常感谢你,你为我节省了几个小时的努力工作,但是,档案不起作用。当我输入它时它不识别模块... – Eduard

1

我不认识你。但对我而言,扩展和主机应用程序包含框架定义的所有窗格是完全合法和合理的。这就是我的意思是:

def shared_pods 
    pod 'Alamofire' 
end 

target 'Framework' do 
    shared_pods 
end 

target 'Host' do 
    shared_pods 
    // Some other pods 
end 

target 'Extension' do 
    shared_pods 
end 

我知道你是担心,但如果你仔细想想,你使用这些第三方的框架,它们都具有相关性。你不必担心它们,因为Cocoapods为你照顾它们。如果你想利用它,那么你需要在列表中放置一个本地pod条目。

target 'Host' do 
    pod Framework, :path => '../Framework' 
end 

但是,那么你必须保持podspec文件。

+0

经过头脑麻木的研究和测试,我已经找到了解决我的问题(下面发布供参考)。它主要涉及意识到,无论你如何配置你的Podfile,所有的豆荚都可以导入到任何地方(我猜是因为链接共享框架),因此我的首要担忧是没有问题的。应该注意的是,你的解决方案不会导致“目标有名称冲突的框架”,因为你最终引用了扩展中的pod。 –

0

这是一个swift-3.0项目的配置文件示例。

platform :ios, '8.0' 

def import_public_pods 

    pod 'SwiftyJSON' 

end 


target 'Demo' do 
    use_frameworks! 

    # Pods for Demo 
    import_public_pods 
    pod 'Fabric' 
    pod 'Crashlytics' 

    target 'DemoTests' do 
    inherit! :search_paths 
    # Pods for testing 
    end 

    target 'DemoUITests' do 
    inherit! :search_paths 
    # Pods for testing 
    end 

end 


target 'DemoKit' do 
    use_frameworks! 

    # Pods for DemoKit 
    import_public_pods 
    pod 'RealmSwift' 

    target 'DemoKitTests' do 
    inherit! :search_paths 
    # Pods for testing 
    end 

end