iOS-Static Framework

  • 存放類的地方
  • 存放圖片資源的地方
  • 打包生成的方式

第一步:創(chuàng)建一個新的"Cocoa Touch Static Library"工程

Static Library生成的是libSerenity.a的靜態(tài)庫文件.
而我們最終要生成的是Serenity.framework的方式.

效果圖

創(chuàng)建:


創(chuàng)建

第二步:創(chuàng)建主框架的頭文件

如果你希望其他開發(fā)者以<Serenity/Serenity.h> 的方式來使用你自己的靜態(tài)庫.那么你需要確保你的項目中包含該頭文件.例如:

#import <Foundation/Foundation.h>
#import <Serenity/Widget.h>
(ps : Widget.h 是你項目中的其他文件)

一旦你創(chuàng)建了framew得頭文件,你需要將這些頭文件列為"public"的狀態(tài).

public

第三步 : 更新Public類型頭文件的地址

默認情況下,靜態(tài)庫項目將私人的和public頭文件復制在同一文件夾路徑下: /usr/local/include. 為了避免錯誤的將私人標題復制到我們的框架,我們想確保我們的public頭文件復制到一個單獨的目錄中. 例如 :$(PROJECT_NAME)Headers. 要去修改這些設定.

默認路徑

編譯后

編譯后生成的頭文件路徑

修改后


修改后
$(PROJECT_NAME)Headers

再次編譯


再次編譯后的路徑
接下來考慮: 添加一些新的資源到Framework

不管你什么時候要添加一些新的類,你將要考慮是否將這些.h文件是否置為public的狀態(tài),因為默認是Project的狀態(tài),默認不會拷貝到你剛剛創(chuàng)建的自定義的頭文件路徑.

測試

這里添加一個新的NewSource的類測試.
測試結(jié)果:

測試結(jié)果

第四步 : Disable Code Stripping

We do not want to strip any code from the library; we leave this up to the application that is linking to the framework. To disable code stripping we must modify the following configuration settings:

"Dead Code Stripping" => No             (for all settings)
"Strip Debug Symbols During Copy" => No (for all settings)
"Strip Style" => Non-Global Symbols     (for all settings)
Dead Code Stripping
Strip Debug Symbols During Copy
Strip Style

第五步 : 開啟所有architecture支持

我們需要我們的framework可以用于所有的不同設備,所有不同的架構體系

"Build Active Architecture Only" => No (for all settings)
111.png

第六步: 生成架構(以framework的形式)

首先 : 創(chuàng)建文件目錄布局

添加腳本
set -e

mkdir -p "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Versions/A/Headers"

# Link the "Current" version to "A"
/bin/ln -sfh A "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Versions/Current"
/bin/ln -sfh Versions/Current/Headers "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Headers"
/bin/ln -sfh "Versions/Current/${PRODUCT_NAME}" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}"

# The -a ensures that the headers maintain the source modification date so that we don't constantly
# cause propagating rebuilds of files that import these headers.
/bin/cp -a "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}/" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework/Versions/A/Headers"
腳本展示

編譯生成


Framework

生成的目錄結(jié)構:

Serenity.framework/
    Headers/ -> Versions/Current/Headers
    Serenity -> Versions/Current/Serenity
    Versions/
        A/
        Headers/
            Serenity.h
            Widget.h
        Current -> A
接下來: 生成Framework的發(fā)布目標
  • 創(chuàng)建一個新的Aggregate 目標
創(chuàng)建一個新的Aggregate
  • 添加Static Library作為獨立的目標
添加Static Library
  • 修改配置Architecture
修改配置
  • 構建其他平臺

添加腳本

set -e
set +u
# Avoid recursively calling this script.
if [[ $SF_MASTER_SCRIPT_RUNNING ]]
then
    exit 0
fi
set -u
export SF_MASTER_SCRIPT_RUNNING=1

SF_TARGET_NAME=${PROJECT_NAME}
SF_EXECUTABLE_PATH="lib${SF_TARGET_NAME}.a"
SF_WRAPPER_NAME="${SF_TARGET_NAME}.framework"

# The following conditionals come from
# https://github.com/kstenerud/iOS-Universal-Framework

if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]
then
    SF_SDK_PLATFORM=${BASH_REMATCH[1]}
else
    echo "Could not find platform name from SDK_NAME: $SDK_NAME"
    exit 1
fi

if [[ "$SDK_NAME" =~ ([0-9]+.*$) ]]
then
    SF_SDK_VERSION=${BASH_REMATCH[1]}
else
    echo "Could not find sdk version from SDK_NAME: $SDK_NAME"
    exit 1
fi

if [[ "$SF_SDK_PLATFORM" = "iphoneos" ]]
then
    SF_OTHER_PLATFORM=iphonesimulator
else
    SF_OTHER_PLATFORM=iphoneos
fi

if [[ "$BUILT_PRODUCTS_DIR" =~ (.*)$SF_SDK_PLATFORM$ ]]
then
    SF_OTHER_BUILT_PRODUCTS_DIR="${BASH_REMATCH[1]}${SF_OTHER_PLATFORM}"
else
    echo "Could not find platform name from build products directory: $BUILT_PRODUCTS_DIR"
    exit 1
fi

# Build the other platform.
xcrun xcodebuild -project "${PROJECT_FILE_PATH}" -target "${TARGET_NAME}" -configuration "${CONFIGURATION}" -sdk ${SF_OTHER_PLATFORM}${SF_SDK_VERSION} BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}" SYMROOT="${SYMROOT}" $ACTION

# Smash the two static libraries into one fat binary and store it in the .framework
xcrun lipo -create "${BUILT_PRODUCTS_DIR}/${SF_EXECUTABLE_PATH}" "${SF_OTHER_BUILT_PRODUCTS_DIR}/${SF_EXECUTABLE_PATH}" -output "${BUILT_PRODUCTS_DIR}/${SF_WRAPPER_NAME}/Versions/A/${SF_TARGET_NAME}"

# Copy the binary to the other architecture folder to have a complete framework in both.
cp -a "${BUILT_PRODUCTS_DIR}/${SF_WRAPPER_NAME}/Versions/A/${SF_TARGET_NAME}" "${SF_OTHER_BUILT_PRODUCTS_DIR}/${SF_WRAPPER_NAME}/Versions/A/${SF_TARGET_NAME}"

重要提示 :

  • 你可以在這里修改你的打包生成的Framework的名稱
SF_TARGET_NAME=${PROJECT_NAME}
  • 你可以修改為
SF_TARGET_NAME=Serenity
  • 如果你有使用Cocoapods,你需要編譯workspace 而不是project,如果你需要修改workspace相關內(nèi)容,你可以修改一下腳本代碼
xcrun xcodebuild ONLY_ACTIVE_ARCH=NO -workspace "${PROJECT_DIR}/${PROJECT_NAME}.xcworkspace" -scheme "${TARGET_NAME}" -configuration "${CONFIGURATION}" -sdk ${SF_OTHER_PLATFORM}${SF_SDK_VERSION} BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}" SYMROOT="${SYMROOT}" $ACTION

PS : 注意修改workspace setting.修改為legacy build system即可

構建與驗證

編譯Aggregate.

查找
驗證文件

打開終端

lipo -info /Users/liliguang/...../Serenity.framework/Serenity(文件直接拖到終端)

終端打印信息

Architectures in the fat file: /Users/liliguang/...../Serenity.framework/Serenity are: i386 armv7 x86_64 arm64 

需要注意的是: 在這里面編譯生成之后是沒有包含armv7s, 關于iPhone5,5c的架構是armv7s,我測試過是在iPhone5,5c上運行也是沒有問題的.最好也自己測試一下.



Resources and Bundles (資源包)

  • 第一步 : 創(chuàng)建Bundle

創(chuàng)建Bundle
  • 第二步 : 設置Bundle

默認的設置只配置了Mac OS X

設置Bundle

修改打包的Bundle Name

修改Bundle Name
  • 第三步 : 移除 HIDPI Mac OS X Build 設定

我們創(chuàng)建了一個OS X包,它包括并且選擇合并HIDPI(視網(wǎng)膜和non-retina)媒體資源.tiff文件.你不希望這種行為,你需要禁用它,否則你將無法加載映像資產(chǎn)包。

簡單來說,你現(xiàn)在加載了Bundle中的資源.同時項目中也可以通過assets中加載.避免沖突.你將所有的資源全部放在Bundle中使用.因為這是給別人使用的內(nèi)容.

HIDPI
  • 給Bundle中添加資源

無論你什么會后添加資源,請選擇Bundle


添加圖片
  • 第四步 : 添加Bundle到你的Aggregate中

添加到Aggregate中
  • 第五步 : 讀取Bundle資源

// Load the framework bundle.
+ (NSBundle *)frameworkBundle {
    static NSBundle* frameworkBundle = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath];
        NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:@"Bundle.bundle"];
        frameworkBundle = [NSBundle bundleWithPath:frameworkBundlePath];
    });
    return frameworkBundle;
}


代碼自己簡單研究下就可以了.

注意路徑正確就好@"Bundle.bundle"




如果你的項目中需要資源. 你在發(fā)布的時候,需要將.framework與.bundle一起發(fā)給其他開發(fā)者.開發(fā)者直接拖動這兩個文件到他們項目中就可以了...

(這里有個想法,能不能只拖動一個就可以了呢???)
思考其他Framework :
1.需不需要Bundle?也就是有沒有相關的登錄界面的UI素材?
2.有沒有包含資源在一起的Framework創(chuàng)建方式?

我自己對比了一下,其他的SDK,其中也有很多關于Bundle在里面,應該也是和這種方式類似.

也有其他的創(chuàng)建Framework的方式,比如cocoa touch Framework,可以創(chuàng)建靜態(tài)庫和動態(tài)庫.這種方式適合于純方法創(chuàng)建.不適合帶有UI的Framework. 擇優(yōu)選擇吧.

總結(jié)

當開發(fā)一個框架時,滿足你想減少構建時間同時確保你的內(nèi)容大致匹配你的第三方開發(fā)者磺箕。我們實現(xiàn)這一平衡,只是構建static library,把static library當做像framework一樣使用匈织。

Github Demo

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末店乐,一起剝皮案震驚了整個濱河市禾酱,隨后出現(xiàn)的幾起案子涣雕,更是在濱河造成了極大的恐慌四苇,老刑警劉巖已骇,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件离钝,死亡現(xiàn)場離奇詭異,居然都是意外死亡褪储,警方通過查閱死者的電腦和手機卵渴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲤竹,“玉大人浪读,你說我怎么就攤上這事⌒猎澹” “怎么了碘橘?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吱肌。 經(jīng)常有香客問我痘拆,道長,這世上最難降的妖魔是什么氮墨? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任纺蛆,我火速辦了婚禮,結(jié)果婚禮上规揪,老公的妹妹穿的比我還像新娘桥氏。我一直安慰自己,他們只是感情好猛铅,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布识颊。 她就那樣靜靜地躺著,像睡著了一般奕坟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上清笨,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天月杉,我揣著相機與錄音,去河邊找鬼抠艾。 笑死苛萎,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播腌歉,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蛙酪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了翘盖?” 一聲冷哼從身側(cè)響起桂塞,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎馍驯,沒想到半個月后阁危,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡汰瘫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年狂打,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片混弥。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡趴乡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蝗拿,到底是詐尸還是另有隱情晾捏,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布蛹磺,位于F島的核電站粟瞬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏萤捆。R本人自食惡果不足惜裙品,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俗或。 院中可真熱鬧市怎,春花似錦、人聲如沸辛慰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帅腌。三九已至驰弄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間速客,已是汗流浹背戚篙。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留溺职,地道東北人岔擂。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓位喂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乱灵。 傳聞我的和親對象是個殘疾皇子塑崖,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容