簡體   English   中英

在快速框架中使用GTM時,“ Pods-App”目標具有傳遞性依賴關系,其中包括靜態二進制文件

[英]The 'Pods-App' target has transitive dependencies that include static binaries when using GTM in a swift framework

我正在嘗試重新處理swift 3項目的一部分,使其成為一個swift 框架 ,以便將其用作pod。 事情是,我需要使用GoogleTagManager舊版(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的依賴項,因此我無法控制它。 至少那是我在這里所了解的。

這是我的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容器沒有變化,並且仍然具有靜態庫作為依賴項,因此仍然不可能創建將GTM容器作為依賴項的框架並通過Cocoapods進行分發。

我最終決定忽略Cocoapods,並手動添加第三方框架。 因此,此答案與我的問題並不完全匹配,但這是我發現分配我的框架的唯一方法。

因此,第一步是創建一個新項目。 選擇可可觸摸框架

選擇可可觸摸框架

給它起個名字 ,我的將是myFramework 准備好工作場所后,向其添加一個新目標:

如何添加新目標

單擊跨平台選項卡,然后選擇“聚合”模板。 我將其命名為Aggregate (非常有創意)。 但是我們暫時不會太在意。

總目標

完成此操作后,便可以為您的工作場所創建令人驚嘆的框架! 讓我們再潛水一點!

您現在將創建或復制您的源文件。 如果您復制它們,請不要忘記選中復制項目框( 如果需要),並確保將它們添加到框架目標中:

在復制文件時驗證選項

到現在為止,我猜還不足為奇。

由於我的問題是關於GTM的,因此我們將其添加為框架的依賴項。 我無法在Cocoapods上的其他地方找到源,因此我創建了一個新項目(我使用了應用程序模板並將其命名為PodApp ),然后向其中添加了Cocoapods。 打開終端並導航到PodApp項目文件夾:

  1. pod init
  2. vi Podfile
  3. PodApp的#Pods下 ,添加pod'GoogleTagManager pod 'GoogleTagManager', '~> 6.0.0'
  4. 保存並關閉Podfile,然后運行pod install
  5. 下載並安裝依賴項后,關閉PodApp項目窗口並運行open PodApp.xcworkspace

在Framework項目中,添加一個新的組,將其命名為Frameworks (在Xcode Navigator-> new Group中右鍵單擊)。 您將復制在PodApp項目中myFramework的Frameworks組下下載的所有Cocoapods依賴 再一次,不要忘記將其添加到myFramework目標,根據需要復制項目

在您的項目中拖放框架

在下面的圖片,點擊1,2,3,如果一切順利,你應該看到的框架/庫您剛才添加4。

xcode項目

為了使Firebase正常工作,您還必須與AdSupport.framework鏈接。 只需單擊+( 5 ),搜索並添加。

我也對GoogleToolBoxForMac遇到了一些麻煩,我要做的是構建PodApp項目,並將GoogleToolBoxForMac.framework復制到myFramework / Frameworks /組中的PodApp / Pods / Products /下。 請記住將其添加到正確的目標並復制該項目

與GTM有關的另一個棘手的細節是:您必須向框架中添加一些資源。 按照下一張圖片上的步驟操作:

在此處輸入圖片說明

在打開的彈出窗口中,單擊“ 添加其他” ,找到GTM.framework的保存位置,將其展開並添加TagManagerResources.bundle(不要忘記復制該項目!)。

TagManagerResources.bundle

由於其他資源可能會給您警告(在此特定示例中),因此您可以使用-將其刪除。

如果希望框架的最終用戶能夠使用您嵌入的框架,請在“復制捆綁資源”上方,打開“標題”面板,將所有項目標題拖放到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)。 在“ 配置”面板下,通過選擇“ 調試”並按-來刪除它。 現在選擇Build Settings(圖像上的2 ),我們將在此處進行一些更改。

  • 僅構建活動架構 :否
  • 允許非模塊化模塊包含在框架模塊中 :否
  • 有效的體系結構 :arm64 armv7 i386 x86_64 (因為在此示例中,armv7s未針對某些框架構建)
  • 預處理器宏 :PB_NO_PACKED_STRUCTS = 1 PB_FIELD_32BIT = 1
  • 啟用模塊(C和Objective-C) :是

在您的兩個目標中,對於上述構建設置,將它們設置為$(inherited) ,這意味着它們將從您剛剛在“項目構建設置”中設置的參數繼承。

在框架目標中,我還將“ 其他鏈接器標志”設置為PodApp項目中設置的標志,但是我不確定100%是否有必要。

(僅供參考,它們是: $(繼承)-ObjC -l“ GoogleAnalytics” -l“ c ++” -l“ sqlite3” -l“ z”-框架“ AdSupport”-框架“ CoreTelephony”-框架“ FirebaseAnalytics”-框架“ FirebaseCore”-框架“ FirebaseInstanceID”-框架“ GoogleSymbolUtilities”-框架“ GoogleTagManager”-框架“ GoogleToolboxForMac”-框架“ GoogleUtilities”-框架“ JavaScriptCore”-框架“ SystemConfiguration”-框架“ StoreKit”-框架“ AddressBook”-框架“ CoreData”

定義模塊設置為yes

現在選擇Aggregate目標,這將創建一個胖框架,一個包含我們框架的多個版本的文件,一個針對我們在幾步前指定的每種架構的一個文件( arm64 armv7 i386 x86_64 )。 我們將不得不告訴Xcode我們想要它構建什么。 請按照下圖( 1 )的步驟操作:

圖片說明

在構建階段中,您希望聚合目標先構建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的每個版本鏈接在一起。

現在一切都應該正常工作。 選擇“聚合”作為活動方案,然后運行它。

運行匯總方案

如果要在測試應用程序中添加框架,請創建一個新的Application項目,只需將myFramework.framework例如,從myFramework文件夾中 )拖放到Application項目中。 再一次,不要忘記將其添加到正確的目標並復制項目。 在“應用程序”目標的“ 常規”選項卡下,在“ 嵌入式二進制文件”面板中添加您的框架,但是從“ 鏈接的框架和庫”面板中刪除一次,因為它應該存在兩次(請在執行操作之前先進行檢查)。 導入您的框架

import myFramework

並開始使用您構建的內容!

注意:如果您嘗試使用GTM,請不要忘記添加與GTM集成相關的內容(您的容器和GoogleInfo plist):

GTM相關資料

我真的希望這會對您有所幫助! 如果有任何不清楚的地方或遇到問題,請隨時發表評論,我會盡力為您提供幫助。

請在下面找到我的資料:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM