美文网首页
Framework制作到打包

Framework制作到打包

作者: Ocean_e553 | 来源:发表于2020-06-15 14:07 被阅读0次

    Framework制作流程

    坑:由于oc的分类会覆盖同名的方法, 在framework中一定要谨慎对待分类

    1. 新建framework 项目

    File > New > Project

    create.png

    2. 需要注意配置的地方

    1.配置sdk运行最低支持的iOS版本
    当sdk是为项目定制时,直接配置跟项目运行版本一致即可;
    当sdk是封装了开放给别的开发者使用时,使用大众版本,如目前大多应用都需要iOS9及以上
    2.静态库or动态库选择
    首先要搞清楚静态库和动态库的区别,这里有介绍
    在这里,我选择了使用静态库的形式,配置:Build Settings > Mach-O Type 可以配置静态库/动态库
    3.Build Phases > Headers
    Public: 需要暴露给外部的.h文件,只有在public中的.h文件,才能被外部直接使用

    3.新建target测试demo

    新建一个target用来测试(File > New > Target > Single View App)


    屏幕快照 2020-06-15 上午10.53.39.png

    如图,Products>MyTestSDK.framework 产物勾选,现在在Demo中就可以引用SDK中的文件了

    #import <MyTestSDK/TestSDKAPI.h>

    屏幕快照 2020-06-15 上午11.04.06.png

    4.集成第三方库

    项目开发中会使用到很多第三方库(AFN,SD等),那么在sdk中集成第三方库的时候最方便的是使用pods来管理了

    在使用的过程中只需要sdk中和使用sdk的项目保持第三方库的版本一致即可。

    1. 创建pod文件,分别添加两个target所依赖的第三方库(注意:使用到的相同第三方库需要保持版本一致)

    2. 因为sdk中使用了pod管理依赖库,所以当sdk开发完成,提供别别人使用时,需要同时提供podspec文件,当别人使用pod集成你的sdk的时候,podspec会指明sdk所依赖的第三方库,pod init的时候会一并安装

    * 使用 pod spec create MyTestSDK 就可以创建一个名为MyTestSDK的podspec文件, 将podspec文件放在项目 ./docs/  目录下
    
    * podspec文件配置需要注意的地方:
    
      1. resource文件,sdk中需要使用的图标需要新建一个bundle,统一放在bundle中管理,
    
        spec.resource = "MyTestSDK.framework/*.bundle" 可以包含sdk中的所有bundle文件
    
    
    
      2. spec.dependency 配置,将sdk中依赖的第三方库全都列出来
    
        spec.dependency 'AFNetworking'
    
        spec.dependency 'MJRefresh'
    
        spec.dependency 'YYModel'
    

    5.framework打包脚本

    sdk的打包跟需要支持的cpu架构有关,当运行的target选模拟器时,编译出来的framework是支持x86_64和i386的;当运行的target选择真机时,编译出来的framework是支持arm64,armv7等架构;我们需要做的是将支持两个架构的可执行文件合并,生成既支持模拟器,也支持真机运行的包,脚本如下:

    
      #!/bin/sh
    
    # 合并在真机和模拟器上编译出的 Framework
    
    # 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
    
    FMK_NAME="MyTestSDK"
    
    # 在工程的根目录创建framework的文件夹.
    
    INSTALL_DIR="./build/MyTestSDK/${FMK_NAME}.framework"
    
    WRK_DIR="./build"
    
    DEVICE_DIR="./build/Build/Products/Release-iphoneos/${FMK_NAME}.framework"
    
    SIMULATOR_DIR="./build/Build/Products/Release-iphonesimulator/${FMK_NAME}.framework"
    
    # Clean两个架构的framework
    
    xcodebuild clean -configuration "Release" -scheme ${FMK_NAME} -workspace ${FMK_NAME}.xcworkspace -sdk iphoneos
    
    xcodebuild clean -configuration "Release" -scheme ${FMK_NAME} -workspace ${FMK_NAME}.xcworkspace -sdk iphonesimulator
    
    # build iphoneos
    
    xcodebuild -configuration "Release" -scheme ${FMK_NAME} -workspace ${FMK_NAME}.xcworkspace -sdk iphoneos build -derivedDataPath ${WRK_DIR}
    
    # build simulator
    
    xcodebuild -configuration "Release" -scheme ${FMK_NAME} -workspace ${FMK_NAME}.xcworkspace -sdk iphonesimulator build -derivedDataPath ${WRK_DIR}
    
    # 删除之前生成的framework
    
    if [ -d "${INSTALL_DIR}" ]
    
    then
    
    rm -rf "${INSTALL_DIR}"
    
    fi
    
    mkdir -p "${INSTALL_DIR}"
    
    cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
    
    # 合成同时支持真机和模拟器架构的 framework
    
    lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"
    
    # 文档, 将生成好的podspec文件拷贝到 framework目录下
    
    cp "./docs/MyTestSDK.podspec" "./build/MyTestSDK/"
    
    #移除多余文件
    
    rm -rf "./build/Build"
    
    rm -rf "./build/Logs"
    
    rm -rf "./build/SourcePackages"
    
    rm -rf "./build/ModuleCache.noindex"
    
    

    6. 最后的项目结构 & 需要提供的产物

    屏幕快照 2020-06-15 上午11.50.51.png

    如图,./build/MyTestSDK/ 目录下的 MyTestSDK.framework 和 MyTestSDK.podspec 就是需要提供给别人使用的

    7. 如何集成导出的framework到项目中使用

    只需要将第6步中导出的产物放到项目目录下,然后使用pod集成就可以了

    1. 在项目的pod 中加入:pod 'MyTestSDK', :path => './MyTestSDK'
    2. pod install, ok 大功告成!

    遇到问题及解决办法

    1. 关于第三方库引用,怎么避免类重名?

    使用pods来管理第三方依赖库

    1. 关于在静态库中使用分类时报错 unrecognized selector sent to instanceunrecognized selector sent to instance?

      如果静态库中有category类,则在使用静态库的项目配置中【Other Linker Flags】需要添加参数【-ObjC]或者【-all_load】。

    2. 不能断点调试framework中的源码?
      调试中发现在framework的源码打断点没有效果, 排查后发现是因为 framework target的 Generate Debug Symbols 设置为NO, 导致的, 改成YES即可 (Generate Debug Symbols 对app target也是相同的效果, 可以缩小framework的包大小, 但是不会生成调试信息, 导致不能断点调试)

    3. 使用lipo合并真机&模拟器framework时报错: have the same architectures (arm64) and can't be in the same fat output file
      在Xcode12之前:
      编译模拟器静态库支持i386 x86_64两架构
      编译真机静态库支持armv7 arm64两架构
      使用lipo -create -output命令可以将两个库合并成一个支持模拟器和真机i386 x86_64 armv7 arm64四种架构的静态库。

    但是Xcode12编译的模拟器静态库也支持了arm64,导致出现真机库和模拟器库不能合并的问题。

    ---> 解决: 在 Build Settings -> Excluded Architectures 设置 Any iOS Simulator SDK : arm64
    在打包时, 模拟器上的库就不会在支持arm64架构了, 合并也就没问题了
    ---> 解决2: 可以使用 lipo xxx.a -remove arm64 -output xxx_no64.a, 将模拟器静态库中的arm64移除, 然后再进行合并

    1. 问题4中连带出的问题, 经过问题4中打包出来的framework同时支持了 真机:arm64、armv7, 模拟器:i386、x86_64 这4种架构, 但是在Xcode13(目前使用的13)或以上使用时, 在模拟器上编译会报错: in XXX.a(XXXXXXX.o), building for iOS Simulator, but linking in object file built for iOS, for architecture arm64
      ---> 模拟器运行需要支持模拟器的arm64, 但是静态库中没有, 所以报错了
      ---> 解决: 在 Build Settings -> Excluded Architectures 设置 Any iOS Simulator SDK : arm64 (Debug模式, 因为运行的时候一般是设置的debug)

    相关文章

      网友评论

          本文标题:Framework制作到打包

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