主要解決以下三個問題:
- 自己封裝的framework庫有多個公共的方法,model,類等,所以打算封裝一個公共類庫,讓其他的framework庫進行依賴;
- framework庫中包含圖片資源,plist文件的讀取 ;
- 資源文件bundle的創(chuàng)建方式;
1. 一般公共類庫的封裝
不涉及資源問題,就是一些公共方法的封裝,封裝流程和一般的framework庫沒區(qū)別,注意點:
- 暴露.h文件;
- image.png
- image.png
- 設置成release版本;
- 如果用了Category分類,需要在工程中
other linker flags中添加-objC,如果依然有問題,再添加-all_load; - 關于符號表的警告,這時需要將
Generate Debug Symbols設置為NO即可關閉符號表警告; - 如果需要支持
bitcode:在TAGETS的Build setting中搜索Other C Flags,添加命令-fembed-bitcode。同樣的設置在PROJECT中。
2. 創(chuàng)建資源文件bundle
兩種方式
- 直接創(chuàng)建文件夾,拖入文件,再修改后綴為.bundle;
此方法缺點是如果有新的資源需要導入,又得重新在創(chuàng)建文件夾,把上一次的資源全部拷貝進來,更新新的資源,很麻煩;- 使用Xcode生成,具體如下:
-
創(chuàng)建Bundle文件:創(chuàng)建工程,選擇如下:
image.png -
進行配置:
image.png




info.plist文件處理:(打包的bundle給別人使用,別人在打包完上傳過程中可能會極大的坑,加上如下處理)


然后把圖片導入工程,build即可;分別選擇真機和模擬器,然后各運行一遍,即可生成真機和模擬器使用的bundle;
3. 創(chuàng)建包含資源和依賴庫的framework庫
- 創(chuàng)建的SDK,這里命名為 AM300QuestionSDK,選擇的是framework庫;
- 把上面創(chuàng)建的依賴庫 AM300PublicSDK.framework添加到AM300QuestionSDK文件夾下;
- 對SDK進行配置:具體配置和上面創(chuàng)建framework庫一樣;
- 把工程中使用到公共類庫的地方,修改成: #import <AM300PublicSDK/XXX.h>;
- 把創(chuàng)建好的資源: questionimages.bundle 導入到AM300QuestionSDK下;
- 資源文件的調用問題修改:
因為現(xiàn)在iOS只能創(chuàng)建自己的靜態(tài)庫,靜態(tài)庫資源加載方式:
plist文件如下:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Am300QuestionSDK.framework/questionimages" ofType:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
NSString *plistPath = [bundle pathForResource:@"QuestionnaireList" ofType:@"plist"];
image如下:
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Am300QuestionSDK.framework/questionimages" ofType:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
NSString *fileName = [NSString stringWithFormat:@"%@%@",imageName,@"@2x.png"];
NSString *filePath = [bundle pathForResource:fileName ofType:nil];
UIImage *img = [UIImage imageWithContentsOfFile:filePath];
修改完,然后運行生成framework文件;
4. 庫的使用
-
創(chuàng)建一個工程,導入SDK及其依賴庫,創(chuàng)建SDK的調用類CRQuestionViewController,用于驗證SDK是否正常工作;
image.png -
現(xiàn)在運行工程,發(fā)現(xiàn)可以正常運行,但是資源文件沒有加載成功,
因為靜態(tài)庫framework讀取資源文件需要額外創(chuàng)建一個copy Files 進行讀取
操作如下:
image.png

然后運行,成功.
注:不管是資源文件.bundle還是framework庫,都存在真機和模擬器,上架需要記得使用真機生成;
上面第二步一定不能少,除非你的資源文件是直接放在主工程目錄下的;不過不把資源文件放在framework庫中,那也就沒必要打framework庫了,直接用.a庫也行了,主要還是看需求;
參考鏈接:
http://www.itdecent.cn/p/c92c08d8afda
https://blog.csdn.net/ljl5125/article/details/52210283
http://www.itdecent.cn/p/fb5083f2c0d2
5.創(chuàng)建可調式工程
以上的方式,如果SDK有問題,修改很麻煩,所以可以創(chuàng)建可調試工程,運行沒問題直接生成framework庫,操作如下:
創(chuàng)建項目工程TiaoShiDemo
通過TARGETS 添加 一個我們要創(chuàng)建的SDK,這里命名為 AM300QuestionSDK,選擇的是framework庫,不創(chuàng)建.a
把我們SDK需要的類導入AM300QuestionSDK文件夾下;
把上面創(chuàng)建的依賴庫 AM300PublicSDK.framework添加到AM300QuestionSDK文件夾下;
通過TARGETS—> AM300QuestionSDK :對SDK進行配置:具體配置和上面創(chuàng)建framework庫一樣;
把工程中使用到公共類庫的地方,修改成: #import <AM300PublicSDK/XXX.h>
選擇AM300QuestionSDK,進行編譯,編譯通過后,選擇TiaoShiDemo編譯,發(fā)現(xiàn)報錯;因為我們的TiaoShiDemo工程沒有AM300PublicSDK.framework,需要添加一個;
把創(chuàng)建好的資源: questionimages.bundle 導入到AM300QuestionSDK下;
然后運行工程即可
問題:
這樣創(chuàng)建的AM300QuestionSDK,在訪問資源時,需要使用如下方式:
/得到framework路徑
#define FrameworkPath [[NSBundle mainBundle] pathForResource:@"Frameworks/AM300QuestionSDK" ofType:@"framework"]
//得到對應的bundle路徑
#define FrameworkBundle [NSBundle bundleWithPath:FrameworkPath]
//得到資源的bundle路徑
#define VivienBundle [NSBundle bundleWithPath:[FrameworkBundle pathForResource:@"questionimages" ofType:@"bundle"]]
//獲取資源路徑,文件實例:
NSString *plistPath = [VivienBundle pathForResource:@"QuestionnaireList" ofType:@"plist"];
但是如果用上面的訪問方式,最后生成framework,在使用時,資源讀取會失敗;導致我在生成framework庫前,又要更改資源的讀取方式,不知道是哪里有問題沒有設置好,有知道的仁兄指點一二.
一些基本設置說明:
-ObjC
我們知道在Objective-C中方法調用都是在運行期確定的,所以Objective-C沒有針對每個方法定義鏈接符號,它只每個類創(chuàng)建鏈接符號。因此當在一個靜態(tài)庫中使用類別來擴展已有類的時候,鏈接器不知道如何把類原有的方法和類別中的方法整合起來,就會導致你調用類別中的方法時出現(xiàn)selector not recognized的錯誤。
設置ObjC標志后,鏈接器會把一個類相關的所有目標文件都加載進來,這樣就解決了這個問題。由于這樣做會使可執(zhí)行文件體積變大,所以需要需要自己手動設置一下。
官方的說明鏈接:https://developer.apple.com/library/archive/qa/qa1490/_index.html
參考鏈接:http://www.itdecent.cn/p/fb5083f2c0d2
-all_load 和 -force_load
在64位ios應用環(huán)境下,在靜態(tài)庫中只有category而沒有對應的class定義時-ObjC標志會失效(這是鏈接器的一個bug)
這時可以使用-all_load強制加載所有目標文件 或者使用-force_load指定加載某一個包
千萬不要隨便使用這個參數(shù)!假如你使用了不止一個靜態(tài)庫文件,然后又使用了這個參數(shù),那么你很有可能會遇到ld: duplicate symbol錯誤,因為不同的庫文件里面可能會有相同的目標文件
所以建議在遇到-ObjC失效的情況下使用-force_load參數(shù)
-force_load所做的事情跟-all_load其實是一樣的
但是-force_load需要指定要進行全部加載的庫文件的路徑
這樣的話,你就只是完全加載了一個庫文件,不影響其余庫文件的按需加載
2021.01.13新增:模擬器包含arm64打包合并問題
只需要對模擬器的.a進行處理即可,終端輸入如下
lipo 路徑/XXX.a -remove arm64 -output 路徑/XXX.a





