iOS架构-静态库.framework手动打包及脚本化打包(5)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shifang07/article/details/89372877

引用一张博客的图片来理解下基本知识(http://www.cnblogs.com/oc-bowen/p/7478461.html)

我们可以看出.a的封装和.framework的封装差不多,也有模拟器和真机合并的过程,通过上边的图片我们可以看出.a 和.framework的区别,就是.a+.h+soureFile=.framework。可以看出我们直接封装.framework其实是最好的。那么我们就来看看framework怎么封装的。

步骤

1、打开Xcode,新建工程名:MySDK在这里插入图片描述
2、创建测试类:ShowInfo

ShowInfo.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface ShowInfo : NSObject

+ (void)show;
    
@end

NS_ASSUME_NONNULL_END

ShowInfo.m

#import "ShowInfo.h"

@implementation ShowInfo

+ (void)show {
    NSLog(@"-----ShowInfo------");
}

@end
3. framework修改target配置

1.Mach-O type 修改为 static framework
2.暴露的头文件放在public下面
3.在MySDk.h中将你所有要公开的.h引入。(必须是公开的,否则无法引用)
4.需要把Build Active Architecture Only修改为NO,否则生成的静态库就只支持当前选择设备的架构。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

1.手动打包

1、选中模拟器,command+B
2、选中真机,command+B
3、在finder中找到framework文件
4、终端合并MySDK

Last login: Thu Apr 18 19:58:24 on ttys005
lzz-Mac-mini:~ suning$ lipo -create /Users/suning/Desktop/VideoPlayerFramework/MySDK/Build/Products/Debug-iphoneos/MySDK.framework/MySDK /Users/suning/Desktop/VideoPlayerFramework/MySDK/Build/Products/Debug-iphonesimulator/MySDK.framework/MySDK -output /Users/suning/Desktop/VideoPlayerFramework/MySDK/Build/Products/MySDK
lzz-Mac-mini:~ suning$ lipo -info /Users/suning/Desktop/VideoPlayerFramework/MySDK/Build/Products/MySDK
Architectures in the fat file: /Users/suning/Desktop/VideoPlayerFramework/MySDK/Build/Products/MySDK are: x86_64 arm64 
lzz-Mac-mini:~ suning$ 

在这里插入图片描述

合并成功,将Projects 文件夹下合并的 MySDK copy 到 MySDK.framework下替换MySDK ,后形成最终的目标 MySDK.framework 包在这里插入图片描述导入demo 使用

2.脚本化打包(shell)

.framework 也可以像 .a 一样将打包过程自动化,用脚本来实现自动打包
参考 iOS架构-静态库.a的脚本化打包及使用(3) 由于之前有过 .a 的脚本化打包的经验,那么这里就非常简单了。

那么就用脚本来把上面手动打包的过程实现一下:

  1. iOS架构-静态库.a的脚本化打包及使用(3) 中的 Script.sh 的脚本copy 到和MySDk.xcodeproj 同一目录下
    在这里插入图片描述在这里插入图片描述
  2. 脚本之行后形成的目标文件 MySDK.framework
    在这里插入图片描述
  3. 修改后的脚本,代码有注释
#!/bin/sh

#  Script.sh
#  VideoPlayerLib
#
#  Created by lzz on 2019/4/10.
#  Copyright © 2019 lzz. All rights reserved.

#注意:脚本目录和xxxx.xcodeproj要在同一个目录,如果放到其他目录,请自行修改脚本。
#要build的target名
target_Name=MySDK
echo "target_Name=${target_Name}"

#工程名
project_name=$target_Name
echo "project_name=${project_name}"

#打包模式 Debug/Release 默认是Release
development_mode=Release


#当前脚本文件所在的路径 $(pwd)
SCRIPT_DIR=$(pwd)
echo "======脚本路径=${SCRIPT_DIR}======"

#工程路径
#PROJECT_DIR=${SCRIPT_DIR} 和下面写法也样
PROJECT_DIR=$SCRIPT_DIR
echo "======工程路径=${PROJECT_DIR}======"

#build之后的文件夹路径
build_DIR=$SCRIPT_DIR/Build
echo "======Build路径=${build_DIR}======"

#真机build生成的.framework 文件路径
DEVICE_DIR=${build_DIR}/${development_mode}-iphoneos/${project_name}.framework

#真机build生成的sdk文件路径
DEVICE_DIR_A=${build_DIR}/${development_mode}-iphoneos/${project_name}.framework/${project_name}
echo "======真机.framework路径=${DEVICE_DIR_A}======"

#模拟器build生成的sdk文件路径
SIMULATOR_DIR_A=${build_DIR}/${development_mode}-iphonesimulator/${project_name}.framework/${project_name}
echo "======模拟器.framework路径=${SIMULATOR_DIR_A}======"



#目标文件夹路径(也就SDK的文件:.framework文件 和 bundle文件)
INSTALL_DIR=${build_DIR}/Products/${project_name}
echo "======SDK的文件夹路径=${INSTALL_DIR}======"

#目标 sdk 路径
INSTALL_DIR_A=${build_DIR}/Products/${project_name}/${project_name}.framework/${project_name}
echo "======目标sdk路径=${INSTALL_DIR}======"



#判断build文件夹是否存在,存在则删除
#rm -rf 命令的功能:删除一个目录中的一个或多个文件或目录
if [ -d "${build_DIR}" ]
then
rm -rf "${build_DIR}"
fi


#判断目标文件夹是否存在,存在则删除该文件夹
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi


#创建目标文件夹
mkdir -p "${INSTALL_DIR}"



echo "======盒子已经准备好了,开始生产.a 并合成装到盒子里吧======"

#build之前clean一下
xcodebuild -target ${target_Name} -configuration ${development_mode} -sdk iphonesimulator clean

xcodebuild -target ${target_Name} -configuration ${development_mode} -sdk iphoneos clean

#模拟器build
xcodebuild -target ${target_Name} -configuration ${development_mode} -sdk iphonesimulator

#真机build
xcodebuild -target ${target_Name} -configuration ${development_mode} -sdk iphoneos


#1.复制真机的${project_name}.framework到目标文件夹
#使用-R参数可实现递归功能,即所有子目录中的文件与目录均拷贝
cp -R "${DEVICE_DIR}" "${INSTALL_DIR}"

#2.删除真机 INSTALL_DIR 中原来的MySDK 文件
#判断目标文件夹是否存在,存在则删除该文件夹
if [ -f "${INSTALL_DIR_A}" ]
then
rm -f "${INSTALL_DIR_A}"
fi



#合成模拟器和真机 MySDK 文件替换目标文件夹中${project_name}.framework 下的 真机 MySDK 文件
lipo -create "${DEVICE_DIR_A}" "${SIMULATOR_DIR_A}" -output "${INSTALL_DIR_A}"

echo "======合成结束======"



# -f 判断文件是否存在
if [ -f "${INSTALL_DIR_A}" ]
then
echo "======验证合成包是否成功======"
lipo -info "${INSTALL_DIR_A}"
fi


#打开目标文件夹
open "${INSTALL_DIR}"

  1. 终端执行脚本
Last login: Mon Apr 22 09:02:10 on console
lzz-Mac-mini:~ suning$ cd /Users/suning/Desktop/VideoPlayerFramework/MySDK 
lzz-Mac-mini:MySDK suning$ ./Script.sh 

结果

** BUILD SUCCEEDED **

======合成结束======
======验证合成包是否成功======
Architectures in the fat file: /Users/suning/Desktop/VideoPlayerFramework/MySDK/Build/Products/MySDK/MySDK.framework/MySDK are: armv7 armv7s i386 x86_64 arm64 
lzz-Mac-mini:MySDK suning$ 

让库支持armv7s
在这里插入图片描述

  1. 最终就形成了第2步
  1. 脚本之行后形成的目标文件 MySDK.framework

使用:我们就可以把上面路径下的 MySDK.framework 文件夹丢给客户了,然后尼?然后就可以喝喝茶,刷刷手机了!岂不乐哉!使用方法和(一)一样。

方法二:可以在公共新建Target:Aggregate
在Aggregate里面添加运行脚本,这里有个博客介绍的很详细
参考:http://www.cnblogs.com/oc-bowen/p/7478461.html

注意:

1. Debug和Release版本

 一般来说, 我们应该发布的是release版本.

 debug:调试版本, 系统本身也会有一些调试代码. 此版本体积会稍大, 运行会稍慢

 release: 发布版本, 系统会去除调试代码, 体积变小, 运行速度变快. 对用户来说没有明显的感觉

 

 2. 到底要不要合成多个架构

 真机和模拟器合成的好处: 调试会非常方便, 缺点是体积会变大(一种架构就占用一部分体积).

 真机和模拟器不合成的好处:体积小,  缺点是调试稍显麻烦.

 

 3. 资源包的问题
  
  a:静态库的资源, 都应该放到后缀为.bundle的文件夹中 --> 避免文件重名被覆盖, 导致加载资源文件出错
  
  b:静态库打包时, 并不会打包资源文件 --> 需要手动拖出去

猜你喜欢

转载自blog.csdn.net/shifang07/article/details/89372877
今日推荐