美文网首页iOS成长路线iOS - 大杂烩iOS开发进阶
用 Xcode 7 建立依赖其它第三方库静态库

用 Xcode 7 建立依赖其它第三方库静态库

作者: yww | 来源:发表于2016-03-29 11:50 被阅读1942次

    编写 SDK 的时候, 经常会用到一些常用组件, 比如 AFNetworking.
    如果直接将AFNetworking编译进 SDK ,那么如果用户在使用你写的 SDK 的同时也使用了 AFNetworking,那么会出现"duplicate symbol _OBJC_CLASS_$_xxx"的问题.
    如果自己重新写一个功能类似 AFNetworking 的组件,一来是很麻烦,二来像这种成熟的第三方库, 都是经过很多人测试过,多次修改 bug的,自己写的话,未必比得上,而且重复造轮子也是没有多大意义的.
    接下来我们就来开始写一个简单的 SDK,并且使用 AFNetworking库

    今天的任务是编写一个快递查询 SDK, 使用的是快递100 的API, API 信息源自 BeJSON

    1. 创建工程
      与创建其他工程唯一区别是选择模板的时候要选Cocoa Touch Framework,后面就没什么区别了

      选择模板
      至于为何不选择 Cocoa Touch Static Library 是因为虽然后者也能建立静态库,但是最后得到的是一堆头文件加上一个 .a 文件,不容易部署, 而 Framework 则是把头文件和编译好的二进制文件打包为一个. framwork ,容易部署.
    2. 加入 AFNetworking
      既然要使用 AFNetworking ,自然要先引入, 我用 CocoaPods 来管理, 至于你如果问我没用过 CocoaPods,有没有别的办法? 我还真不知道, 我觉得要是直接把源文件放到工程中多半是不行的, 如果不会可以学习一下 CocoaPods 的使用方法,参见这位大神的文章.
      新建一个 Podfile, 内容如下, 推介使用Xcode 插件,比如CocoaPods 插件

    platform :ios, '7.0'
    target 'ExpressInfo' do
        pod 'AFNetworking'
    end
    

    ExpressInfo 是我的项目名,你可以改成你自己的名字.记得加上 target 'xxx' do ... end, 要不然后面编译要提示can't locate file for: -lPods 错误.
    用命令或是插件执行安装.接下来就可以愉快的使用AFNetworking 了.

    1. 编写 SDK
      源码在这里 GitHub
      注意一点
      ExpressInfo.h,这个文件中,要把所有需要公开的头文件全部列举出来

      引入所有公开头文件
    2. 配置
      打开SDK 这个 target 的 build phase ,找到 Headers, 将 project 中需要公开的头文件选中,移动到 public group 中


      设置头文件

      接下来到 General 中设置需要支持的版本, Build Setting 中加入 armv7s


      添加 armv7s
      既然我们是编写的静态库,就需要将 Mach-O Type 设置为 Static Library
      设置为静态库
      接下来可以编译试试有没有什么错误和警告

      如果没有,就可以进行下一步了

    3. 增加合并模拟器和真机的 Aggregate Target
      由于编译的时候,只会编译当前选中设备的版本,为了编译一份同时能够运行于真机和模拟器的 SDK ,我们再增加一个 target


      Aggregate Target

      在这个 Target 里面选择 Build Phase, 新建一个 Run Script


      添加 Run Sctipt
      代码如下
    #!/bin/sh
    UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
    WORKSPACE_NAME=${PROJECT_NAME}.xcworkspace
    # make sure the output directory exists
    mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
    # Step 1. Build Device and Simulator versions
    xcodebuild -workspace "${WORKSPACE_NAME}" -scheme "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphoneos ONLY_ACTIVE_ARCH=NO   BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
    xcodebuild -workspace "${WORKSPACE_NAME}" -scheme "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
    # Step 2. Copy the framework structure (from iphoneos build) to the universal folder
    cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
    # Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
    SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
    if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
    cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
    fi
    # Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
    lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
    # Step 5. Convenience step to copy the framework to the project's directory
    cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
    # Step 6. Convenience step to open the project's directory in Finder
    open "${PROJECT_DIR}"
    
    run script

    设置这个 Target 为 Release


    设置为 Release

    接下来可以切换到这个 Target 编译了,完成之后,会自动弹出 Framework 所在的文件夹


    编译好的文件
    1. 小试牛刀
      接下来实际使用一下这个 SDK
    2. 先创建一个普通的项目
    3. 添加刚才创建的 Framework
      添加 Framework 到项目
      3.接下来可以编写代码了, 我的源代码在这里GitHub
      编写源代码
    4. 由于我们的 SDK 使用了 AFNetworking, 而 AFNetworking 是没有编译进入我们 SDK 的. 如果直接编译, 会出现找不到类的错误


      错误

      所以使用的时候, 需要加上AFNetworking, 使用 CocoaPods 或者直接使用源文件都可以.
      5.现在可以运行试试了


      运行测试
      打完收工. 若有任何指教, 欢迎留言

    相关文章

      网友评论

      • LightReason:作者,有整个项目打包成一个静态库吗?
        yww:这里只是将自己写的 sdk 打包了, 你可以去 github 上下载 demo 下来看看
      • 我的大名叫小爱:使用.a依赖第三方怎么做???
        yww:第三方库如果是. a 的话, 略微有点麻烦, 只有将.a 整个打包进去.
      • ElegantLiar:你解决了一个困扰我一天时间的问题 赞 我是从你的脚本中发现了我的错误

      本文标题:用 Xcode 7 建立依赖其它第三方库静态库

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