iOS创建OC 和Swift混编framework

3,231 阅读2分钟
前言

项目中使用oc创建framework,随着工程的不断变化,需要引入一些swift文件,针对项目中遇到的问题,记录下曾经踩的坑,framework工程中选择静态库Static Library等要求就不做说明

创建工程

创建framework工程,使用OC为主要语言

截屏2022-03-11 上午10.23.48.png

创建framework demo的target

截屏2022-03-11 上午10.29.47.png

项目中添加OC和swift文件,默认生成bridging-Header文件,在bridging文件中添加swift需要调用的OC文件

image.png

class TestTwoVC: UIViewController {

    func initializationContentView() -> Void {

        let presentBtn = UIButton.init(frame: CGRect.init(x: 50, y: 150, width: 200, height: 100))

        presentBtn.setTitle("jump", for: .normal)

        presentBtn.setTitleColor(UIColor.black, for: .normal)

        presentBtn.addTarget(self, action: #selector(presentAction), for: .touchUpInside)

        self.view.addSubview(presentBtn)           
    }

    @objc func presentAction(){

        self.navigationController?.pushViewController(TestThreeVC.init(), animated: true)

    }   
}

TestOneVC 跳转 TestTwoVC 文件时,需要引入 -Swift文件,在demo和framework需要添加不同的-Swift文件,在target上使用preprocess macros上加入宏定义区分

image.png

#if FRAMEWORK
#import "frameworkProject-Swift.h"
#else
#import "frameworkProjectDemo-Swift.h"
#endif

此时运行demo工程,效果如下:

未命名.gif

Perfect!!!!!

开始编译framework

报错1 “Cannot find 'TestThreeVC' in scope”,swift文件中提示未找到 TestThreeVC 文件

image.png

解决方案:把TestThreeVC移动到public选项下,同时在frameworkProject.h引入,可解决

image.png

报错2 “'frameworkProject-Swift.h' file not found”,-Swift文件不存在

image.png

发现是写法问题,应该使用 #import <frameworkProject/frameworkProject-Swift.h>,修改之后,以为可以了,xcode提示我想多了

image.png

swift文件在framework中想要暴露给OC使用,需要添加 @objc public

image.png

OK !!! 大功告成

But,解决报错1的时候,把不需要暴露给framework以外的工程调用的文件也被暴露出来,违背了framework的本意

image.png

这时,需要把TestThreeVC从public中移除出来
So,根据老司机们的说法,创建 module.modulemap 文件

1、首先创建一个header文件,将swift需要调用的TestThreeVC引入

#ifndef frameworkPrivateHeader_h
#define frameworkPrivateHeader_h
#import "TestThreeVC.h"
#endif

2、创建.modulemap 文件

framework module frameworkProject[system] {
  umbrella header "frameworkPrivateHeader.h"
  export *
}

image.png 3、在framework工程 build Setting -> Swift Compiler-Language -> Import Paths 中引入 module.modulemap,添加路径 image.png

$(SRCROOT)/frameworkProject/

build。 Fail! Fail! Fail!

image.png

module里面的名称不能与工程名相同,改为 "frameworkPrivate" image.png 需要在TestTwoVC.swift 文件中 import frameworkPrivate

build。 SUCCESS! 终于成功了。

module.modulemap文件最终内容为

module frameworkPrivate [system] {
    header "frameworkPrivateHeader.h"
    export *
}

umbrella header的说明可以参考: # iOS - Umbrella Header在framework中的应用