iOS 打Framework

六月潮濕天氣的日數比五月多,比四月也多烫沙。周四晚踢足球匹层,深圳多雨,中午電閃雷鳴雨不停锌蓄,有人建議取消場地升筏,我想雨后終究會見到彩虹,不一會瘸爽,雨停您访。

項目需求提供framework,記錄下過程剪决。

一灵汪、什么是庫?
庫是共享程序代碼的方式柑潦,一般分為靜態(tài)庫和動態(tài)庫享言。

二、靜態(tài)庫和動態(tài)庫的區(qū)別渗鬼?
靜態(tài)庫:鏈接時完整地拷貝至可執(zhí)行文件中览露,被多次使用就有多分拷貝冗余拷貝。
動態(tài)庫:鏈接不復制譬胎,程序運行時由系統(tǒng)動態(tài)加載到內存差牛,供程序調用命锄,系統(tǒng)只加載一次,多個程序共用多糠,節(jié)省內存累舷。

三浩考、iOS里靜態(tài)庫形式夹孔?
.a和.framework

四、iOS里動態(tài)庫形式析孽?
.dylib和.framework

五搭伤、framework為么可以既是靜態(tài)庫有事動態(tài)庫?
系統(tǒng)的.framework是動態(tài)庫袜瞬,我們自己建立的.framework是靜態(tài)庫怜俐。

六、.a與.framework有什么區(qū)別邓尤?
.a是一個純二進制文件拍鲤,.framework中除了有二進制文件之外還有資源文件。
.a文件不能直接使用汞扎,至少要有.h文件配合季稳,.framework文件可以直接使用。
.a + .h + sourceFile = .framework澈魄。
建議用.framework景鼠。

七、為什么要使用靜態(tài)庫痹扇?
方便共享代碼铛漓,便于合理使用。
實現iOS程序的模塊化鲫构∨ǘ瘢可以把固定的業(yè)務模塊化成靜態(tài)庫。和別人分享你的代碼庫结笨,但不想讓別人看到你代碼的實現问顷。開發(fā)第三方sdk的需要。

提供給接入方使用的是文件禀梳,一般是一個.framework和一個同名的.bundle文件杜窄。

1、嵌入包含.bundle的framework到接入方的embeded binaries里面算途,剛開始想著是否能只提供一個.framework文件塞耕,bundle包含在里面∽烊浚可是可以扫外,只是需要將打出來的.framework導入到embeded binaries中莉钙。但是接入此.framework后,打包會報錯。

VaRZnA.png

點擊show logs筛谚,did not contain a "archived-expanded-entitlements.xcent" resource
解決辦法:一個static的libraryxxx.framework被添加在Embedded Binaries里面了磁玉,從Embedded Binaries移除framework,添加在Link Frameworks and Libraries里面驾讲。
只能作罷蚊伞,只有動態(tài)庫能放到embeded binaries中,Xcode也能制作動態(tài)庫吮铭,只是不能上傳AppStore时迫。
通過嵌入embeded binaries里面打出來的,最后形成.app文件右鍵顯示包內容之后和可以看到一個Frameworks的文件夾谓晌。里面有嵌入embeded binaries的所有framework掠拳。


Snip20190615_1.png
  • 新建一個workspace,添加兩個project:CVideoProject,CVideoDemoProject纸肉。在CVideoProject中添加一個target:CVideoBundle溺欧。相當于總共有三個target,方便調試。

1.新建靜態(tài)庫:static framework柏肪。

Snip20190616_2.png
2.修改配置信息
  • 每次build時不是只生成支持一種設備的framework


    Snip20190616_3.png
  • 添加framework支持所有類型設備姐刁。


    Snip20190616_4.png
arm64:iPhone6s | iphone6s plus|iPhone6| iPhone6 plus|iPhone5S | iPad Air| iPad mini2(iPad mini with Retina Display)
armv7s:iPhone5|iPhone5C|iPad4(iPad with Retina Display)
armv7:iPhone4|iPhone4S|iPad|iPad2|iPad3(The New iPad)|iPad mini|iPod Touch 3G|iPod Touch4
i386是針對intel通用微處理器32位處理器
x86_64是針對x86架構的64位處理器
模擬器32位處理器測試需要i386架構,
模擬器64位處理器測試需要x86_64架構预吆,
真機32位處理器需要armv7,或者armv7s架構龙填,
真機64位處理器需要arm64架構。

  • 需要暴露給接入方使用的頭文件移到public路徑中拐叉。


    Snip20190616_5.png

    Snip20190616_8.png

3.在framework中新建bundle岩遗。

Snip20190616_9.png

Snip20190616_10.png
  • 導入用到的資源文件


    Snip20190616_14.png
  • 修改bundle文件的參數配置


    Snip20190616_15.png

    Snip20190616_16.png

    Snip20190616_18.png

    Snip20190616_20.png
  • 編譯bundle target生成bundle。


    Snip20190616_23.png

    Snip20190616_24.png

    Snip20190616_25.png
  • 編譯framework發(fā)現framework中包含bundle凤瘦。


    Snip20190616_26.png

1宿礁、將bundle放入到framework中,打出來的framework中包含bundle蔬芥,此時代碼里面引入圖片的路徑有變梆靖。在workspace的Demo中的embeded binaries引入framework。

0.gif
  • 通過打開CVideoDemo.app顯示包內容發(fā)現如果嵌入到embeded binaries中的framework都放在一個frameworks文件夾路徑下笔诵。而CVideo.bundle就在Frameworks/CVideo.framework路徑下返吻,圖片的路徑據此找到。


    1.gif
-(void)setupBackNaviBar
{
    self.navigationItem.leftBarButtonItem = nil;
    self.backView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 44)];
    CVideoAddAreaButton *backButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
    backButton.shouldExpandClickArea = YES;
    [backButton setFrame:CGRectMake(0, 0, 44, 44)];
    [backButton setImage:[CVideoBundle CVideoImageWithName:@"icon_back"] forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(onNaviBack) forControlEvents:UIControlEventTouchUpInside];
    [self.backView addSubview:backButton];
    
    self.closeButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
    self.closeButton.shouldExpandClickArea = NO;
    [self.closeButton setFrame:CGRectMake(32, 0, 44, 44)];
    [self.closeButton setImage:[CVideoBundle CVideoImageWithName:@"icon_close"] forState:UIControlStateNormal];
    [self.closeButton addTarget:self action:@selector(closeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.backView addSubview:self.closeButton];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.backView];
}
+ (NSString *)CVideoBundlePathForResource:(NSString *)name ofType:(NSString *)type {
    NSString *bundlePath = [self getCVideoBundlePath];
    return [[NSBundle bundleWithPath:bundlePath] pathForResource:name ofType:type];
}

+ (UIImage *)CVideoImageWithName:(NSString *)name {
    //bundle放入framework中乎婿,framework嵌入embeded binaries中的圖片路徑
    name = [NSString stringWithFormat:@"%@@%dx", name, (int)[UIScreen mainScreen].scale];
    NSString *imagePath = [CVideoBundle CVideoBundlePathForResource:name ofType:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    //bundle單獨拖入Demo中的bundle路徑
//    NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[self getCVideoBundlePath],name];
//    UIImage *image = [UIImage imageNamed:imagePath];
    return image;
}

+ (NSString *)getCVideoBundlePath {
    static NSString *bundlePath;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //bundle放入framework中测僵,framework嵌入embeded binaries中的bundle路徑
        bundlePath = [[NSBundle mainBundle] pathForResource:@"Frameworks/CVideo.framework/CVideo" ofType:@"bundle"];
        //bundle單獨拖入Demo中的bundle路徑
//        bundlePath = [[NSBundle mainBundle] pathForResource:@"CVideo" ofType:@"bundle"];
    });
    return bundlePath;
}

2、顯然,雖然將bundle放入framework中,提供給接入方只需要提供framework文件給接入方而不需要提供bundle文件捍靠,但是打包的時候會報錯沐旨,所以還是要將bundle和framework分開提供。

2.gif
  • 圖片的路徑榨婆。
-(void)setupBackNaviBar
{
    self.navigationItem.leftBarButtonItem = nil;
    self.backView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 44)];
    CVideoAddAreaButton *backButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
    backButton.shouldExpandClickArea = YES;
    [backButton setFrame:CGRectMake(0, 0, 44, 44)];
    [backButton setImage:[CVideoBundle CVideoImageWithName:@"icon_back"] forState:UIControlStateNormal];
    [backButton addTarget:self action:@selector(onNaviBack) forControlEvents:UIControlEventTouchUpInside];
    [self.backView addSubview:backButton];
    
    self.closeButton=[CVideoAddAreaButton buttonWithType:UIButtonTypeCustom];
    self.closeButton.shouldExpandClickArea = NO;
    [self.closeButton setFrame:CGRectMake(32, 0, 44, 44)];
    [self.closeButton setImage:[CVideoBundle CVideoImageWithName:@"icon_close"] forState:UIControlStateNormal];
    [self.closeButton addTarget:self action:@selector(closeButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.backView addSubview:self.closeButton];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:self.backView];
}
+ (NSString *)CVideoBundlePathForResource:(NSString *)name ofType:(NSString *)type {
    NSString *bundlePath = [self getCVideoBundlePath];
    return [[NSBundle bundleWithPath:bundlePath] pathForResource:name ofType:type];
}

+ (UIImage *)CVideoImageWithName:(NSString *)name {
    //bundle放入framework中磁携,framework嵌入embeded binaries中的圖片路徑
    name = [NSString stringWithFormat:@"%@@%dx", name, (int)[UIScreen mainScreen].scale];
//    NSString *imagePath = [CVideoBundle CVideoBundlePathForResource:name ofType:@"png"];
//    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    //bundle單獨拖入Demo中的bundle路徑
    NSString *imagePath = [NSString stringWithFormat:@"%@/%@",[self getCVideoBundlePath],name];
    UIImage *image = [UIImage imageNamed:imagePath];
    return image;
}

+ (NSString *)getCVideoBundlePath {
    static NSString *bundlePath;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //bundle放入framework中,framework嵌入embeded binaries中的bundle路徑
//        bundlePath = [[NSBundle mainBundle] pathForResource:@"Frameworks/CVideo.framework/CVideo" ofType:@"bundle"];
        //bundle單獨拖入Demo中的bundle路徑
        bundlePath = [[NSBundle mainBundle] pathForResource:@"CVideo" ofType:@"bundle"];
    });
    return bundlePath;
}

Demo地址良风。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末谊迄,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子拖吼,更是在濱河造成了極大的恐慌鳞上,老刑警劉巖这吻,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吊档,死亡現場離奇詭異,居然都是意外死亡唾糯,警方通過查閱死者的電腦和手機怠硼,發(fā)現死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來移怯,“玉大人香璃,你說我怎么就攤上這事≈畚螅” “怎么了葡秒?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嵌溢。 經常有香客問我眯牧,道長,這世上最難降的妖魔是什么赖草? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任学少,我火速辦了婚禮,結果婚禮上秧骑,老公的妹妹穿的比我還像新娘版确。我一直安慰自己,他們只是感情好乎折,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布绒疗。 她就那樣靜靜地躺著,像睡著了一般骂澄。 火紅的嫁衣襯著肌膚如雪吓蘑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天酗洒,我揣著相機與錄音士修,去河邊找鬼枷遂。 笑死,一個胖子當著我的面吹牛棋嘲,可吹牛的內容都是我干的酒唉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼沸移,長吁一口氣:“原來是場噩夢啊……” “哼痪伦!你這毒婦竟也來了?” 一聲冷哼從身側響起雹锣,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤网沾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蕊爵,有當地人在樹林里發(fā)現了一具尸體辉哥,經...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年攒射,在試婚紗的時候發(fā)現自己被綠了醋旦。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡会放,死狀恐怖饲齐,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情咧最,我是刑警寧澤捂人,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站矢沿,受9級特大地震影響滥搭,放射性物質發(fā)生泄漏。R本人自食惡果不足惜咨察,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一论熙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧摄狱,春花似錦脓诡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至酣衷,卻和暖如春交惯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工席爽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留意荤,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓只锻,卻偏偏與公主長得像玖像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子齐饮,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內容