【问题标题】:The 'Pods-App' target has transitive dependencies that include static binaries when using GTM in a swift framework在 swift 框架中使用 GTM 时,“Pods-App”目标具有传递依赖关系,包括静态二进制文件
【发布时间】:2017-02-13 17:39:59
【问题描述】:

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

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

或者,使用 GTM v5:

错误 | [iOS] 未知:遇到未知错误(“Pods-App” 目标具有传递依赖关系,包括静态二进制文件: (/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 的说明。非常感谢!

【问题讨论】:

  • 其实这不是同一种问题,我的问题是在一个框架中使用GTM,之后会变成一个pod。不只是在 Swift 项目中使用 GTM,我已经知道该怎么做 ;)

标签: ios cocoapods swift3 google-tag-manager


【解决方案1】:

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

我最终决定忽略 Cocoapods 并手动将第三方框架添加到我的框架中。所以这个答案不会完全符合我的问题,但这是我发现分布我的框架的唯一方法。

所以,第一步是创建一个新项目。选择 Cocoa Touch 框架

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

单击跨平台选项卡并选择聚合模板。我会命名我的Aggregate(非常有创意)。但我们暂时不会太在意它。

完成此操作后,您的工作场所就可以为您创建令人惊叹的框架了!让我们再深入一点!

您现在要创建或复制源文件。如果您复制它们,请不要忘记选中 Copy items if needed 框并确保将它们添加到框架目标中:

到目前为止,我想这没什么大不了的。

因为我的问题是关于 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

在您的框架项目中,添加一个您将命名为 Frameworks 的新组(在 Xcode 导航器中右键单击 -> 新组)。您将复制 myFramework 的 Frameworks 组下的 PodApp 项目中下载的所有依赖项 Cocoapods。再一次,不要忘记将其添加到 myFramework 目标根据需要复制项目,如上所示。

在下图中,点击123,如果一切顺利,你应该会看到你的frameworks/libs刚刚添加到 4

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

我在使用 GoogleToolBoxForMac 时也遇到了一些问题,我要做的是构建 PodApp 项目,并将 GoogleToolBoxForMac.framework 复制到 PodApp/Pods/Products 下/ 在组 myFramework/Frameworks/ 中。 记得将其添加到正确的目标并复制项目

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

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

由于其他资源可能会给您警告(在此特定示例中),您可以使用 - 删除它们。

如果您希望您的框架的最终用户能够使用您嵌入的框架,请在“复制捆绑资源”正上方,打开“标题”面板,拖放所有项目 em> 标头到 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>

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

现在,选择您项目的信息部分(上图中的 1),检查您正在构建的版本(我的是 8.0 以向后兼容大多数设备)。在 Configurations 面板下,通过选择 Debug 并按 - 将其移除。 现在选择 Build Settings(图像上的 2),我们将在此处进行一些更改。

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

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

在框架目标中,我还将 Other Linker Flags 设置为在 PodApp 项目中设置的内容,但我不是 100% 确定有必要。

(仅供参考,这里是:$(inherited) -ObjC -l"GoogleAnalytics" -l"c++" -l"sqlite3" -l"z" -framework "AdSupport" -framework "CoreTelephony" -框架“FirebaseAnalytics”-框架“FirebaseCore”-框架“FirebaseInstanceID”-框架“GoogleSymbolUtilities”-框架“GoogleTagManager”-框架“GoogleToolboxForMac”-框架“GoogleUtilities”-框架“JavaScriptCore”-框架“SystemConfiguration”-框架“StoreKit”-框架“AddressBook”-框架“CoreData”

Define Modules设置为yes

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

在构建阶段,您希望您的 Aggregate 目标在构建自己之前构建 myFramework.framework。

添加完myFramework.framework后,按下图中标注为2+,选择New Run Script Phase。 将以下脚本粘贴到其中:

# 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 步中,将名称更改为您的框架名称。 花点时间了解它的作用,并在它不符合您的要求时更改其行为。它最终的作用是在您的项目文件夹中创建一个框架和一个 zip 存档。我这样做是为了将它与每个 Github 版本链接起来。

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

如果您想在测试应用程序中添加您的框架,请创建一个新的应用程序项目,只需拖放您的 myFramework.framework例如从您的 myFramework 文件夹中 ) 到您的应用程序项目。再一次,不要忘记将它添加到正确的目标,并复制项目。在您的应用程序目标中,在 General 选项卡下,将您的框架添加到 Embedded Binaries 面板中,但将其从 Linked Frameworks and Libraries 中删除一次面板,因为它应该在那里两次(在做之前检查一下)。导入你的框架

import myFramework

并开始使用你构建的东西!

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

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

请在下面找到我的来源:

【讨论】:

  • 我完成了所有这些步骤,但是,我的 lib 似乎缺少它的依赖项二进制文件,我无法使用它。构建有 8MB,即使我添加的框架本身也有 20 个。知道我可能做错了什么吗?
  • @KioCoan 抱歉回答迟了。实际上我几乎不记得这一点,而且我不再使用 iOS 了。你能弄清楚吗?也许您没有以正确的方式复制依赖项?喜欢复制它的引用而不是实际的框架?让我知道你的情况如何。
猜你喜欢
  • 2021-06-12
  • 2020-09-27
  • 2019-10-13
  • 2018-10-22
  • 2020-10-13
  • 2017-01-01
  • 2017-07-25
  • 1970-01-01
  • 2020-11-13
相关资源
最近更新 更多