美文网首页iOS
iOS Framework 实用开发技巧

iOS Framework 实用开发技巧

作者: ChinaChong | 来源:发表于2020-07-18 16:58 被阅读0次

    时间:2020年7月

    版本:Xcode 11.5 (11E608c)

    语言:Objective-C

    作者:非著名程序员

    介绍自己在实际开发SDK过程中遇到的实际问题,以及解决方案。仅供参考。

    1. Framework与主工程(App)实时联调
    2. Framework、主工程(App)以及 Pod 等三个工程实时联调
    3. 使用脚本合并真机、模拟器等多种架构的Framework
    4. Framework中使用.bundle资源文件
    5. Framework中使用Category
    6. Framework支持bitcode

    一、Framework与主工程(App)实时联调

    ① 为什么需要实时联调?

    首先说明,Framework指的是我们自己开发的Framework(SDK),主工程(App)泛指那些要接入你的SDK的App。

    朕之前在写SDK进行调试的时候都是先创建一个Framework的工程,代码都写完之后打包成Framework静态库,然后再把Framework拉到App的主工程中去验证功能。这样的调试方式没什么不可以,但是非常的浪费时间,需要一遍又一遍的打包Framework,而且Framework中的问题不可以打断点排查。

    ② 实时联调最终要达到什么效果?

    实时联调最终要达到的效果是:仅需要让主工程跑起来就可以同时调试Framework和App两个工程的代码

    这样一来,Framework不用每次都去打包一遍,再拖进App工程。大致的流程可以理解为:先build Framework,Framework编译完成后自动添加到App中,最后build App。

    ③ 干

    1. 创建App工程,命名为RealDemo

    image.png

    2. 创建Framework工程,命名为RealSDK

    image.png

    注意路径!

    image.png

    3. 设置Framework工程的Build Settings

    image.png image.png image.png

    4. 创建WorkSpace,命名为RealDemo

    image.png

    注意路径!

    image.png

    5. 连接Framework工程和App工程

    打开 RealDemo.xcworkspace,毫无疑问,空空如也


    image.png

    直接把需要连接的Framework工程和App工程拖进来即可


    image.png

    哎~你瞧,这就有了


    image.png

    6. 把Framework添加到App工程中

    image.png image.png

    添加完是这样的


    image.png



    有过SDK开发经验的道友到这里应该已经看明白了,所谓实时联调说白了就是用WorkSpace把两个工程连接起来而已,跟Pod的原理有几分相似。

    继续,咱们验证一下

    7. 给Framework加点功能

    增加一个RealDog类,定义一个eat方法,实现里面打印一句话“吃骨头”。最后在SDK的公开头文件RealSDK.h中集中引用一下。

    image.png
    // RealDog.h
    
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface RealDog : NSObject
    
    - (void)eat;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    // RealDog.m
    
    #import "RealDog.h"
    
    @implementation RealDog
    
    - (void)eat {
        NSLog(@"吃骨头");
    }
    
    @end
    
    
    // RealSDK.h
    
    #import <Foundation/Foundation.h>
    
    //! Project version number for RealSDK.
    FOUNDATION_EXPORT double RealSDKVersionNumber;
    
    //! Project version string for RealSDK.
    FOUNDATION_EXPORT const unsigned char RealSDKVersionString[];
    
    // In this header, you should import all the public headers of your framework using statements like #import <RealSDK/PublicHeader.h>
    
    
    #import <RealSDK/RealDog.h>
    
    

    8. 在App的ViewController调用一下SDK的方法

    // ViewController.m
    
    #import "ViewController.h"
    #import <RealSDK/RealSDK.h>
    
    @interface ViewController ()
    
    @property (nonatomic, strong) RealDog *dog;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.dog = [[RealDog alloc] init];
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        [self.dog eat];
    }
    
    @end
    

    OK,实时联调到此结束。

    二、Framework、主工程(App)以及 Pod 等三个工程实时联调

    再加上Pod之后,三个工程实时联调其实也没什么难的,只要保证刚刚第一部分的工程文件夹层级关系,然后直接创建Podfile,pod install即可。

    image.png

    注意:此处Podfile里面的target是RealDemo!

    platform :ios, '10.0'
    
    target 'RealDemo' do
      
      pod 'AFNetworking', '~> 4.0.1'
      
    end
    

    三个工程顺利组到一起,全部可实时联调。

    image.png

    三、使用脚本合并真机、模拟器等多种架构的Framework

    1. 添加一个Aggregate Target。路径:RealSDK Project -> TARGETS -> "+"(左下角) -> Cross-platform - Other -> Aggregate
      WX20200718-110427@2x.png
    1. Aggregate Target 命名为“RealDemo-Script”
      WX20200718-110553@2x.png
      WX20200718-110835@2x.png
    1. 依赖RealSDK


      WX20200718-112151@2x.png
    1. 添加脚本


      WX20200718-112823@2x.png
      WX20200718-113154@2x.png

    脚本源码

    这个脚本是通用的,各位道友直接复制粘贴即可~

    # Type a script or drag a script file from your workspace to insert its path.
    UNIVERSAL_OUTPUTFOLDER=../Framework/
    
    # 创建输出目录,并删除之前的framework文件
    mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
    rm -rf "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework"
    
    # 分别编译模拟器和真机的Framework
    xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
    xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
    
    # 定义真机、模拟器Build文件夹路径变量
    IPHONE_BUILD=${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
    SIMULATOR_BUILD=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
    
    # 拷贝framework到univer目录
    cp -R "${IPHONE_BUILD}" "${UNIVERSAL_OUTPUTFOLDER}/"
    
    #cp -R "${SIMULATOR_BUILD}" "${UNIVERSAL_OUTPUTFOLDER}/"
    
    # 定义输出路径变量
    OUTPUT_PATH=${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework
    
    # 合并framework,输出最终的framework到build目录 
    lipo -create "${IPHONE_BUILD}/${PROJECT_NAME}" "${SIMULATOR_BUILD}/${PROJECT_NAME}" -output "${OUTPUT_PATH}/${PROJECT_NAME}"
    
    
    
    1. 运行脚本


      WX20200718-120005@2x.png
    1. 运行结果


      WX20200718-115622@2x.png
    1. 检验一下是否合成成功


      WX20200718-120516@2x.png

    四、Framework中使用.bundle资源文件

    1. 首先,我们先随便创建一个Bundle工程。


      WX20200718-152228.png
    1. Bundle工程命名为RealSDKResource。在Build Settings中修改Base SDK为iOS。
      WX20200718-152500.png
    1. 去掉Bundle文件的info.plist文件
      WX20200718-153145.png
    1. 修改Bundle文件名称(可依需求选择)


      WX20200718-153421.png
    1. 将Versioning System设置为None,默认Xcode会通过agvtool生成对应的版本信息,并打包进bundle文件中,这会导致后续在SDK跟随使用的App提交到AppStore的时候报错。


      WX20200718-153623.png
    1. 加一张图片资源,打包


      WX20200718-160219.png
      WX20200718-160246.png
    1. 测试一下RealSDK是否可以引用Bundle资源,SDK中什么都不用设置,直接引用Bundle资源即可。注意引用Bundle资源的方式:用字符串路径读取图片。还可以用NSBundle获取文件。
    WX20200718-160609.png

    用NSBundle获取文件

    WX20200718-161242.png
    1. 把Bundle文件拖到App工程中,写一个测试代码
    WX20200718-161415.png
    1. 运行起来,看一下效果,OJBK
    WX20200718-161706.png

    五、Framework中使用Category

    在Framework工程的Build Setting中添加-ObjC。另外,使用我们SDK的App的Build Setting中也要添加-ObjC

    在网上看到有人建议用-all_load,我个人建议使用-ObjC足矣。-all_load会比-ObjC范围更大,没有必要的事情就不要做,免得浪费性能。具体区别我就不在这里具体说了,网上一大片。

    六、Framework支持bitcode

    WX20200718-165002.png

    相关文章

      网友评论

        本文标题:iOS Framework 实用开发技巧

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