Framework 打包

引言

SDK定义上是指软件开发包,对应iOS端来说就包含了库文件、头文件、资源文件等文件的集合。SDK开发就是在保证sdk源代码安全的情况,给开发者一个可方便快速接入的,兼容多个iOS系统、便于真机模拟器调试、可以上线AppStore的库。这句话包含的几个重要的信息将在本文中逐步详解。

Step1:设置building setting(选static或者dynamic)

image.png

Step2: 接口设计

  1. 接口命名的正确方式:createGroupWithTitle:(NSString *)title
    包含:action(create)+parameters(title)
    需要对参数类型进行校验:最好的错误回调应该是至少包含错误码,最好包含错误描述(中英文两种),如下面例子:(实例中包含错误码和错误简单描述、详细描述。)
-(void)requestGroupMasterViaGroupId:(NSString *)groupId  
requestSucess:(RequestGroupMasterSucess)success 
requestError:(RequestGroupMasterError) error;
typedef void (^RequestGroupMasterError) (CMIMError * error);//获取群主详情失败回调
//回调的参数是一个CMIMError实例:
@interface CMIMError : NSObject

@property (nonatomic, assign) CMIMErrorCode code;

@property (nonatomic, readwrite, copy) NSString *codeDescription;

@property (nonatomic, readwrite, copy) NSString *detailDescription;

+ (instancetype)errorWithCode:(CMIMErrorCode)aCode;

- (instancetype)initWithCode:(CMIMErrorCode)aCode;

  1. category、第三方库、类的命名、宏定义命名需要独一无二

  2. 头文件、属性暴露合理
    保证代码安全就是保证头文件暴露合理,并且头文件中只暴露开发者需要用到的属性(定义好readonly属性)和接口,这样可以保证开发者不会错误调用其他接口或属性使SDK内部状态或逻辑错乱。

  3. 支持的最低系统
    通过app可能根据用户群体有不同的最低系统支持,例如目前很多app已经不再支持ios8以下系统,但是SDK作为app的内核,需要保证不同客户的需求都能满足,所以SDK应该尽可能保证支持最低系统,一般到iOS6.

  4. 支持模拟器调试
    为了便于开发者调试,需要支持模拟器调试,所以在打包framework时需要有x86和i386版本,并通过lipo指令将二者合并到armv7 v7s arm64中去。

步骤:

  1. 新建一个framework
  2. 参数配置
  • Build Settings >> Dead Code Stripping >> 设置为NO
  • Build Settings >> Strip Debug Symbol During Copy >> 全部设置为NO
  • Build Settings >> Strip Style >> 设置为Non-Global Symbols
  • Build Settings >> Link With Standard Libraries >> 设置为 NO
  • Build Settings >> Mach-O Type >> Static Library
  • 对于Mach-O Type:选择 Static Library 打出来的是静态库
  1. 设置头文件的属性(public/project)
  2. 设置debug和release的地址
  3. 编译
  4. 复制合并

实例

步骤:
新建一个工程名称为“ProjectName”,类型为:Cocoa Touch Static Library
删除与工程名相同的ProjectName.m文件
在ProjectName.h文件中,将所有内容删除,增加:#import < UIKit/UIKit.h>
将UIKit作为依赖库,加入到工程中(点击BuildPhases,展开Link Binary with Libraries这一部分,点击+添加一个新的framework,找到UIKit.framework,点击add添加进来)
在BuildPhases中,点击“new Headers Phase”
将公开的头文件,拖到Public下,将私有的头文件,拖到projcet下
新建一个文件夹,命名为:”folder”,将公共的头文件,放到folder文件夹下
在“Build Setting”中,搜索“public header”,设置Public Headers Folder Path为:include/$(PROJECT_NAME)/folder
进行简化设置(无效代码和debug用符号)
- Dead Code Stripping设置为NO
- Strip Debug Symbol During Copy 全部设置为NO
- Strip Style设置为Non-Global Symbols

  1. 编译运行
    11.创建framework
    • Build Phases栏,选择Editor/Add Build Phase/Add Run Script Build Phase来添加一个新的脚本
set -e
export FRAMEWORK_LOCN="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework"
# Create the path to the real Headers dir
mkdir -p "${FRAMEWORK_LOCN}/Versions/A/Headers"
# Create the required symlinks
/bin/ln -sfh A "${FRAMEWORK_LOCN}/Versions/Current"
/bin/ln -sfh Versions/Current/Headers "${FRAMEWORK_LOCN}/Headers"
/bin/ln -sfh "Versions/Current/${PRODUCT_NAME}" \
"${FRAMEWORK_LOCN}/${PRODUCT_NAME}"
# Copy the public headers into the framework
/bin/cp -a "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}/" \
"${FRAMEWORK_LOCN}/Versions/A/Headers"
  • 选择静态库,编译
    12 创建Aggregate ,命名为“Framework”
    13 将静态库,添加到Aggregate中
    14 添加脚本信息
set -e
# If we're already inside this script then die
if [ -n "$RW_MULTIPLATFORM_BUILD_IN_PROGRESS" ]; then
exit 0
fi
export RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1
RW_FRAMEWORK_NAME=${PROJECT_NAME}
RW_INPUT_STATIC_LIB="lib${PROJECT_NAME}.a"
RW_FRAMEWORK_LOCATION="${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework"
function build_static_library {
    # Will rebuild the static library as specified
    #    build_static_library sdk
    xcrun xcodebuild -project "${PROJECT_FILE_PATH}" \
    -target "${TARGET_NAME}" \
    -configuration "${CONFIGURATION}" \
    -sdk "${1}" \
    ONLY_ACTIVE_ARCH=NO \
    BUILD_DIR="${BUILD_DIR}" \
    OBJROOT="${OBJROOT}" \
    BUILD_ROOT="${BUILD_ROOT}" \
    SYMROOT="${SYMROOT}" $ACTION   
}
function make_fat_library {
    # Will smash 2 static libs together
    #    make_fat_library in1 in2 out
    xcrun lipo -create "${1}" "${2}" -output "${3}"   
}
# 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name
if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]; then
RW_SDK_PLATFORM=${BASH_REMATCH[1]}
else
echo "Could not find platform name from SDK_NAME: $SDK_NAME"
exit 1
fi
# 2 - Extract the version from the SDK
if [[ "$SDK_NAME" =~ ([0-9]+.*$) ]]; then
RW_SDK_VERSION=${BASH_REMATCH[1]}
else
echo "Could not find sdk version from SDK_NAME: $SDK_NAME"
exit 1
fi
# 3 - Determine the other platform
if [ "$RW_SDK_PLATFORM" == "iphoneos" ]; then
RW_OTHER_PLATFORM=iphonesimulator
else
RW_OTHER_PLATFORM=iphoneos
fi
# 4 - Find the build directory
if [[ "$BUILT_PRODUCTS_DIR" =~ (.*)$RW_SDK_PLATFORM$ ]]; then
RW_OTHER_BUILT_PRODUCTS_DIR="${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}"
else
echo "Could not find other platform build directory."
exit 1
fi
# Build the other platform.
build_static_library "${RW_OTHER_PLATFORM}${RW_SDK_VERSION}"
# If we're currently building for iphonesimulator, then need to rebuild
#  to ensure that we get both i386 and x86_64
if [ "$RW_SDK_PLATFORM" == "iphonesimulator" ]; then
build_static_library "${SDK_NAME}"
fi
# Join the 2 static libs into 1 and push into the .framework
make_fat_library "${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \
"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \
"${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}"
# Ensure that the framework is present in both platform's build directories
cp -a "${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}" \
"${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}"
# Copy the framework to the user's desktop
ditto "${RW_FRAMEWORK_LOCATION}" "${HOME}/Desktop/${RW_FRAMEWORK_NAME}.framework"

15 编译,桌面上会生成一个.Framework文件
16 在cmd中检查Framework文件

    - $ cd ~/Desktop/projectName.Framework
    - $  xcrun lipo -info projectName
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生x阅读 15,967评论 3 119
  • 没想到你竟如此的小 简直是一条软体的虫子 当我伸出偌大的双手 却不知如何抱你 你第一次见我, 就面似老人,就满脸皱...
    yummymummy1201阅读 609评论 1 4
  • 刚刚毕业的我们总有种种的选择。 毕业了,该工作了。工作了,该嫁人了… 诸如此类,种种总总。 混沌的我...
    千熹阅读 209评论 0 0
  • 一转眼2018年就只剩下二十多天了,时间就如流水。。。。。 。 对于生命垂危的病人来说,时间就是宝...
    94min呀阅读 165评论 0 0
  • 不好意思,我是不小心点错了,打扰您了
    秋韵阅读 83评论 0 1