最近在开发vision os的时候需要经常兼容oc写的老代码,一般在不涉及库的情况下,项目的swift和oc互相调用比较简单:
* swift调用oc采用桥接文件的方式
* oc调用swift采用#import "xx-swift.h"的方式
但是在涉及到自己编写的库的时候存在一些坑,这里一并记录,最终能够达到无论在项目中,还是在库中,还是项目调库(库调项目不符合逻辑)都能够做到swift和oc无缝衔接
一、原OC项目的文件目录为:
|- MySDK.xcodeproj
|-- MySDK
|
|--- Example
|----- example.h
|----- example.m
|
|- Frameworks
╰
在MySDK.xcodeproj所在目录新建MySDK.podspec,填入相关内容后到当前项目中
二、当前项目的文件目录为:
|- Your Project
|- ...
|
|- Pods
|-- Podfile
|
|-- Development Pods
|
|--- MySDK
|
|---- Swift-Code
|----- example.swift(文件名自定义)
|
|---- OC-Code
|----- example.h
|----- example.m
|
|---- Pod
|----- MySDK.podspec
|
|-- Frameworks
|-- Products
|-- Targets Support Files
╰
在当前项目的Your project.xcodeproj所在目录下执行pod init之后就可以看到Podfile文件,
在Podfile文件中添加
pod 'MySDK',:path => '找到自己原OC项目的 .../MySDK.podspec'
之后执行pod install同步自己的库到当前项目中
三、当前项目 Your Project 中调用 MySDK 库中的 Swift 代码
上述pod install配置后,直接通过 import MySDK就可以调用库内的 Swift 类
四、当前项目 Your Project 中调用 MySDK 库中的 OC 代码
上述pod install配置后,建立桥接文件 bridge.h ,在 Your Project 的Build Settings右侧filter中搜索bridge,找到
在Objective-C Bridging Header中配置路径
$(SRCROOT)/bridge.h
在bridge.h中添加需要引入的oc代码
#import "example.h"
之后在当前项目中调用库中的OC类即可
五、自编库 MySDK 内 OC 调用自己库内写的 Swift 代码:
直接调用:
在oc文件中添加 #import "自编库名/自编库名-swift.h"
这个自编库名-swift.h是Xcode自动生成的,所以直接import即可
#import "MySDK/MySDK-swift.h"
调用完成后,直接在oc文件里就可以使用swift的类
六、自编库 MySDK 内 Swift 调用自己库内写的 OC 代码:
最普遍的想法:创建桥接文件
但是Xcode报错Using bridging headers with framework targets is unsupported
所以采用module.map调用:
在原项目中创建文件夹PublicHeader(直接创建文件也可以)后,创建文件:MySDKPublicHeader.h 和 module.modulemap,目录如下:
|- MySDK.xcodeproj
|-- MySDK
|
|--- PublicHeader
|---- MySDKPublicHeader.h
|---- module.modulemap
|
|--- Example
|----- example.h
|----- example.m
|
|- Frameworks
╰
MySDKPublicHeader.h中的内容为:
#import <Foundation/Foundation.h>
#import "../Example/example.h"
NS_ASSUME_NONNULL_BEGIN
@interface MySDKPublicHeader : NSObject
@end
NS_ASSUME_NONNULL_END
module.modulemap中的内容为:
module MySDK[system]{
umbrella header "MySDKPublicHeader.h"
export *
}
之后在当前项目Podfile所在的位置执行:pod install
就可以在当前项目的Pods/Development Pods/MySDK目录中看到PublicHeader/MySDKPublicHeader.h(module.modulemap看不到的)
最重要的一步:在Pods的Build Settings中,右侧filter搜索import,找到
在Import Path中配置原项目的PublicHeader路径,不要到.h,只到目录,可以采用$(SRCROOT)/../../../ 的形式从当前项目跳转到原项目
然后在example.swift中导入module.modulemap中定义的oc module名
import MySDK
之后就可以在swift中调用oc的类了
至此,无论是在项目中,还是在库中,还是项目调库,(库调项目不符合逻辑)都没有Swift和OC的隔阂了,撒花~