swift framework 制作

作者: 一念之见 | 来源:发表于2016-11-11 18:35 被阅读342次

    首先我们通过新建菜单的 Framework & Library 创建一个 Cocoa Touch Framework 项目QJWiFi

    1、内容:

    创建需要打包的代码,将需要公开调用的接口方法声明为public(供其他 module 调用)

    2、framework 生成:

    将运行设备选择为任一 iOS 模拟器,然后使用 Shift + Cmd + I 进行 Profiling 编译(同时生成 debug 与 release 版本,如果是 Cmd + B,则只生成 debug 版本)。我们可以在项目的生成的数据文件夹 中找到QJWiFi.framework

    (对应项目的 ~/Build/Products/Release-iphonesimulator)

    快捷访问生成文件

    3、版本兼容:

    将运行设备选择为真机,使用 Shift + Cmd + I 进行 Profiling 编译,此时我们的生成文件目录下有(Debug-iphonesimulator、Release-iphoneos、Release-iphonesimulator)三个文件,我们需要将其中的一些内容合并

    合并A:合并 Release-iphoneos 与Release-iphonesimulator 文件下的二进制文件
    终端命令:

     cd /Users/xxx/Library/Developer/Xcode/DerivedData/QJWiFi-fejnkmidkzkbocbjnkbgoclwbobz/Build/Products
    
    lipo -create Release-iphoneos/QJWiFi.framework/QJWiFi Release-iphonesimulator/QJWiFi.framework/QJWiFi -output Release-iphoneos/QJWiFi.framework/QJWiFi
    
    lipo -info QJWiFi  // 查询framework 支持的 cpu 架构
    Architectures in the fat file: QJWiFi are: i386 x86_64 armv7 arm64 
    

    合并B:拷贝Release-iphonesimulator/QJWiFi.framework/Modules/QJWiFi.swiftmodule 文件夹下的所有文件到 Release-iphoneos 相应的文件夹中,现在 Release-iphoneos 文件中的 QJWiFi.framework 就是我们需要的架包。


    4、测试:

    新建一个 Swift 项目, 将 QJWiFi.framework 拖拽添加到项目中。我们最好勾选上 Copy items if needed,这样原来的框架的改动就不会影响到我们的项目了。然后,在需要使用这个框架的地方导入框架的 module(import QJWiFi),这样我们就可以使用使用框架中的公开类与方法。

    但是。。。运行项目,success 之后编译器会报以下错误

    dyld: Library not loaded: @rpath/QJWiFi.framework/QJWiFi
      Referenced from: /Users/laichunhui/Library/Developer/CoreSimulator/Devices/CBBB7623-1930-4A1F-A094-6A2AC27A8E29/data/Containers/Bundle/Application/AB2EAE28-C094-4047-9379-815980E8A214/QJWiFiDemo.app/QJWiFiDemo
      Reason: image not found
    

    这是因为我们还未将框架复制到项目包中。在 Build Phases 选项卡里添加一个 Copy File 的阶段 ,然后将目标设定为 Frameworks,将我们的 QJWiFi.framework 添加到新建的阶段里,来指定 IDE 在编译时进行复制。

    常见问题:

    1. Objective-C 项目集成 Swift framework 注意点
      如果要将框架导入到 OC 项目中(#import "QJWiFi/QJWiFi.h" 或 #import "QJWiFi/QJWiFi-Swift.h"),还需要将 Build setting 中的 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES 设置为 YES,否则项目会报 image not found 的错误。


    2. 资源加载

    • framework 自身对应的 bundle: Bundle(for: QJWiFi.self)
    • framework 内部 image 访问: UIImage(named: imageName, in: bundle, compatibleWith: nil)
    1. 报错: Include of non-modular header inside framework module
      如果我们项目中调用了比如 CommonCrypto 等底层框架,由于这些框架并未打包成 module,我们无法直接导入到 Swift 项目中,如果在 framework 的头文件中直接导入 (#import <CommonCrypto/CommonCrypto.h>)就会报以上错误。在framework 中,桥接是不被允许的,有兴趣的可以不妨一试。所以我们只能为这个底层框架创建 module。
    • 首先在你的 Framework/Target 下建一个文件夹,可以叫做 CommonCrypto ,并创建两个子文件夹,可以分别命名为 iphoneos 、iphonesimulator,并分别新建一个 module.modulemap的文件,内容分别为:
      module CommonCrypto [system] {
        header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/CommonCrypto/CommonCrypto.h"
        export *
    }
    
    module CommonCrypto [system] {
        header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/CommonCrypto/CommonCrypto.h"
        export *
    }
    
    • 然后在你的 Target 的 Build Setting 中找到 Swift ComCompiler - Search Paths 的 Import Paths ,设置键值:
      • Any iOS Simulator SDK
        ${SRCROOT}/QJWiFi/CommonCrypto/iphonesimulator

      • Any iOS SDK
        ${SRCROOT}/QJWiFi/CommonCrypto/iphoneos


    这样在 framework 中就可以直接导入 module (import CommonCrypto)

    相关文章

      网友评论

        本文标题:swift framework 制作

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