Framework&&Bundle打包&

作者: earthX | 来源:发表于2016-04-12 14:45 被阅读5528次

    在网上搜索了很多关于静态库的知识,最后都是不了了之,遂怒发冲冠,暴走了一次,将Framework打包的一些详细细节加以记录,给予有同样需求的朋友一些帮助。

    首先,Framework作为静态库,是苹果公司允许的一种打包机制,通常SDK的制作也是通过讲.h文件和.m文件加以编译,打包成framework,而例如图片,xib,storyboard,xcassets等资源文件通常是以bundle的方式进行打包,framewrok和bundle本质上都是一种资源包,以一种包集合的概念来对目标文件进行封装。同时,Cocoapods的出现为我们带来了更加便捷的方便,搜索了很多也找不到一个很满意的可以支持Pods方式的静态库打包,我们接下来就尝试进行依赖Cocoapods方式的Framework方式的打包。

    1. Framework

    Framework打包其实很容易,首先,我们将原有工程的项目进行剥离,这里我用了SDAutoLayout的Demo进行操作。
    附上传送门:SDAutoLayoutDemo

    • 新建Framework工程
    framework_1.jpg framework_3.jpg
    • 配置工程
      1.IOS版本配置
      根据需要 7.0&&8.0均可 主要是兼容问题
      2.mach-O type
      由于是静态库 需要设置setting中Mach-O type 为Static Library

    • 终端导入Cocoapods
      导入项目所需要的Pods

      framework_8.jpg
    • 添加打包文件
      1.将项目需要打包的文件添加到项目文件目录中
      2.将项目所依赖的库文件(静态库,framework,lib导入并link)
      3.创建项目头文件,需要包含全部打包的文件
      格式如:#import<demo1/demo1.h>
      4.将Build Phases中headers头文件进行处理

      framework_14.jpg
    • 进行编译
      由于项目属于Framework,编译后只能在模拟器或真机中运行,而实际需求是要在两者内都可以正常操作,在编译前,我们这里要借助mac系统脚本文件Aggregate进行合并打包。
      1.创建aggregate target
      2.添加脚本

    # Sets the target folders and the final framework product.
    # 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
    # 例如: FMK_NAME = "MyFramework"
    FMK_NAME=${PROJECT_NAME}
    # Install dir will be the final output to the framework.
    # The following line create it in the root folder of the current project.
    INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework
    # Working dir will be deleted after the framework creation.
    WRK_DIR=build
    DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
    SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
    # -configuration ${CONFIGURATION}
    # Clean and Building both architectures.
    xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos -arch armv7 -arch armv7s -arch arm64 clean build
    xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator -arch x86_64 clean build
    # Cleaning the oldest.
    if [ -d "${INSTALL_DIR}" ]
    then
    rm -rf "${INSTALL_DIR}"
    fi
    mkdir -p "${INSTALL_DIR}"
    cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
    # Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
    lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"
    rm -r "${WRK_DIR}"
    open "${SRCROOT}/Products/"
    

    3.设置Run 模式为 release模式


    framework_19.jpg

    4.删除Frameworks中的libPod.a文件
    这个需要强调一下,必须要删除这个文件,因为打包后该项目不存在拿给其他项目用的时候,该文件会重复,引起报错。


    framework_20.jpg

    5.编译生成Framework

    framework_21.jpg

    2. Bundle打包

    前文说过,例如图片,xib,storyboard,xcassets等资源文件通常是以bundle的方式进行打包,framewrok和bundle本质上都是一种资源包,以一种包集合的概念来对目标文件进行封装。且bundle在xcode7中已经被划分到mac项目文件中来,新建时要从OS X文件中寻找。

    • 新建Bundle
      bundle_1.jpg
    • 配置Bundle
      由于是OS X系统下的Bundle, 新建后我们要对其进行一些设置
    • "Base SDK" 设置为 "IOS 8.3" (Xcode 6.3.2为例)
    • "Build Active Architecture Only" 设置为 "YES"
    • "Debug Information Format" 设置为 "DWARF with dSYM File"
    • "OS X Deployment Target" 设置为 "Compiler Default"
    • "Skip Install" 设置为 "NO"
    • "Strip Debug Symbols During Copy" 中"Release"模式设置为 "YES"
    • "IOS Deployment Target" 设置为 "IOS 7.0"
    • "COMBINE_HIDPI_IMAGES" 设置为 "NO"
    bundle_7.jpg
    • 导入打包资源文件并编译打包
      这里测试放入png,xib,storyborad,xcassets文件,以此类推.
    bundle_11.jpg

    3. 主项目调用

    需要将主项目Enable Bitcode 设置为“YES”

    bundle_12.jpg framework_26.jpg

    需要注意的是 如果主项目中采用了Category的话 需要在引用framework的工程中设置 Build Pharse -> Other Linker Flags中加上 -all_load 就OK了,再次运行工程,可以完成所有的打印过程.

    4. 调用方法

    • bundle路径(定义宏)
    #define MYBUNDLE_NAME_2   @"bundle1.bundle"
    #define MYBUNDLE_PATH_2   [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: MYBUNDLE_NAME_2]
    #define MYBUNDLE_2        [NSBundle bundleWithPath: MYBUNDLE_PATH_2]
    
    • 加载storyboard
    //加载storyboard
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SFMapKit" bundle:MYBUNDLE_2];
        UIViewController *test = [storyboard instantiateViewControllerWithIdentifier:@"test"];
        [self.navigationController pushViewController:test animated:YES];
    // bundle加载图片
        UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
        imageView.image = [UIImage imageWithContentsOfFile:[MYBUNDLE_PATH_2 stringByAppendingPathComponent:@"test.png"]];
        [self.view addSubview:imageView];
    
    • xcassets加载图片
    // xcassets加载图片
        UIImageView *imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(100, 260 , 40, 40)];
        UIImage *image1 = [UIImage imageNamed:@"ScanBook_HL" inBundle:MYBUNDLE_2 compatibleWithTraitCollection:nil];
        imageView1.image = image1;
        [self.view addSubview:imageView1];
    
    • 加载xib
    //加载xib
        -(instancetype)init{
        NSBundle *bundle = [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"bundle1.bundle"]];
        self = [super initWithNibName:@"testxib" bundle:bundle];
        return self;
    }
    

    好了到此为止,问题解决!

    相关文章

      网友评论

      • 恒liu:哥们能问你一些SDK开发的问题么,加个QQ1153797560
      • 哈哈哈士奇XHB:你这个资源Bundle怎么整合到SDK里面去?也就是说,资源Bundle不暴露在外,只暴露SDK的相关接口
      • First灬DKS:博主你好:我的framework中用了一个第三方,但是主工程中没有使用这个第三方,出现错误,怎么去解决呢,不能强制在主工程添加这个第三方吧?
        我的大名叫小爱:没有详细步骤操作都没法操作。
        earthX:@First灬DKS 没有怎么能编译呢。。。肯定会报错啊
      • 落霞与孤鹜齐飞i:楼主你好,我想请问一下 我把图片存放到.bundle文件里,然后把bundle文件放到framework,这样可以吗?我尝试了 但是图片不显示
        Sandy苗:楼主你好,模拟器是OK的,用真机报Unknown class FMWelcomeViewController in Interface Builder file.但是link是配置好的
        落霞与孤鹜齐飞i:@earthX 多谢了,我试试
        earthX:framework和bundle 本质上你可以理解为文件夹,但是bundle主要是来实现资源文件,而framework更像是一个包,原理上应该是可以在涵盖bundle的,但我没试过,aipay的sdk就是两个framework,如果有资源的话,应该也在里面,你可以试试。你提到的图片显示不出来的问题,你检查下图片的path,是不是有可能是路径的问题,可以按着这个思路:
        NO1.找得到bundle么?NO2:bundle路径是对的么?NO3.能不能通过framework 找bundle在找image
      • NicWhite:能问一下,如果想打包plist文件进去,也放进bundle中吗?plist文件不想让外面看到
        earthX:plist?没有试过,一般情况这个不会有一些涉密的内容 因为最后都要是引用头文件 你可以试试放在bundle里面 只是一种思路,没有验证过
      • 纪宝宝:楼主,能发一下bundle那几种读取的demo么,邮箱983442994@qq.com 先谢谢了 :blush: :heart:
        纪宝宝:我知道怎么弄的了,谢谢楼主分享~ :blush:
      • humanff:问个问题我想不使用bundle直接扔在framework目录,但是xib引用图片出错了,这是什么原因
        earthX:@humanff 建议检查一下路径 还有图片所在文件夹
      • Jon1993:脚本没毛病,感谢!!
      • earthX:先获取storyboard 然后再调用VC里的UI即可
      • 十六_:请教一个问题,我打包进去了整个工程到framework里面去,然后怎么跳转的时候调用我的故事版里面的ui呢?这块有点不太明白 希望可以帮忙回答一下,谢谢
        LightReason:哥们 ,求助,我现在面临需要把原来整个项目打包成SDK,想求教你一些问题,是否可以联系下你,
      • walter211:你好,请教个问题,我在开发framwork的时候由于冲突需要抽取公共库,并且从外部测试的test工程引用一些第三方公共库,这块怎么设置?
        earthX:@walter211 建议用pod方式

      本文标题:Framework&&Bundle打包&

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