Just a Computer Graphics Studio & My Life

又到了要套用第三方套件的時候,一般而言都是找最「受歡迎」的GitHub開源套件,因為做得好大家有目共睹,還會給作者一顆星!不過在台灣的市場,要套Beacon SDK就得找台灣廠商,去年旅遊App套一個廠商的Beacon SDK,搞了一陣子的背景偵測有問題,現在購物App也要來套另一個廠商的Beacon SDK,這個廠商製作各種「可串接」套件都有些問題,這次當然也少不了啦XD~

回想三年多前iBeacon被Apple提出來至今,台灣市場總算熱絡了起來,可以回顧一下我先前撰寫的初探iBeacon

一直希望合作廠商的「成品」能夠直接使用而沒有任何問題,但是目前串接以來多少有些問題需要排解。因為負擔三個超大案子,所以測試Beacon SDK的任務先交給Android工程師同事,不過他也僅能測試Android平台,iOS平台還是要由我來試驗。確實不意外,兩個平台都出現問題,而且問題還不太一樣⋯⋯

就來說明iOS Beacon SDK出現什麼問題好了~

我按照使用說明書把SDK匯進專案,將API Key和URL設定好,很高興地編譯且執行順利!然而這時候Xcode跳到AFNetworking某個Class,Console出現一大串很類似的錯誤訊息:

objc[14676]: Class AFNetworkReachabilityManager is implemented in both /private/var/containers/Bundle/Application/28E9058F-4187-4903-BF9F-3D391FCFB708/HappyLife.app/Frameworks/AFNetworking.framework/AFNetworking (0x100717f18) and /var/containers/Bundle/Application/28E9058F-4187-4903-BF9F-3D391FCFB708/HappyLife.app/HappyLife (0x1003f15d8). One of the two will be used. Which one is undefined.
2017-03-21 14:50:22.017344HappyLife[14676:4139382] Unknown class ViewController in Interface Builder file.
2017-03-21 14:50:22.041679HappyLife[14676:4139382] -[AFHTTPSessionManager POST:parameters:progress:success:failure:]: unrecognized selector sent to instance 0x1701b7300
(lldb)

翻作白話文的意思是,在Run Time的時候,程式執行到要呼叫AFNetworking,不知道要選擇哪一個Method執行,就崩潰給你看。才發現原來Beacon SDK有把AFNetworking包在XXXEngine.a中,在Compile Time時無法得知。想到的解法是請廠商把AFNetworking套件露出來,不要包在XXXEngine.a中,說明文件好歹也要寫一下SDK的相依套件呀⋯⋯

[iOS] 拆掉和包裝套件 (Unarchive and Archive Library)2

好在這次廠商一天就回覆,真的有把AFNetworking套件露出來,我也很高興地再次來串SDK,只不過我得移除專案中早已使用的AFNetworking套件,改採用廠商露出來的AFNetworking套件。移除後且修改完引用路徑發現,原本寫的Method出現紅色錯誤訊息,原來該SDK使用舊版的AFNetworking,好在只要把Progress這個參數給移除,然而跑到最後又出現之前有遇過的錯誤:

duplicate symbol _AFQueryStringPairsFromDictionary in:
/Users/jason/Library/Developer/Xcode/DerivedData/HappyLife-cknfvpankgemrwdcbyexaygtryjt/Build/Intermediates/HappyLife.build/Debug-iphoneos/HappyLife.build/Objects-normal/armv7/AFURLRequestSerialization.o
/Users/jason/git/HappyLife-ios/HappyLife/Framework/XXXEngine.a(AFURLRequestSerialization.o)
duplicate symbol _OBJC_IVAR_$_AFHTTPBodyPart._boundary in:
/Users/jason/Library/Developer/Xcode/DerivedData/HappyLife-cknfvpankgemrwdcbyexaygtryjt/Build/Intermediates/HappyLife.build/Debug-iphoneos/HappyLife.build/Objects-normal/armv7/AFURLRequestSerialization.o
/Users/jason/git/HappyLife-ios/HappyLife/Framework/XXXEngine.a(AFURLRequestSerialization.o)

ld: 208 duplicate symbols for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

這次說有「重複的符號 (duplicate symbol)」,而且是在Compile Time就知道!之前還要到Run Time才會出現重複定義Method,難道是因為AFNetworking套件版本一樣,所以可以提早知道?總之這次想到的解法就是要把XXXEngine.a中的AFNetworking套件(相關.o檔)給移除,還是要透過廠商幫忙一途。

因為追根究柢的精神,讓我找到可以拆掉和包裝套件 (Unarchive and Archive Library)的方式,原來是可以透過終端機指令,知道.a檔裡包含哪些套件!甚至還能先拆掉和再包裝,我乾脆自己來做這件事~~~

[iOS] 拆掉和包裝套件 (Unarchive and Archive Library)

  • 得知架構

$ lipo -info XXXEngine.a

Architectures in the fat file:XXXEngine.a are: armv7 arm64

  • 輸出架構(以arm64為例,armv7如法炮製)

$ lipo -thin arm64 XXXEngine.a -output XXXEngine_arm64.a

  • 先拆解.a檔

$ ar -t XXXEngine_arm64.a

__.SYMDEF
AFURLRequestSerialization.o
AFURLConnectionOperation.o
UIAlertView+AFNetworking.o
AFSecurityPolicy.o
AFHTTPRequestOperation.o
AFURLSessionManager.o
AFURLResponseSerialization.o
XXXEngine.o
UIProgressView+AFNetworking.o
AFHTTPSessionManager.o
AFNetworkActivityIndicatorManager.o
AFHTTPRequestOperationManager.o
UIImageView+AFNetworking.o
UIButton+AFNetworking.o
UIRefreshControl+AFNetworking.o
UIWebView+AFNetworking.o
AFNetworkReachabilityManager.o
GTMBase64.o
UIActivityIndicatorView+AFNetworking.o

可以見到,大部分都是AFNetworking相關.o檔,所以全數移除就對了!於是剩下⋯⋯

XXXEngine.o

  • 包裝.a檔

$ libtool -static *.o -o XXXEngine_arm64.a

  • 最後將所有架構物件檔(XXXEngine_arm64.a和XXXEngine_armv7.a)包裝起來

$ lipo -create XXXEngine_arm64.a XXXEngine_armv7.a -output XXXEngine_test.a

用XXXEngine_test.a取代原本的XXXEngine.a匯入專案,你將會發現,duplicate symbol已經悉數消失,總算可以偵測到手邊三顆廠商給的Beacon,不過問題還沒完結XD~

之後再說囉~

參考:如何解决duplicate symbols for architecture

Advertisements

發表留言

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

標籤雲

%d 位部落客按了讚: