• iOS项目功能模块封装SDK使用总结


    一、功能模块SDK封装步骤:

    1、创建IOS Framework工程

    先我们需要创建一个iOS的CocoaTouch工程,点击Next,输入我们Framework的名字即可。下方我们暂且将该Framework的名字命名为“CreateLoginSDKFramework”。操作如下所示:

    Xcode ——》FileNewProject ——》iOSFramework and LibraryCocoa Touch Framework ——》命名项目工程

     

    2、设置兼容版本:

    创建完工程后,我们要选择“Deployment Target”, 此处我们选择的是8.0。也就是说此处我们封装的SDK所支持的iOS系统版本是iOS8.0+。操作所示:

    Xcode ——》Project ——》Targets ——》General ——》Deployment Info ——》iOS8.0(最低支持的兼容版本)

     

    3.1、配置动态库:

    创建的framework默认是动态库,操作如下所示:

    Xcode ——》Project ——》Targets ——》Build Settings ——》Msch-O Type——》Dynamic Library

    Xcode ——》Project ——》Targets ——》Build Settings ——》Build active Architecture only——》NO

     

    3.2、配置静态库:

    由于创建的framework默认是动态库,所以我们要讲Mach-O Type设置为静态库“Static Library”。操作如下所示:

    Xcode ——》Project ——》Targets ——》Build Settings ——》Msch-O Type——》Static Library

    Xcode ——》Project ——》Targets ——》Build Settings ——》Build active Architecture only——》NO

    Xcode ——》Project ——》Targets ——》Build Settings ——》Dead Code Stripping——》NO

    Xcode ——》Project ——》Targets ——》Build Settings ——》Link With Standard Libraries——》NO

     

    4、设置支持所有架构(armv7/armv7s/arm64):

    Xcode ——》Project ——》Targets ——》Build Settings ——》Build Active Architecture Only——》NO

     

    5、导入源代码文件,设置要公开的所有头文件:

    将事先准备好的SDK源代码引入到我们的Framework的工程中进行编译了,在编译之前我们要选择SDK用户可以看到的文件。在Build Phases下的Headers中进行设置的。将用户可以看到的头文件放在Public中,用户看不到的放在Project中。操作如下所示:

    Xcode ——》Project ——》Targets ——》Build Phases ——》Headers——》Public/Private/Project

     

    6、编译工程:

    设置和配置完毕后,我们就要对我们的Framework程进行编译了。先选择模拟器进行编译,然后选择真机进行编译。编译完后,在Products下会生成相应的Framework, 然后通过Show in Finder进行查看即可。查看时,如果想看“模拟器”和“真机”的framework的话,在Show in finder后,需要前往上层文件夹查看。

     

    7、第一种方式(使用命令行合并模拟器和真机Framework库):

    因为在模拟器下编译会生成模拟器下使用的Framework,在真机下编译会生成真机使用的Framework。如果想我们生成的Framework既可以在真机下使用,也可以在模拟器下使用,那么我们需要将两个Framework进行合并。使用终端命令将上述两个文件进行合并。下方就是合并上述两个文件的执行命令, 执行完下方命令后会生成合并后的新文件。操作如下所示:

    打开终端 ——》lipo -create 模拟器framework路径  真机framework路径 -output 新的文件

    注意事项:

    1、编译Framework工程前,需要设置Edit Scheme, 选择run->将Debug模式改成Release模式,选择Close。

    2、合并Framework出现error:can't map input file: xxxFramework.framework/ (Invalid argument),原因是如果工程名称和Framework的Target名称不一样的话,要自定义FrameworkName。

    lipo -info xxxFramework.framework/xxxFramework

     或者

    cd xxxFramework.framework

    lipo -info xxxFramework

    完整命令如下:

    lipo -create /Users/yh/Library/Developer/Xcode/DerivedData/YouHone_SDK-dchvyxjtxmxejegowpxcteqnerux/Build/Products/Release-iphonesimulator/YouHone_SDK.framework/YouHone_SDK  /Users/yh/Library/Developer/Xcode/DerivedData/YouHone_SDK-dchvyxjtxmxejegowpxcteqnerux/Build/Products/Release-iphoneos/YouHone_SDK.framework/YouHone_SDK -output /Users/yh/Desktop/NewSDK/YouHone_SDK

     

    注意:记得将新合成的YouHone_SDK文件,替换成发布模式的真机里面YouHone_SDK文件

    Debug-iphonesos(测试模式真机)

    Debug-iphonesimulator(测试模式模拟器)

    Release-iphonesos(发布模式真机)

    Release-iphonesimulator(发布模式模拟器)

     

    3、如果需要隐藏文件中的分类创建的类,需要在工程添加

    Xcode ——》Project ——》Targets ——》Build Phases ——》 Other Linker Flags ——》-all_load

     

    8、第二种方式(使用脚本合并模拟器和真机Framework库):

    1、编译framework的shell脚本

    #buildtarget TARGET_NAME=${PROJECT_NAME} if [[ $1 ]] then TARGET_NAME=$1 fi UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}_Products/" #创建输出目录,并删除之前的framework文件 mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}" rm -rf "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework" #分别编译模拟器和真机的Framework xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build #拷贝frameworkuniver目录 cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_FOLDER}" #合并framework,输出最终的frameworkbuild目录 lipo -create -output "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}" #删除编译之后生成的无关的配置文件 dir_path="${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/" for file in ls $dir_path do if [[ ${file} =~ ".xcconfig" ]] then rm -f "${dir_path}/${file}" fi done #判断build文件夹是否存在,存在则删除 if [ -d "${SRCROOT}/build" ] then rm -rf "${SRCROOT}/build" fi rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos" #打开合并后的文件夹 open "${UNIVERSAL_OUTPUT_FOLDER}"

    2、编译library(静态库.a文件)的脚本

    #要build的target名 target_Name=${PROJECT_NAME} if [[ $1 ]] then target_Name=$1 fi UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}_Products" # 创建输出目录,并删除之前的文件 rm -rf "${UNIVERSAL_OUTPUT_FOLDER}" mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}" # 分别编译真机和模拟器版本 xcodebuild -target "${target_Name}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build xcodebuild -target "${target_Name}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build #复制头文件到目标文件夹 HEADER_FOLDER="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/include/${target_Name}" if [[ -d "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/usr/local/include" ]] then HEADER_FOLDER="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/usr/local/include" fi cp -R "${HEADER_FOLDER}" "${UNIVERSAL_OUTPUT_FOLDER}" #合成模拟器和真机.a包 lipo -create "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${target_Name}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${target_Name}.a" -output "${UNIVERSAL_OUTPUT_FOLDER}/lib${target_Name}.a" # 判断build文件夹是否存在,存在则删除 if [ -d "${SRCROOT}/build" ] then rm -rf "${SRCROOT}/build" fi #打开目标文件夹 open "${UNIVERSAL_OUTPUT_FOLDER}"

     

    二、资源文件的Bundle封装步骤:

    1、Bundle工程的创建:

    首先像创建Framework工程一样创建一个Bundle工程,因为iOS工程下方没有Bundle类型的工程,所以我们需要在OS X -> Framework & Library -> Bundle下面来创建我们的Bundle工程。操作如下所示:

    Xcode ——》FileNewProject ——》macOSFramework and LibraryBundle——》命名项目工程

     

    2、配置Bundle工程:

    创建完Bundle工程后,我们要对其进行相应的配置。因为我们是选择OS X创建的Bundle,默认的Bundle是不能在iOS中使用的,所以我们得将Base SDK进行设置,选择相应的iOS样式即可(默认Mac OS样式),如下所示。选择完Base SDK后,我们还要像上面Framework的封装一样,设置一下要兼容的iOS版本(iOS Deployment Target)。操作如下所示:

    A、Xcode ——》Project ——》Targets ——》Build Settings ——》Base SDK ——》iOS样式

    B、Xcode ——》Project ——》Targets ——》General ——》Deployment Info ——》Deployment Target——》ios8.0(最低支持的兼容版本)

    C、Xcode ——》Project ——》Targets ——》Build Settings ——》Installation Directory ——》清空路径

    D、Xcode ——》Project ——》Targets ——》Build Settings ——》Skip Install ——》默认YES,跳过安装过程

    E、Xcode ——》Project ——》Targets ——》Build Settings ——》COMBINE_HIPI_IMAGES ——》设置NO(如果为YES,图片是TIFF模式)

     

    3、导入Bundle资源文件并进行编译:

    进行上述配置完后,接下来就是引入资源文件进行编译了,下方引入的资源文件就是我们的LoginSDK.storyboard。引入资源后,进行编译,编译后会在Products下面生成相应的Bundle资源文件,该文件就可以和我们的Framework进行使用了。

    Xcode ——》Project ——》Targets ——》Build Phases——》Copy Bundle Resources ——》添加图片资源

     

    4、项目中Bundle资源的加载:

    生成完Bundle资源文件后,我们在SDK的源代码中,要从Bundle资源文件中进行资源的加载。下方代码就是加载相应Bundle的代码。通过下方的宏定义,就可以通过“Bundle”的名字来加载Bundle。

    #define LOGIN_SDK_BUNDLE_NAME   @"LoginSDKResource.bundle"

    #define LOGIN_SDK_BUNDLE_PATH   [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: LOGIN_SDK_BUNDLE_NAME]

    #define LOGIN_SDK_BUNDLE        [NSBundle bundleWithPath: LOGIN_SDK_BUNDLE_PATH]

     

    5、注意事项:

    如果Bundle工程中中引用了资源文件,工程编译过后会出现.storyboardc或者.xibc文件才算真正封装成功。

     

    三、封装后的SDK文件的使用步骤:

    1、导入SDK,进行路径配置

    导入SDK到我们的App工程后,我们要对其进行相应的配置。首先我们要对Framework Search Paths进行配置,也就是说告诉编译器我们的第三方SDK所在的位置。下方这个配置项在引入SDK后就默认存在的,如果没有的话就进行配置即可。操作如下所示:

    Xcode ——》Project ——》Targets ——》Build Settings ——》Search PathsFramework Search Paths ——》$(PROJECT_DIR)/LoginSDK

     

    2、进行编译配置

    配置完路径后,接下来我们要在Other Linker Flags添加上-Objc和-all_load选项。-Objc这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。而-all_load会强制链接器把目标文件都加载进来,即使没有objc代码。操作如下所示:

    Xcode ——》Project ——》Targets ——》Build Settings ——》LinkingOther Link Flags——》-Objc和-all_load

     

    3、SDK的使用:

    配置完毕后,接下来就是在我们App中使用该SDK了。下方代码就是我们上述LoginSDK的使用方式,首先获取单例,然后检查是否登录,登录成功后根据Block回调跳转到首页,如果未登录,就通过LoginAPI获取登录页面进行登录。

     

    4、 注意事项:

    《A》如果打包导出的是动态库,需要在新的工程

    Xcode ——》Project ——》Targets ——》General ——》Embedded Binaries ——》添加导入Framework库

     

    《B》如果打包导出的是态库,需要在新的工程

    Xcode ——》Project ——》Targets ——》General ——》Link Binary With Libraries ——》添加导入Framework库

    如果是态库,那么在新的工程还需要额外的配置:

    Xcode ——》Project ——》Targets ——》Build Phases ——》New Copy Files phase ——》添加导入Framework库

    如果是态库,资源打包进Framework是读取不了的。静态Framework和.a文件都是编译进可执行文件里面的。只有动态Framework能在.app的Framework文件夹下看到,并读取.framework里的资源文件。

     

  • 相关阅读:
    Qt:QT右键菜单
    Ubuntu 12.04安装字体
    在ubuntu下关闭笔记本触摸板
    SSL与TLS的区别以及介绍
    隔行扫描与逐行扫描的区别
    Linux下的绘图(流程图、UML、mindmap)工具
    RedHat Linux 下安装MPlayer 编译源代码方式
    循环数组实现队列的四种方式
    Linux内核spin_lock与spin_lock_irq分析
    Oracle 创建同义词
  • 原文地址:https://www.cnblogs.com/yuhao309/p/8960730.html
Copyright © 2020-2023  润新知