什么是SDK?
软件开发工具包(缩写:SDK,英语全称:Software Development Kit),一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。
在OC的开发中,我们涉及到的一般是静态库(.a)或者动态库(.framework)。(注:不是所有的.framework就一定是动态库)
静态库与动态库的区别?
- 静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。表现形式为 .a和.framework。
- 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。 表现形式为 .dylib和.framework。
a与.framework有什么区别?
.a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。 .a文件不能直接使用,至少要有.h文件配合(微信的SDK就是这种形式),.framework文件可以直接使用。 .a + .h + sourceFile = .framework。 建议用.framework。再者 静态方式开发,一直是iOS SDK开发的主流方式。
静态库.framework开发:
- 新建SDK .framework项目:
- File -> New -> Project -> IOS -> Framework & Library -> Framework 新建.framework SDK
- 填写SKD名: 填写SKD名
- 选择SDK保存位置。
- 设置配置:
- TARGETS -> General -> Deployment Info,设置支持iOS系统的最低版本和支持的设备。 支持版本及设备
- TARGETS -> Build Settings -> Linking -> Mach-O Type 更改为Static Library(静态库),默认为Dynamic Library(动态库)。 更改为静态库
- TARGETS -> Build Settings -> Linking -> Other Linker Flage 添加-Objc标志(在静态库中慎用Category,如果使用了Category就必须在SDK和SDK使用的项目中都要添加该标识,否则会报unrecognized selector sent to instance的异常) Category 必填
- TARGETS -> Build Settings -> Architectures 添加armv7s(Xcode6之后,默认不支持armv7s,如果需要添加SDK的工程是支持armv7s,那将会有冲突) 支持armv7s
- TARGETS -> Build Settings -> Build Options -> Enable Bitcode设置为No,默认为YES。 Enable Bitcode
- 添加要制作成SDK的代码。
- 配置公开文件:
- TARGETS -> Build Phases -> Headers 公开文件
- 在SDK的.h头文件中引用公开的文件:
//#import <SDK名字/公开文件名字.h>
#import <ETCOnlineServices/WebViewController.h>
- SDK.framework打包:
模拟器 iPhone5s 以下是 i386 架构,iPhone5s 及以上是 x86_64 架构。如果想同时支持 i386 和 x86_64,设置:TARGETS -> Build Settings —> Architectures —> Build Active Architecture Only —> NO。
真机iPhone5s 以下是 armv7 架构,iPhone5s 及以上是 arm64 架构。- Product -> Scheme -> Edit Scheme -> Run -> Build Configuration修改为release Build Configuration.png
- 生成模拟器和真机使用的framework包:
- 真机包:模拟器选项中,选择Generic IOS Device, Command + B生成真机包。
- 模拟器包:模拟器选项中,选择任意模拟器, Command + B生成模拟器包。
- 查看真机包和模拟器包的位置:项目中的Product文件夹中选择SDK文件,右击选择Show in Finder
- 通过终端命令行查看包是真机包还是模拟器包:lipo -info framework路径 SDK路径 lipo -info
终端输出为:armv7 arm64 是真机架构;i386 x86_64 是模拟器架构。
- 合并framework的真机包和模拟器包:
- 通过终端命令行合并:lipo -create 真机路径 模拟器路径 -output 真机路径 合并
- 通过脚本语言合并:
- TARGETS -> Build Phases 点击加号创建Run Script Run Script
-
Run Script中添加脚本运行代码:
Run Script
command + B 分别生成真机和模拟器包,再次按command + B合并真机包和模拟器包。脚本代码如下:
if [ "${ACTION}" = "build" ]
then
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework
DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"
lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"
#open "${DEVICE_DIR}"
open "${SRCROOT}/Products"
fi
- lipo -info查看合并后的包支持的架构: 合并后
静态库.a开发:
- 新建SDK .a项目:
- File -> New -> Project -> IOS -> Framework & Library -> Static Library image
- 填写SDK名: image
- 选择SDK保存位置。
- SDK中会生成.h和.m文件,.m文件可以直接删除。
- SDK所支持的最低版本:PROJECT -> info -> Deployment Target
- 添加需要生成SDK的代码。
- 在SDK的.h头文件中引用公开调用的头文件:
//#import "公开文件名.h"
#import "WebViewController.h"
- Targets -> Build Settings -> Copy Files 添加公开的.h文件。并且清空Subpath中的路径,如果不清空,.a文件和.h文件不在同一个文件夹中。 公开文件.h
- SDK.a打包:
- Product -> Scheme -> Edit Scheme -> Run -> Build Configuration修改为release Edit Scheme
- 生成模拟器和真机使用的framework包:
- 真机包:模拟器选项中,选择Generic IOS Device, Command + B生成真机包。
- 模拟器包:模拟器选项中,选择任意模拟器, Command + B生成模拟器包。
- 查看真机包和模拟器包的位置:项目中的Product文件夹中选择SDK文件,右击选择Show in Finder
- 通过终端命令行查看包是真机包还是模拟器包:lipo -info SDK.a路径 .a的路径 终端
终端输出为:arm64 是真机架构;x86_64 是模拟器架构。
- 合并framework的真机包和模拟器包:
- 通过终端命令行合并:lipo -create 真机路径 模拟器路径 -output 真机路径 合并
Bundle资源文件创建:
手动创建Bundle资源:
- 创建一个文件夹,把这个文件夹的后缀改成.bundle image
- 右击该文件 -> 显示包内容: image
- 把资源文件直接copy到该文件中: image
- Bundle加入SDK中: 添加Bundle
- 从Bundle资源文件中读取内容:
- Html本地文件的读取:
NSString *htmlFilePath = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:@"Bundle名.bundle/transpay/index.html"];
NSURL * htmlFileURL = [NSURL URLWithString:htmlFilePath];
NSURLRequest * request = [NSURLRequest requestWithURL:htmlFileURL];
[self.webView loadRequest:request];
- 图片/视频资源的读取:
NSString *imageFilePath = [[[NSBundle mainBundle]resourcePath] stringByAppendingPathComponent:@"Bundle名.bundle/image/xingkong.png"];
imageView.image = [UIImage imageWithContentsOfFile:imageFilePath];
- Storyboard、xib,需要在对应的视图控制器中添加以下代码:
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
NSBundle *bundle = [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"Bundle名.bundle"]];
if (bundle) {
// 如果是storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"你的storyboard名称(例如Main)" bundle:bundle];
self = [storyboard instantiateViewControllerWithIdentifier:@"你在storyboard中设置的此视图控制器的id"];
return self;
// 如果是xib
self = [super initWithNibName:@"当前控制器的名称" bundle:bundle];
return self;
}
return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
-
把生成的SDK文件和Bundle资源文件放在同一个文件夹中:
image.png
Bundle文件创建和使用完成。
创建的SDK中使用其他的SDK
- 往SDK中拖入另一个SDK: 添加SDK
- 在合适的地方,添加这个引入的SDK的相关代码。
Bundle 和 其他的SDK都要和创建的SDK放在同一个文件夹,然后拖入要使用的项目中,如果该项目中的SDK和创建的SDK中的引用的SDK重复,那么就只要保持存在一个就好了。
网友评论