zoukankan      html  css  js  c++  java
  • IOS

    1. 创建一个静态库 名字为   MySDK

    删除没用的.m 文件

    删除.h中内容 添加 #import<UIkit/UIkit.h>

    导入uikit 框架

    依然是在Xcode的Build Phases界面,选择EditorAdd Build PhaseAdd Copy Headers Build Phase。

    Note:如果你发现按上面找到的菜单项是灰色的(不可点击的),点击下方Build Phases界面的白色区域来获取Xcode的应用焦点,然后重新试一下。

    把MySDK.h从项目导航栏中拖到中央面板的Copy Headers下的Public部分。这一步确保任何使用你的库的用户均可以获取该头文件。

    Note:显然,所有包含在你的公共头文件中的头文件必须是对外公开的,这一点非常重要。否则,开发者在使用你的库时会得到编译错误。如果Xcode在读取公共头文件时不能读到你忘记设为public的头文件,这实在是太令人沮丧了。

    创建一个UI页面拖入工程

    Note:在你弄清楚之前,这三个组的名称可能会让你迷惑,Public是你期望的,Private下的头文件依然是可以暴露出来的,因此名字可能有些误导。讽刺的是,在Project下的头文件对你的工程来说才是“私有”的,因此,你将会更多地希望你的头文件或者在Public下,或者在Project下。

    现在,你需要将控件的头文件Myview.h分享出来,有几种方式可以实现这一点,首先是在Copy Headers面板中将这个头文件从Project栏拖到Public栏。

    配置Build Settings

    然后选择MySDK静态库目标,选择Build Setting栏,然后搜索public header,双击Public Headers Folder Path,在弹出视图中键入如图所示内容:

    输入 include/$(PROJECT_NAME)

    因为你正在创建framework供他人使用,最好禁掉这些功能(无效代码和debug用符号),让用户自己选择对自己的项目有利的部分使用。和之前一样,使用搜索框,改变下述设置:

    Dead Code Stripping设置为NO

    Strip Debug Symbol During Copy 全部设置为NO

    Strip Style设置为Non-Global Symbols

    编译然后运行,到目前为止没什么可看的,不过确保项目可以成功构建,没有错误和警报是非常好的。

    选择目标为iOS Device,按下command + B进行编译,一旦成功,工程导航栏中Product目录下libMySDK.a文件将从红色变为黑色,表明现在该文件已经存在了。右键单击libMySDK.a,选择Show in Finder。

    第二大部分

    常见一个新的工程(Single View Application 类型)位置和MySDK位置在同一目录下

    把MySDK工程关掉 将MySDK.xcodeproj拖入MyTestSDK中的工程

    Note:你无法将同一工程在两个Xcode窗口中同时打开,如果你发现你无法在你的工程中导航到库工程的话,检查一下是否库工程在其他Xcode窗口中打开了。

    为了连接到静态库本身,展开Link Binary With Libraries面板和TargetDependencies,再次点击+按钮,从Workspace组中选择libMySDK.a然后点击Add。

    然后在MyTestSDK的viewController 中导入头文件#import<MySDK/Myview.h>

    Myview *myview = [[Myview alloc] init];

    [self.view addSubview:myview];

    添加view,运行我只设置了View的北京颜色 

    第三大部分   创建framework

    到现在,你可能迫不及待地点着脚趾头,想着什么时候framework可以出来。可以理解,因为到现在为止你已经做了许多工作,然而却没有看到过framework的身影。

    现在你需要在静态库构建过程中添加脚本来创建这种结构,在项目导航栏中选择MySDK.xcodeproj,然后选择MySDK静态库目标,选择Build Phases栏,然后选择Editor/Add Build Phase/Add Run Script Build Phase来添加一个新的脚本。

    none: 如果是灰色的请点击build phases 页面 聚集焦点

    添加脚本信息

    set -e

    export FRAMEWORK_LOCN="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework"

    # Create the path to the real Headers dir

    mkdir -p "${FRAMEWORK_LOCN}/Versions/A/Headers"

    # Create the required symlinks

    /bin/ln -sfh A "${FRAMEWORK_LOCN}/Versions/Current"

    /bin/ln -sfh Versions/Current/Headers "${FRAMEWORK_LOCN}/Headers"

    /bin/ln -sfh "Versions/Current/${PRODUCT_NAME}"

    "${FRAMEWORK_LOCN}/${PRODUCT_NAME}"

    # Copy the public headers into the framework

    /bin/cp -a "${TARGET_BUILD_DIR}/${PUBLIC_HEADERS_FOLDER_PATH}/"

    "${FRAMEWORK_LOCN}/Versions/A/Headers"

    这个脚本首先创建了MySDK.framework/Versions/A/Headers目录,然后创建了一个framework所需要的三个连接符号(symbolic links)。

    Versions/Current => A

    Headers => Versions/Current/Headers

    MySDK => Versions/Current/MySDK

    最后,将公共头文件从你之前定义的公共头文件路径拷贝到Versions/A/Headers目录下,-a参数确保修饰次数作为拷贝的一部分不会改变,防止不必要的重新编译。

    现在,选择MySDK静态库,然后选择iOS Device构建目标,然后使用cmd+B构建。

    创建Aggregate  

    点击Next 命名为Framework----> finish

    在Build Phases中添加一个依赖。展开Target Dependencies面板,点击 + 按钮选择MySDK静态库。

    这个目标的主要编译部分是多平台编译,你将使用一个脚本来做到这一点。和你之前做的一样,在Framework目标下,选择Build Phases栏,点击Editor/Add Build Phase/Add Run Script Build Phase,创建一个新的Run Script Build Phase。

    添加脚本信息

    ----------------------------------------------------------------------------------------------------------

    set -e

    # If we're already inside this script then die

    if [ -n "$RW_MULTIPLATFORM_BUILD_IN_PROGRESS" ]; then

    exit 0

    fi

    export RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1

    RW_FRAMEWORK_NAME=${PROJECT_NAME}

    RW_INPUT_STATIC_LIB="lib${PROJECT_NAME}.a"

    RW_FRAMEWORK_LOCATION="${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework"

    function build_static_library {

    # Will rebuild the static library as specified

    #    build_static_library sdk

    xcrun xcodebuild -project "${PROJECT_FILE_PATH}"

    -target "${TARGET_NAME}"

    -configuration "${CONFIGURATION}"

    -sdk "${1}"

    ONLY_ACTIVE_ARCH=NO

    BUILD_DIR="${BUILD_DIR}"

    OBJROOT="${OBJROOT}"

    BUILD_ROOT="${BUILD_ROOT}"

    SYMROOT="${SYMROOT}" $ACTION

    }

    function make_fat_library {

    # Will smash 2 static libs together

    #    make_fat_library in1 in2 out

    xcrun lipo -create "${1}" "${2}" -output "${3}"

    }

    # 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name

    if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]; then

    RW_SDK_PLATFORM=${BASH_REMATCH[1]}

    else

    echo "Could not find platform name from SDK_NAME: $SDK_NAME"

    exit 1

    fi

    # 2 - Extract the version from the SDK

    if [[ "$SDK_NAME" =~ ([0-9]+.*$) ]]; then

    RW_SDK_VERSION=${BASH_REMATCH[1]}

    else

    echo "Could not find sdk version from SDK_NAME: $SDK_NAME"

    exit 1

    fi

    # 3 - Determine the other platform

    if [ "$RW_SDK_PLATFORM" == "iphoneos" ]; then

    RW_OTHER_PLATFORM=iphonesimulator

    else

    RW_OTHER_PLATFORM=iphoneos

    fi

    # 4 - Find the build directory

    if [[ "$BUILT_PRODUCTS_DIR" =~ (.*)$RW_SDK_PLATFORM$ ]]; then

    RW_OTHER_BUILT_PRODUCTS_DIR="${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}"

    else

    echo "Could not find other platform build directory."

    exit 1

    fi

    # Build the other platform.

    build_static_library "${RW_OTHER_PLATFORM}${RW_SDK_VERSION}"

    # If we're currently building for iphonesimulator, then need to rebuild

    #  to ensure that we get both i386 and x86_64

    if [ "$RW_SDK_PLATFORM" == "iphonesimulator" ]; then

    build_static_library "${SDK_NAME}"

    fi

    # Join the 2 static libs into 1 and push into the .framework

    make_fat_library "${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}"

    "${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}"

    "${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}"

    # Ensure that the framework is present in both platform's build directories

    cp -a "${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}"

    "${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}"

    # Copy the framework to the user's desktop

    ditto "${RW_FRAMEWORK_LOCATION}" "${HOME}/Desktop/${RW_FRAMEWORK_NAME}.framework"

    ----------------------------------------------------------------------------------------------------------

    选择Framework集合方案(aggregate scheme),按下cmd+B编译该MySDK。

    如果编译成功, 在桌面上将生成一个MySDK.framework 

    为了检查一下我们的多平台编译真的成功了,启动终端,导航到桌面上的framework,像下面一样:

    $ cd ~/Desktop/MySDK.framework

    $  xcrun lipo -info MySDK


    这里你可以看到,一共有五种片段:i386, x86_64, arm7, arm7s 和 arm64,正如你在编译时设定的那样。如果你之前使用lipo –info指令,你可以看到这些片段的一个分组。

    打包(Bundle)资源

    你有没有注意到MySDK的framework只包含了代码和头文件,其他的文件却没有被包含。例如,你没有使用其他任何资源,比如图片。这是iOS的一个限制,framework只能包含头文件和静态库。

    下面我们就来创建一个包含图片的资源方法、

    选择MySDK.xcodeproj   点击Add Target按钮

    导航到macOS /Framework and Library/Bundle。将新的Bundle命名为MySDKResources,然后从framework选择框中选择Core Foundation。

    这里需要配置几个编译设置,因为你正在创建一个在iOS上使用的bundle,这与默认的OS X不同。选择MySDKResources目标,然后点击Build Settings栏,搜索base sdk,选择Base SDK这一行,按下delete键,这一步将OS X切换为iOS。

    同时你需要将工程名称改为MySDK。搜索product name,双击进入编辑模式,将${TARGET_NAME}替换为MySDK。

    默认情况下,有两种resolutions的图片可以产生一些有趣的现象。例如,当你导入一个retina @2x版本的图片时,普通版的和Retina版的将会合并成一个多resolution的TIFF(标签图像文件格式,Tagged Image File Format)。这不是一件好事。搜索hidpi将COMBINE_HIDPI_IMAGES设置为NO。

    现在,你将确保当你编译framework时,bundle也能被编译并将framework作为依赖添加到集体目标中。选中Framework目标,选择Build Phases栏,展开Target Dependencies面板,点击 + 按钮,选择MySDKResources目标将其添加为依赖。

    现在,在Framework目标的Build Phases中,打开Run Script面板,在脚本的最后添加下述代码:

    # Copy the resources bundle to the user's desktop

    ditto "${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.bundle"

    "${HOME}/Desktop/${RW_FRAMEWORK_NAME}.bundle"

    这条指令将拷贝构建好的bundle到用户的桌面上。现在,编译framework scheme,你会发现bundle在桌面上出现。

    导入Bundle

    在项目导航栏中,选择MyTestSDK工程,点击MySDK目标,展开MySDK工程的Product组,把MySDKResources.bundle拖到Copy Bundle Resources面板中的 Build Phases栏。

    在Target Dependencies面板中,点击+按钮,添加新的依赖,然后选择MySDKResources.bundle。

    接下来拖入一张图片然后设置属于的目标

    导入头文件#import<MySDK/DownViewcontroller.h>到MySDK.h中

    还记得我们说过要确保framework可以被访问吗?现在,你需要导出头文件DownViewController.h,在Target Membership面板中选择该文件,然后从弹出视图中选择Public。

    调用bound中的图片方法

    self.headerImg.image = [UIImage imageNamed:@"MySDK.bundle/header"];

     
  • 相关阅读:
    知识点小结
    体检套餐
    序列化和反序列化
    深入.NET平台的软件系统分层开发
    深入.NET平台和C#编程
    影院售票系统
    面向服务(接口)开发过程中常用的实体类数据复制解决方案
    EF优缺点的理解
    事务锁兼容性
    ASP.NET列表信息以Excel形式导出
  • 原文地址:https://www.cnblogs.com/xu-antong/p/6962732.html
Copyright © 2011-2022 走看看