場景說明:
-之前做的App,使用Swift框架語言,混合編程,內含少部分OC代碼。
-需要App整體功能打包成靜態庫,完整移植到另一個App使用,該App使用OC。
-所以涉及到一個語言互轉的處理,以及一些AppDelegate的代碼減除變化。
--------------------------------打包篇-------------------------------
實現步驟:
一、新建 Project - Framework&Library - Cocoa Touch Framework,Next 語言選擇Swift
建立完成,會看到默認生成的一個 xxx.h 和 Info.plist 文件(只看紅框內)。
解釋一下這兩個文件:
1⃣️xxx.h 文件的作用是整個包對外提供的入口頭文件,除了正常定義參數屬性之外,還有
1、提供 Swift項目內引用的OC文件的import引用,注意,這里引用之前必須在Build Phrases的Headers內暴露到 Public,見步驟六
2、提供 第三方文件的import引用,這里的第三方管理,我們依然選擇使用Pods管理,下文會具體描述。
以上兩部完成后,舉例效果圖:
2⃣️info.plist 文件的作用就如同正常項目的plist文件作用,用來定義或添加一些屬性。
二、添加文件,這里可以自己新建,或者從已有項目拷貝過來都可以。
這里要注意一下:由於打包類庫工程不是一個完整項目工程,所以並沒有AppDelegate等文件,所以涉及到這些的文件要額外處理,或改代碼,或適當改變功能。
注意:工程如果有橋接文件,是不能拷貝過來的,否則編譯不通過。
原因見步驟五。
三、如果有第三方類庫引用,添加第三方庫文件,有幾個注意點:(沒有第三方可以跳過這步)
a、第三方庫依然使用Pods進行管理,添加方法同正常項目一樣。
b、引用的時候,我們需要添加 【use_frameworks!】來告訴pod 生成動態庫文件Framework類型,這樣做的好處是在正式項目用到本類庫的時候,如果兩者第三方庫有引用沖突,可以根據沖突類庫,對本類庫引入的這些依賴庫進行移除。
但有時第三方類庫只有 .a 類型的,怎么辦?
解決:如果第三方庫只有.a類型,就需要手動把庫文件拷貝到項目,而不能通過pod添加,否則在往步驟1內的頭文件添加import時會找不到文件,造成報錯。
四、以上三部做完,本類庫的雛形基本已經具備了,參考如下:
紅框1:自己的業務代碼
紅框2:類庫原有文件
紅框3:添加的資源文件
紅框4:引入的第三方,pod管理
PS:這里涉及到一個資源文件的問題,比如圖片、視頻、音頻等的處理。
之前正常項目的做法可能是這樣,
1:直接用Assets.xcassets
2:新建resources文件夾,存放圖片
但這里,需要注意一點:
對於方法1,這樣做是無效的,我們可以新建一個bundle文件,將圖片移植過來。
對於方法2,我們可以在本地,直接修改添加后綴.bundle實現
然后另一個重點就是路徑問題:
由於類庫的資源文件,當我們在正式項目使用時,查找的路徑文件不是針對項目,而是針對類庫的路徑,所以我們這里引用的資源文件路徑都要改變一下,而且類庫里的其他xib、storyboard文件引用路徑都需要更改一下。
修改辦法就是:在代碼的引用處添加前綴。
定義前綴:
如圖:
resourceRooturl是xib、storyboard文件前綴路徑。
resourceImagesRooturl是圖片文件前綴路徑。(需要添加一層/images.bundle/)
這個路徑怎么來的呢?
Frameworks/XXXX.framework/ 其中XXXX就是你建立的類庫名稱。
如何引用呢:在代碼引用的地方,這樣改動
注意:這里我說的只是針對Framework包里使用圖片的路徑需要修改。如果外部項目需要使用包內的圖片資源,暫未測試,理論上不需要修改。
五、文件都基本添加完畢,可以嘗試build一下了
理論上:
只要類庫xxx.h文件內,對於使用的oc頭文件和第三方頭文件,都添加正常引用申明了,就不會有問題。
而且一般報錯,也都是因為這里沒做好或遺漏的緣故。
此外:如果項目都是純swift文件(沒有混編使用oc文件),這里xxx.h文件只需要導入第三方頭文件即可(如果有使用第三方,沒有的話基本什么都不用做)。
=======================這里解釋一下,xxx.h文件為什么要這樣做:=================
因為正常情況下,如果我們swift項目引入了oc文件,我們必須通過一個橋接文件來處理兩者之間的轉換,而我們在新建類庫包的時候,是禁止橋接文件存在的,即使你添加了,也會永遠編譯不過,打包不了。
所以這里就用到這個 xxx.h 頭文件了。
我們可以通過這個文件來實現兩者之間的轉換,前提就是必須先將oc的.h暴露出來,否則即使你import,也會報錯找不到.h 文件。
(這里有個問題,如果oc文件過多,這里需要暴露的就很多,而這里太多的話,一個是不美觀,第二是后面項目引用本類庫都是能看到這些文件的。所以,能不能通過一個文件,來裝載這些所有文件,達到只需要一個文件暴露就行的效果,如果有人實現了,歡迎指導一下,不甚感激。)
六、暴露文件給外部使用
到這里基本就快完成了,那么我們打包的目的就是給外部使用,怎么暴露文件出來呢?
1、將我們要暴露的swift文件拖到Public內即可。
2、將需要暴露的swift文件的訪問權限申明為public屬性。
兩步缺一不可。
七、編譯通過,查看這里
紅框內就是最終我們得到的Framework包。
右擊本地查看,會看到本類庫以及對應的依賴第三方庫包,后面在其他項目引用的時候,這些都是需要的(需要一起拷貝添加)。
PS:如果沒有引用第三方,這里只需要本類庫包即可。
------------------------------引用篇------------------------------
1、我們新建一個空的工程,由於我的業務需要,這里工程語言選擇OC。
2、新建Framework文件夾,拷貝之前所有的framework包到文件夾內。
3、在工程Targets-General-EmbeddedBinaries內添加Frameworks包
4、由於我的類庫包是基於swift建立的,這里oc使用的話,必須設置一個屬性:
5、由於我們自己的工程都有自己的第三方庫引用,這里如果發現兩者之間有沖突或重復引用,解決如下:
a:如果pod引用內,沒有標注 use_frameworks! 我們先加上這句話,並pod update,目地是保持兩邊引用的第三方類庫都是Framework類型。
b:移除剛才添加過來中的重復類庫,比如AFN
6、添加完,我們就可以在新項目使用類庫集成的功能了
這邊引用的時候有點特殊:
我們只需要把一個文件import即可,而不需要把每一個需要使用的swift文件import。
舉例如圖:
這個文件是系統幫我們自動生成的一個轉換文件,我們要暴露的文件,系統都已經幫我們自動轉換后儲存在這個文件內,很強大,有么有!!!
比如:我的登錄頁面 login.swift文件暴露給外部,需要提供入口,我們使用的時候,是不需要import login.swift的,即使你想import,也會發現找不到!!
如果你點進去紅框文件,會發現類似這樣的內容:
所以我們使用的時候,頭部只需要import一個文件,下面使用的時候,該使用哪個類就使用哪個類。
前提就是:在打包的時候,你已經把這個文件 添加到Public里了,並且申明了public屬性,否則是找不到該文件的。
最后,把我過程中遇到的一些問題紀錄一下
引用集成時遇到的坑:
==================================報錯1:==================================
dyld: Library not loaded: @rpath/AFNetworking.framework/AFNetworking
這里是因為只引用了之前的類庫本身,沒有將類庫自身的依賴庫一並引用過來,
解決辦法:
方法1:
方法2:
按照我的引用篇-步驟3去做,在general處,全部添加,就不會報這個問題。
==================================報錯2:==================================
dyld: Library not loaded: @rpath/libswiftCore.dylib
解決辦法:
按照我的引用篇-步驟4去做 ,設置屬性為Yes。
Xcode8升級之后屬性名稱有所變化:
==================================報錯3:==================================
Unknown class in Interface Builder file .... image not found 等
解決辦法:
==================================報錯4:==================================
load storyboard 或xib 崩潰
解決辦法:
是因為打包的地方引用文件路徑沒有改動,需要加上類庫前綴路徑,詳見打包篇-步驟四。
-----------------------打包合並真機和模擬器------------------------
詳細內容有點多:
若還有其他問題歡迎留言。
enjoy~~