'Pods-App'目标具有传递依赖关系,在swift框架中使用GTM时包含静态二进制文件

时间:2016-10-05 10:12:37

标签: ios cocoapods swift3 google-tag-manager

我正在尝试重做swift 3项目的一部分,使其成为一个快速的框架,以便将其用作pod。问题是我需要使用GoogleTagManager legacy(v3)作为依赖项,并且在执行pod spec lint时出现以下错误:

  

错误| [iOS]未知:遇到未知错误('Pods-App'   target具有包含静态二进制文件的传递依赖项:   (/private/var/folders/7t/0cd0n1gn46xd7r1cywrgcy2w0000gn/T/CocoaPods/Lint/Pods/GoogleTagManager/Libraries/libTagManager.a))   在验证期间。

或者,使用GTM v5:

  

错误| [iOS]未知:遇到未知错误('Pods-App'   target具有包含静态二进制文件的传递依赖项:   (/private/var/folders/7t/0cd0n1gn46xd7r1cywrgcy2w0000gn/T/CocoaPods/Lint/Pods/GoogleTagManager/Frameworks/GoogleTagManager.framework))   在验证期间。

我正在使用最新的cocoapods版本(1.1.0.rc.2),根据我的理解,问题来自GTM pod的依赖关系,其中至少有一个是静态库。

我读了一些线程,人们谈论在框架中安装静态库的工作区,或者在创建pod时将静态库包装到框架中。问题是静态库是GTM pod的依赖,所以我无法控制它。至少这是我在here中理解的内容。

这是我的Podfile:

# Uncomment this line to define a global platform for your project
platform :ios, '8.0'

target 'MyProject' do
  # Comment this line if you're not using Swift and don't want to use dynamic frameworks
  # use_frameworks!

  # Pods for MyProject
    pod 'GoogleTagManager', '~> 3.15.2'
end

这是我的(缩短为StackOverflow)MyProject.podspec:

Pod::Spec.new do |s|

  s.name         = "MyProject"
  s.version      = "0.1.0"

  s.platform = :ios, '8.0'
  s.ios.deployment_target = '8.0'

  s.source_files  = "MyProject", "MyProject/**/*.{h,m}", "MyProject/**/*.{swift}"
  s.dependency 'GoogleTagManager', '~> 5.0.0'

end

我已经尝试下载GTM SDK并在没有cocoapods的情况下安装它,但我想我错过了一步,因为我无法使其工作。

所以我想对podspec和podfile文件提出一些建议,或者解释如何在没有cocoapods的情况下安装SDK。非常感谢!

1 个答案:

答案 0 :(得分:2)

好吧,几个月后我不得不回到这个项目。由于GTM pod没有改变,并且仍然有静态库作为依赖项,因此仍然无法创建一个将GTM pod作为依赖项并通过Cocoapods分发它的框架。

我最终决定忽略Cocoapods并手动添加第三方框架。所以这个答案不能完全匹配我的问题,但这是我找到的唯一方法来分辨我的框架。

因此,第一步是创建一个新项目。选择 Cocoa Touch Framework

Select Cocoa Touch Framework

给它起个名字,我的 myFramework 。工作场所准备就绪后,为其添加新目标:

how to add a new target

单击跨平台选项卡,然后选择聚合模板。我将我的名字命名为 Aggregate (这么多原创性)。但是我们现在不太关心它。

Aggregate target

完成后,您的工作场所将为您创建出色的框架!让我们再深入一点!

您现在要创建或复制源文件。如果您复制它们,请不要忘记选中复制项目(如果需要)框,并确保它们已添加到框架目标中:

verify the options when copying your files

到现在为止,我猜没有什么大惊喜。

由于我的问题是关于GTM,我们将作为框架的依赖添加到框架中。我无法在Cocoapods的其他地方找到源代码,所以我创建了一个新项目(我使用了应用程序模板并命名为 PodApp ),然后我添加了Cocoapods。打开终端并导航到 PodApp 项目文件夹:

  1. pod init
  2. vi Podfile
  3. #Pods for PodApp 下,添加pod 'GoogleTagManager', '~> 6.0.0'
  4. 保存并关闭Podfile,然后运行pod install
  5. 下载并安装依赖项后,关闭PodApp项目窗口并运行open PodApp.xcworkspace
  6. 在您的Framework项目中,添加一个新的组,您将命名 Frameworks (右键单击Xco​​de Navigator - > new Group)。您将复制 myFramework 的Frameworks组下 PodApp 项目中下载的Cocoapods所有依赖项。再一次,不要忘记将其添加到myFramework目标复制项目(如果需要),如上所示。

    Drag and drop frameworks in your project

    在下图中,点击 1 2 3 ,如果一切顺利,您应该看到框架/库刚刚添加 4

    xcode project

    要使Firebase正常运行,您还必须与AdSupport.framework进行关联。只需点击+( 5 ),搜索它,然后添加即可。

    我在使用GoogleToolBoxForMac时遇到了一些麻烦,我必须做的是构建 PodApp 项目,并在 PodApp / Pods / Products下复制GoogleToolBoxForMac.framework /在 myFramework / Frameworks /组中。 请务必将其添加到正确的目标并复制该项

    与GTM相关的另一个棘手的细节:您必须为框架添加一些资源。按照下一张图片中的步骤操作:

    enter image description here

    在打开的弹出窗口中,单击添加其他并找到保存GTM.framework的位置,展开它并添加TagManagerResources.bundle(不要忘记复制该项目! )。

    TagManagerResources.bundle

    由于其他资源可能会向您发出警告(在此具体示例中),您可以使用 - 删除它们。

    如果您希望框架的最终用户能够使用您嵌入的框架,请在" Copy Bundle Resources"上方,打开" Headers"面板,将所有项目标题拖放到 public

    所有这些框架现在都可以通过您自己的框架访问,但为了使它们可用,您必须在myFramework.h中导入它们的标题:

    #import <myFramework/AnObjectiveCClass.h>
    
    #import <GoogleTagManager/GoogleTagManager.h>
    #import <GoogleTagManager/TAGCustomFunction.h>
    
    #import <myFramework/GTMDefines.h>
    #import <myFramework/GTMNSData+zlib.h>
    
    #import <FirebaseCore/FirebaseCore.h>
    #import <FirebaseAnalytics/FirebaseAnalytics.h>
    #import <FirebaseInstanceID/FirebaseInstanceID.h>
    
    #import <myFramework/GAI.h>
    #import <myFramework/GAIDictionaryBuilder.h>
    #import <myFramework/GAIEcommerceFields.h>
    #import <myFramework/GAIEcommerceProduct.h>
    #import <myFramework/GAIEcommerceProductAction.h>
    #import <myFramework/GAIEcommercePromotion.h>
    #import <myFramework/GAIFields.h>
    #import <myFramework/GAILogger.h>
    #import <myFramework/GAITrackedViewController.h>
    #import <myFramework/GAITracker.h>
    
    #import <myFramework/pb_encode.h>
    #import <myFramework/pb.h>
    #import <myFramework/pb_decode.h>
    #import <myFramework/pb_common.h>
    

    好吧,我们差不多完成了!

    Project Info / Build Settings

    现在,选择项目的“信息”部分(上图中 1 ),检查您要构建的版本(我的版本为8.0,以便与大多数设备向后兼容)。在配置面板下,选择调试,然后按 - 。 现在选择构建设置(图像上的 2 ),我们将在此处进行一些更改。

    • 仅构建活动架构:否
    • 允许在框架模块中使用非模块化包含:否
    • 有效体系结构:arm64 armv7 i386 x86_64 (因为armv7s在本例中没有为某些框架构建)
    • 预处理器宏:PB_NO_PACKED_STRUCTS = 1 PB_FIELD_32BIT = 1
    • 启用模块(C和Objective-C):是

    在你的两个目标中,对于上面提到的Build Settings,将它们设置为 $(inherited),这意味着它们将继承你刚刚在Project Build Settings上设置的参数。

    在框架目标中,我还将其他链接器标志设置为PodApp项目中设置的内容,但我并非100%确定它是必要的。

    (仅供参考,这里他们是: $(继承)-ObjC -l&#34; GoogleAnalytics&#34; -l&#34; c ++&#34; -l&#34; sqlite3&#34; - l&#34; z&#34; -framework&#34; AdSupport&#34; -framework&#34; CoreTelephony&#34; -framework&#34; FirebaseAnalytics&#34; -framework&#34; FirebaseCore&#34; -framework &#34; FirebaseInstanceID&#34; -framework&#34; GoogleSymbolUtilities&#34; -framework&#34; GoogleTagManager&#34; -framework&#34; GoogleToolboxForMac&#34; -framework&#34; GoogleUtilities&#34; -framework &#34; JavaScriptCore&#34; -framework&#34; SystemConfiguration&#34; -framework&#34; StoreKit&#34; -framework&#34; AddressBook&#34; -framework&#34; CoreData&#34;

    定义模块设置为

    现在选择Aggregate目标,它将创建一个胖框架,一个包含我们框架的几个版本的文件,一个用于我们几步之前指定的每个架构( arm64 armv7 i386 x86_64 )。我们必须告诉Xcode我们想要它构建什么。请按照下图中的步骤( 1 ):

    image description

    在Build Phases中,您希望Aggregate目标在构建之前构建myFramework.framework。

    添加myFramework.framework后,按下图片中 + 注释为 2 ,然后选择新建运行脚本阶段。 将以下脚本粘贴到其中:

    # Merge Script
    
    # 1
    # Set bash script to exit immediately if any commands fail.
    set -e
    
    # 2
    # Setup some constants for use later on.
    FRAMEWORK_NAME="myFramework"
    
    # 3
    # If remnants from a previous build exist, delete them.
    if [ -d "${SRCROOT}/build" ]; then
    rm -rf "${SRCROOT}/build"
    fi
    
    # 4
    # Build the framework for device and for simulator (using
    # all needed architectures).
    xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch arm64 -arch armv7 -arch armv7s only_active_arch=no defines_module=yes -sdk "iphoneos"
    xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch x86_64 -arch i386 only_active_arch=no defines_module=yes -sdk "iphonesimulator"
    
    # 5
    # Remove .framework file if exists from previous run.
    if [ -d "${PROJECT_DIR}/${FRAMEWORK_NAME}.framework" ]; then
    rm -rf "${PROJECT_DIR}/${FRAMEWORK_NAME}.framework"
    fi
    
    # 6
    # Copy the device version of framework to Framework directory.
    cp -r "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework" "${PROJECT_DIR}/${FRAMEWORK_NAME}.framework"
    
    # 7
    # Replace the framework executable within the framework with
    # a new version created by merging the device and simulator
    # frameworks' executables with lipo.
    lipo -create -output "${PROJECT_DIR}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"
    
    # 8
    # Copy the Swift module mappings for the simulator into the
    # framework.  The device mappings already exist from step 6.
    cp -r "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" "${PROJECT_DIR}/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule"
    
    # 9
    # Delete the most recent build.
    if [ -d "${SRCROOT}/build" ]; then
    rm -rf "${SRCROOT}/build"
    fi
    
    # 10
    # Remove .zip file if exists from previous run.
    if [ -d "${PROJECT_DIR}/${FRAMEWORK_NAME}.zip" ]; then
    rm -rf "${PROJECT_DIR}/${FRAMEWORK_NAME}.zip"
    fi
    
    # 11
    # Zip the Framework and License all together.
    zip -r "${PROJECT_DIR}/${FRAMEWORK_NAME}.zip" "${PROJECT_DIR}/LICENSE" "${PROJECT_DIR}/${FRAMEWORK_NAME}.framework"
    

    在脚本的第2步中,使用您的框架名称更改名称。花些时间了解它的作用,如果不是,则更改其行为。&#39;满足您的要求。它最终做的是它在项目的文件夹中创建一个框架和一个zip存档。我这样做是为了将它与每个Github版本链接起来。

    现在一切都应该运转正常。选择Aggregate作为活动Scheme,然后运行它。

    Run Aggregate Scheme

    如果您想在测试应用程序中添加框架,请创建一个新的应用程序项目,只需拖放 myFramework.framework (例如来自myFramework文件夹 )到您的应用程序项目。再次,不要忘记将其添加到正确的目标,并复制项目。在您的应用程序目标中,在常规标签下,在嵌入式二进制文件面板中添加您的框架,但从链接的框架和库中删除一次面板,因为它应该在那里两次(在做之前检查)。导入您的框架

    import myFramework
    

    并开始使用您构建的内容!

    NB:如果您尝试使用GTM,请不要忘记添加与GTM集成相关的内容(您的容器和GoogleInfo plist):

    GTM related stuff

    我真的希望这会对你有所帮助!如果有任何事情不清楚或者您遇到问题,请随时评论,我会尽力帮助您。

    请在下面找到我的来源: