時間:2020年7月
版本:Xcode 11.5 (11E608c)
語言:Objective-C
作者:非著名程序員
介紹自己在實際開發(fā)SDK過程中遇到的實際問題割捅,以及解決方案。僅供參考帚桩。
- Framework與主工程(App)實時聯(lián)調
- Framework亿驾、主工程(App)以及 Pod 等三個工程實時聯(lián)調
- 使用腳本合并真機、模擬器等多種架構的Framework
- Framework中使用
.bundle
資源文件 - Framework中使用Category
- Framework支持bitcode
一账嚎、Framework與主工程(App)實時聯(lián)調
① 為什么需要實時聯(lián)調莫瞬?
首先說明,F(xiàn)ramework指的是我們自己開發(fā)的Framework(SDK)郭蕉,主工程(App)泛指那些要接入你的SDK的App乏悄。
朕之前在寫SDK進行調試的時候都是先創(chuàng)建一個Framework的工程,代碼都寫完之后打包成Framework靜態(tài)庫恳不,然后再把Framework拉到App的主工程中去驗證功能檩小。這樣的調試方式沒什么不可以,但是非常的浪費時間烟勋,需要一遍又一遍的打包Framework规求,而且Framework中的問題不可以打斷點排查。
② 實時聯(lián)調最終要達到什么效果卵惦?
實時聯(lián)調最終要達到的效果是:僅需要讓主工程跑起來就可以同時調試Framework和App兩個工程的代碼阻肿。
這樣一來,F(xiàn)ramework不用每次都去打包一遍沮尿,再拖進App工程丛塌。大致的流程可以理解為:先build Framework较解,F(xiàn)ramework編譯完成后自動添加到App中,最后build App赴邻。
③ 干
1. 創(chuàng)建App工程印衔,命名為RealDemo
2. 創(chuàng)建Framework工程,命名為RealSDK
注意路徑姥敛!
3. 設置Framework工程的Build Settings
4. 創(chuàng)建WorkSpace奸焙,命名為RealDemo
注意路徑!
5. 連接Framework工程和App工程
打開 RealDemo.xcworkspace彤敛,毫無疑問与帆,空空如也
直接把需要連接的Framework工程和App工程拖進來即可
哎~你瞧,這就有了
6. 把Framework添加到App工程中
添加完是這樣的
有過SDK開發(fā)經驗的道友到這里應該已經看明白了墨榄,所謂實時聯(lián)調說白了就是用WorkSpace把兩個工程連接起來而已玄糟,跟Pod的原理有幾分相似。
繼續(xù)袄秩,咱們驗證一下
7. 給Framework加點功能
增加一個RealDog
類茶凳,定義一個eat
方法,實現(xiàn)里面打印一句話“吃骨頭”播揪。最后在SDK的公開頭文件RealSDK.h
中集中引用一下贮喧。
// RealDog.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface RealDog : NSObject
- (void)eat;
@end
NS_ASSUME_NONNULL_END
// RealDog.m
#import "RealDog.h"
@implementation RealDog
- (void)eat {
NSLog(@"吃骨頭");
}
@end
// RealSDK.h
#import <Foundation/Foundation.h>
//! Project version number for RealSDK.
FOUNDATION_EXPORT double RealSDKVersionNumber;
//! Project version string for RealSDK.
FOUNDATION_EXPORT const unsigned char RealSDKVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <RealSDK/PublicHeader.h>
#import <RealSDK/RealDog.h>
8. 在App的ViewController調用一下SDK的方法
// ViewController.m
#import "ViewController.h"
#import <RealSDK/RealSDK.h>
@interface ViewController ()
@property (nonatomic, strong) RealDog *dog;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dog = [[RealDog alloc] init];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.dog eat];
}
@end
OK,實時聯(lián)調到此結束猪狈。
二箱沦、Framework、主工程(App)以及 Pod 等三個工程實時聯(lián)調
再加上Pod之后雇庙,三個工程實時聯(lián)調其實也沒什么難的谓形,只要保證剛剛第一部分的工程文件夾層級關系,然后直接創(chuàng)建Podfile疆前,pod install
即可寒跳。
注意:此處Podfile里面的target是RealDemo!
platform :ios, '10.0'
target 'RealDemo' do
pod 'AFNetworking', '~> 4.0.1'
end
三個工程順利組到一起竹椒,全部可實時聯(lián)調童太。
三、使用腳本合并真機胸完、模擬器等多種架構的Framework
- 添加一個
Aggregate
Target书释。路徑:RealSDK Project -> TARGETS -> "+"(左下角) -> Cross-platform - Other -> Aggregate
WX20200718-110427@2x.png
-
Aggregate
Target 命名為“RealDemo-Script”
WX20200718-110553@2x.png
WX20200718-110835@2x.png
-
依賴RealSDK
WX20200718-112151@2x.png
-
添加腳本
WX20200718-112823@2x.png
WX20200718-113154@2x.png
腳本源碼
這個腳本是通用的,各位道友直接復制粘貼即可~
# Type a script or drag a script file from your workspace to insert its path.
UNIVERSAL_OUTPUTFOLDER=../Framework/
# 創(chuàng)建輸出目錄赊窥,并刪除之前的framework文件
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
rm -rf "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework"
# 分別編譯模擬器和真機的Framework
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# 定義真機爆惧、模擬器Build文件夾路徑變量
IPHONE_BUILD=${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
SIMULATOR_BUILD=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
# 拷貝framework到univer目錄
cp -R "${IPHONE_BUILD}" "${UNIVERSAL_OUTPUTFOLDER}/"
#cp -R "${SIMULATOR_BUILD}" "${UNIVERSAL_OUTPUTFOLDER}/"
# 定義輸出路徑變量
OUTPUT_PATH=${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework
# 合并framework,輸出最終的framework到build目錄
lipo -create "${IPHONE_BUILD}/${PROJECT_NAME}" "${SIMULATOR_BUILD}/${PROJECT_NAME}" -output "${OUTPUT_PATH}/${PROJECT_NAME}"
-
運行腳本
WX20200718-120005@2x.png
-
運行結果
WX20200718-115622@2x.png
-
檢驗一下是否合成成功
WX20200718-120516@2x.png
四锨能、Framework中使用.bundle
資源文件
-
首先扯再,我們先隨便創(chuàng)建一個Bundle工程芍耘。
WX20200718-152228.png
- Bundle工程命名為
RealSDKResource
。在Build Settings中修改Base SDK為iOS熄阻。
WX20200718-152500.png
- 去掉Bundle文件的
info.plist
文件
WX20200718-153145.png
-
修改Bundle文件名稱(可依需求選擇)
WX20200718-153421.png
-
將Versioning System設置為None斋竞,默認Xcode會通過agvtool生成對應的版本信息,并打包進bundle文件中饺律,這會導致后續(xù)在SDK跟隨使用的App提交到AppStore的時候報錯窃页。
WX20200718-153623.png
-
加一張圖片資源跺株,打包
WX20200718-160219.png
WX20200718-160246.png
- 測試一下RealSDK是否可以引用Bundle資源复濒,SDK中什么都不用設置,直接引用Bundle資源即可乒省。注意引用Bundle資源的方式:用字符串路徑讀取圖片巧颈。還可以用NSBundle獲取文件。
用NSBundle獲取文件
- 把Bundle文件拖到App工程中袖扛,寫一個測試代碼
- 運行起來砸泛,看一下效果,OJBK
五蛆封、Framework中使用Category
在Framework工程的Build Setting中添加-ObjC
唇礁。另外,使用我們SDK的App的Build Setting中也要添加-ObjC
惨篱。
在網上看到有人建議用-all_load
盏筐,我個人建議使用-ObjC
足矣。-all_load
會比-ObjC
范圍更大移袍,沒有必要的事情就不要做赁温,免得浪費性能业栅。具體區(qū)別我就不在這里具體說了,網上一大片漾抬。