美文网首页
iOS 【私有库】模拟真机合并

iOS 【私有库】模拟真机合并

作者: NJ_墨 | 来源:发表于2017-09-15 11:00 被阅读78次

下面我们用系统自带的来新建.framework.然后再添加一个依赖库 AFNetworking

  1. xcode的菜单栏 File -> New Project 建立一个名为 YohunlUtilsLib 的Cocoa Touch Framework的工程. 将Target 改为 7.0(由于现在大多数应用都还要支持7.0sdk,故此处我们修改为支持7.0)
    这时候,编译一下,你可能会遇到警告

我们要修改 Mach-O Type.从默认的Dynamic Library 改为 Static Library,再编译,警告消失
Static Library 支持IOS8.0 sdk以下的,从目前来看,大多数工程都还要支持7.0 sdk,所以我们最常用的就是Static Library

命令行,进入目录下 pod init 建立一个podfile文件,因为我们制作的.framework需要用到AFNetworking网络库 PS:你也可以用任意的方式建立这个podfile文件
打开它,因为我采用 pod init命令建立的,打开后你会发现它已经有内容了
再执行 pod install 建立依赖

platform :ios, ‘8.0’
inhibit_all_warnings!

target 'OSUtilsFirstLib' do

pod 'AFNetworking'

end

打开工程,添加一个类TestMode,在其中添加方法(同理添加类AdvModel)

//TestMode.m
#import <Foundation/Foundation.h>

@interface TestMode : NSObject

+ (NSString *)testName:(NSString *)name;
@end

//TestMode.m
#import "TestMode.h"

@implementation TestMode

+ (NSString *)testName:(NSString *)name {
   return [NSString stringWithFormat:@"test:----%@",name];
}
@end

//创建一个带网络请求的 类

#import <Foundation/Foundation.h>
@interface YONetwork : NSObject
// 需要 pod AFNetworking

- (void)getGithubReposForUser:(NSString*)user withSuccess:(void(^)(id responseObject))success failure:(void(^)(NSError*error))failure;
- (void)test;
@end

//  YONetwork.m
#import "YONetwork.h"
#import "AFNetworking.h"

@implementation YONetwork

- (void)getGithubReposForUser:(NSString*)user withSuccess:(void(^)(id responseObject))success failure:(void(^)(NSError*error))failure
{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager GET:@"https://www.baidu.com" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
        
    }
         success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
             NSLog(@"这里打印请求成功要做的事");
         }
         failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull   error) {
             NSLog(@"%@",error);  //这里打印错误信息
         }];
}
- (void) test {
    [self getGithubReposForUser:@"occ"withSuccess:^(id responseObject) {
        NSLog(@"getGithubReposForUser response = %@",responseObject);
    } failure:^(NSError*error) {
        NSLog(@"getGithubReposForUser error = %@",error);
    }];
}
@end

私有库里的文件头设置

//  OSUtilsFirstLib.h
#import <UIKit/UIKit.h>
FOUNDATION_EXPORT double OSUtilsFirstLibVersionNumber;
FOUNDATION_EXPORT const unsigned char OSUtilsFirstLibVersionString[];
// 设置开放的头文件
#import  <OSUtilsFirstLib/YONetwork.h>
6DBF4EB1-E565-42C0-9329-02EE38880820.png

编译运行 (command + B),生成相应的.framework文件(先选择模拟器,编译,在选择真机,编译)
~/资源库/Developer/Xcode/DerivedData/ 找到 OSUtilsFirstLib 或 在库上右键Show in Finder

434C53BB-3D81-4B73-9B35-DD899E2DB77E.png

可以看到目录结构如下:

B672600D-38AE-4CCF-8613-C61D0028A932.png

查看静态库支持的CPU架构

➜  Release-iphoneos git:(master) ✗ lipo -info OSUtilsFirstLib.framework/OSUtilsFirstLib
Architectures in the fat file: OSUtilsFirstLib.framework/OSUtilsFirstLib are: armv7 arm64 

说明我们生成的真机framework: OSUtilsFirstLib.framework 包含了两种架构 armv7 arm64

我们使用命令来合并我们生成的真机和模拟器的framework

1、建立一个新的target(Aggregate)


54F73597-C916-4B83-AC01-89A6B6158684.png

2、选择Target ——> 【+】号———>【New Run Script Phase]


64FF1B25-5B0A-428D-ADAC-26631CFE6C6B.png

添加如下的合并模拟器和真机的脚本(【Run Script 】添加脚本)

4749B363-E0AE-4BCA-B2F2-F22EFE7DBDD5.png

私有库.framework合并(coocaPods项目)

if [ "${ACTION}" = "build" ]
then


####### PROJECT_NAME = OSUtilsFirstLib
#要build的target名
target_Name=${PROJECT_NAME}
echo "target_Name=${target_Name}"


######## SRCROOT = /Users/occ/Desktop/组件化/私有库2/OSUtilsFirstLib2
#build之后的文件夹路径
build_DIR=${SRCROOT}/build
echo "build_DIR=${build_DIR}"

#真机build生成的.framework文件路径
BUILD_DEVICE_DIR_F=${build_DIR}/Build/Products/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
echo "BUILD_DEVICE_DIR_F=${BUILD_DEVICE_DIR_F}"

#模拟器build生成的.framework文件路径
BUILD_SIMULATOR_DIR_F=${build_DIR}/Build/Products/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
echo "BUILD_SIMULATOR_DIR_F=${BUILD_SIMULATOR_DIR_F}"


#合并目标文件夹路径
RESULT_DIR_F=${SRCROOT}/Products/${PROJECT_NAME}
echo "RESULT_DIR_F=${RESULT_DIR_F}"

#合并目标路径(合并的包替换目标文件.framework中对应的包)
#└── OSUtilsFirstLib.framework
#    ├── Headers
#    ├── Info.plist
#    ├── Modules
#    ├── OSUtilsFirstLib (替换这个)
#    └── PrivateHeaders

RESULT_DIR_F_A=${SRCROOT}/Products/${PROJECT_NAME}/${PROJECT_NAME}.framework/${PROJECT_NAME}
echo "RESULT_DIR_F_A=${RESULT_DIR_F_A}"

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

#判断合并目标文件夹是否存在,存在则删除该文件夹
if [ -d "${RESULT_DIR_F}" ]
then
rm -rf "${RESULT_DIR_F}"
fi
#创建目标文件夹
mkdir -p “${RESULT_DIR_F}"

#build之前clean一下
# ============================== build之前clean一下 =============================#

xcodebuild -target ${target_Name} clean

####PROJECT_FILE_PATH = /Users/occ/Desktop/组件化/私有库2/OSUtilsFirstLib2/OSUtilsFirstLib.xcodeproj
#### CONFIGURATION = Debug

# ============================== build(带有Pods的) =============================#
#模拟器build
xcodebuild -workspace "${target_Name}.xcworkspace" -scheme "${target_Name}" -configuration "${CONFIGURATION}" -sdk iphonesimulator -derivedDataPath "${build_DIR}"

#真机build
xcodebuild -workspace "${target_Name}.xcworkspace" -scheme "${target_Name}" -configuration "${CONFIGURATION}" -sdk iphoneos -derivedDataPath "${build_DIR}"

# 直接换成模拟与真机的
#xcodebuild -workspace "${target_Name}.xcworkspace" -scheme "${target_Name}" -configuration "${CONFIGURATION}" -derivedDataPath "${build_DIR}" ONLY_ACTIVE_ARCH=NO || exit

#复制真机build的framework文件到目标文件夹
cp -R "${BUILD_DEVICE_DIR_F}" “${RESULT_DIR_F}"

# ======================= 合成模拟器和真机.framework包=========================== #
echo "真机build生成的.framework文件路径=${BUILD_DEVICE_DIR_F}/${PROJECT_NAME}"
echo "模拟器build生成的.framework文件路径=${BUILD_SIMULATOR_DIR_F}/${PROJECT_NAME}"

#/Users/occ/Desktop/组件化/私有库2/OSUtilsFirstLib2/build/Build/Products/Release-iphoneos/OSUtilsFirstLib.framework/OSUtilsFirstLib
#/Users/occ/Desktop/组件化/私有库2/OSUtilsFirstLib2/build/Build/Products/Release-iphonesimulator/OSUtilsFirstLib.framework/OSUtilsFirstLib


#(合并的包替换目标文件.framework中对应的包)
#└── OSUtilsFirstLib.framework
#    ├── Headers
#    ├── Info.plist
#    ├── Modules
#    ├── OSUtilsFirstLib (替换这个)
#    └── PrivateHeaders
lipo -create "${BUILD_DEVICE_DIR_F}/${PROJECT_NAME}" "${BUILD_SIMULATOR_DIR_F}/${PROJECT_NAME}" -output "${RESULT_DIR_F_A}"

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

静态库.a文件合成(非coocaPods项目)

if [ "${ACTION}" = "build" ]
then


#要build的target名
target_Name=${PROJECT_NAME}
echo "target_Name=${target_Name}"


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

#真机build生成的头文件的文件夹路径
DEVICE_DIR_INCLUDE=${build_DIR}/Release-iphoneos/include/${PROJECT_NAME}
echo "DEVICE_DIR_INCLUDE=${DEVICE_DIR_INCLUDE}"

#真机build生成的.a文件路径
DEVICE_DIR_A=${build_DIR}/Release-iphoneos/lib${PROJECT_NAME}.a
echo "DEVICE_DIR_A=${DEVICE_DIR_A}"

#模拟器build生成的.a文件路径
SIMULATOR_DIR_A=${build_DIR}/Release-iphonesimulator/lib${PROJECT_NAME}.a
echo "SIMULATOR_DIR_A=${SIMULATOR_DIR_A}"


#目标文件夹路径
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}
echo "INSTALL_DIR=${INSTALL_DIR}"

#目标头文件文件夹路径
INSTALL_DIR_Headers=${SRCROOT}/Products/${PROJECT_NAME}/Headers
echo "INSTALL_DIR_Headers=${INSTALL_DIR_Headers}"

#目标.a路径
INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/lib${PROJECT_NAME}.a
echo "INSTALL_DIR_A=${INSTALL_DIR_A}"

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

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


#build之前clean一下
xcodebuild -target ${target_Name} clean

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

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

#复制头文件到目标文件夹
cp -R "${DEVICE_DIR_INCLUDE}" "${INSTALL_DIR_Headers}"

#合成模拟器和真机.a包
lipo -create "${DEVICE_DIR_A}" "${SIMULATOR_DIR_A}" -output "${INSTALL_DIR_A}"

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

静态库.a文件合成(coocaPods项目)

if [ "${ACTION}" = "build" ]
then

#要build的target名
target_Name=${PROJECT_NAME}
echo "target_Name=${target_Name}"

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

#真机build生成的头文件的文件夹路径
DEVICE_DIR_INCLUDE=${build_DIR}/Build/Products/Release-iphoneos/include/${PROJECT_NAME}
echo "DEVICE_DIR_INCLUDE=${DEVICE_DIR_INCLUDE}"

#真机build生成的.a文件路径
DEVICE_DIR_A=${build_DIR}/Build/Products/Release-iphoneos/lib${PROJECT_NAME}.a
echo "DEVICE_DIR_A=${DEVICE_DIR_A}"

#模拟器build生成的.a文件路径
SIMULATOR_DIR_A=${build_DIR}/Build/Products/Release-iphonesimulator/lib${PROJECT_NAME}.a
echo "SIMULATOR_DIR_A=${SIMULATOR_DIR_A}"


#目标文件夹路径
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}
echo "INSTALL_DIR=${INSTALL_DIR}"

#目标头文件文件夹路径
INSTALL_DIR_Headers=${SRCROOT}/Products/${PROJECT_NAME}/Headers
echo "INSTALL_DIR_Headers=${INSTALL_DIR_Headers}"

#目标.a路径
INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/lib${PROJECT_NAME}.a
echo "INSTALL_DIR_A=${INSTALL_DIR_A}"

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

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


#build之前clean一下
xcodebuild -target ${target_Name} clean

#模拟器build
xcodebuild -workspace "${target_Name}.xcworkspace" -scheme "${target_Name}" -configuration Release -sdk iphonesimulator -derivedDataPath "${build_DIR}"

#真机build
xcodebuild -workspace "${target_Name}.xcworkspace" -scheme "${target_Name}" -configuration Release -sdk iphoneos -derivedDataPath “${build_DIR}"

#复制头文件到目标文件夹
cp -R "${DEVICE_DIR_INCLUDE}" "${INSTALL_DIR_Headers}"

#合成模拟器和真机.a包
lipo -create "${DEVICE_DIR_A}" "${SIMULATOR_DIR_A}" -output "${INSTALL_DIR_A}"

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

对于添加的脚本,其中用到了很多的 xcode预定义的变量,这些变量怎么来的呢?你可以在命令行下, 输入

➜  OSUtilsFirstLib git:(master) ✗ xcodebuild -workspace OSUtilsFirstLib.xcworkspace -scheme OSUtilsFirstLib -sdk iphonesimulator -configuration Debug -showBuildSettings > xcodebuild_showBuildSettings.txt

来将所有的xcode预定义变量都导入到文本xcodebuild_showBuildSettings.txt 中,然后你就可以选用你需要的啦

一般都应该合并release模式的,而不是debug模式的framework,设置好后: ccmmand+B 编译

BF13290E-E3D6-4C55-BAA6-093FDEB3E0E2.png

测试:新建一个项目,将合并的OSUtilsFirstLib.framework拖入到项目中,测试


091523FD-D164-4A4F-B027-74C65F7B1C37.png

当我们使用 Dynamic Library模式(只有iOS8.0及以上才支持)的时候.如同普通文件一样添加到示例工程中去的话,
直接运行,会出现提示:,可能会报错:Reason: image not found

选择 TARGETS [SOTestDemo] ——> Build Phases ——> 【+】号 ——> 【New Copy..】——>【Copy Filses】 添加库


4136D563-3F08-4EE0-907F-408D3A244529.png

终端命令

打包Framework,测试时:
1、用模拟器打包,测试时只能跑在模拟器
2、用真机打包,测试时只能跑在真机

解决如下:
1、打开终端
2、输入 lipo -create 【模拟器打包path】 【真机打包path】 -output 【导出兼容版本path】

实现步骤:
1、右击打开包,在finder显示

78429194-A085-4C61-BC7B-5328D177F27C.png

2、正常我们会看到这些,(一般习惯设置成Release环境下),重点是第三个红框,这就是我们要合并的东西。


BB10184A-D40D-4EF0-92C0-17734B19F603.png

3、创建合并文件夹combine
4、合并

F89B0C94-4A07-455E-BBAF-5C8DE81EE019.png
lipo -create /Users/occ/Library/Developer/Xcode/DerivedData/OSUtilsFirstLib-absygfecsqswxbfursvwqzmxpzpo/Build/Products/Release-iphoneos/OSUtilsFirstLib.framework/OSUtilsFirstLib /Users/occ/Library/Developer/Xcode/DerivedData/OSUtilsFirstLib-absygfecsqswxbfursvwqzmxpzpo/Build/Products/Release-iphonesimulator/OSUtilsFirstLib.framework/OSUtilsFirstLib -output /Users/occ/Library/Developer/Xcode/DerivedData/OSUtilsFirstLib-absygfecsqswxbfursvwqzmxpzpo/Build/Products/combine/OSUtilsFirstLib 

5、合并文件夹下会出现一个文件

89718EE2-53D3-4D5C-A2B2-2F41A1D6D1CE.png

私有库合并

相关文章

网友评论

      本文标题:iOS 【私有库】模拟真机合并

      本文链接:https://www.haomeiwen.com/subject/qwkssxtx.html