Swift 調(diào)用 OC 實用技巧

Swift App

混入OC/C/C++代碼

方法一

使用橋接文件锈玉。

方法二

使用.modulemap

  1. Swift App項目废亭,引入OC/C/C++文件。
  2. 創(chuàng)建文件名必須為module 后綴為.modulemap的文件穿香。
image.png
  1. 配置工程BuildSettingSwift Compiler - Search Paths選項,值為module.modulemap文件所在的目錄路徑或其上層目錄路徑称开。
image.png

此處可為:

${SRCROOT}/MixFrameworkTest
${SRCROOT}/MixFrameworkTest/ObjcInSwitApp

如果這里的路徑配置不正確便會報錯:error build: No such module '*'

4.配置module.modulemap內(nèi)容

module OcInApp {
    // 所引入頭文件相對于`.modulemap`的路徑; "./OcClassInApp.h"也可以
    header "OcClassInApp.h" 
    export *
}
  1. import導(dǎo)入使用
import OcInApp
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        OcClassInApp.description()
    }
}

混入OC Framework

如果引入的OC FrameWork中含有Modules/module.modulemap文件舞骆,則直接拖入Swift工程中钥弯,使用import引入并進行調(diào)用即可。

如果OC FrameWork不支持modulemap(沒有module.modulemap文件)督禽,則有兩種方法:

方法一

建立橋接文件脆霎,按需導(dǎo)入頭文件

方法二

基于OC FrameWork/Modules/module.modulemap路徑,創(chuàng)建module.modulemap文件狈惫,并輸入以下內(nèi)容并保存睛蛛,之后便可使用import引入并進行調(diào)用。

// 按需導(dǎo)入
framework module SameAsFrameWorkName { //必須與導(dǎo)入的`OC Framework`同名
  header "A.h"
  header "B.h"
  header "b.h"
  //..
  export *
}
///遞歸導(dǎo)入
framework module SameAsFrameWorkName { //必須與導(dǎo)入的`OC Framework`同名
  umbrella header "SameAsFrameWorkName.h" //SDK對外頭文件胧谈,包含SDK對外暴露的諸多.h文件

  export *
  module * { export * }
}

混入OC xcframework

與混入OC framework操作基本一致忆肾,如果引入的OC xcframework下不同的架構(gòu)文件下的framework中含有Modules/module.modulemap文件,則直接拖入Swift工程中菱肖,使用import引入并進行調(diào)用即可客冈。

如果OC xcframework不支持modulemap,也是有兩種方法:

方法一

建立橋接文件稳强,按需導(dǎo)入頭文件场仲。

方法二

OC xcframework下不同架構(gòu)framework和悦,參考混入OC framework的方法二,即可調(diào)用渠缕。

Swift Framework

Swift Framework鸽素,僅有Swift類時,如果是需要SDK外部使用的ClassMethod亦鳞,則只需要使用publicopen修飾馍忽。

image.png

Swift工程導(dǎo)入Swift Framework后,直接在Swift的工程中使用即可燕差。

import RadarSDK
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        RadarEntry.start()
    }
}

注意:Swift Framework中是不支持使用橋接文件的遭笋,不然的話會報錯:

image.png

混入OC/C/C++代碼

示例工程結(jié)構(gòu)如下:

image.png

內(nèi)部使用 OC

SDK內(nèi)部的Swift類,不能直接使用OC的代碼徒探,并且不支持橋接文件坐梯。因此只能使用module.modulemap文件

  1. 創(chuàng)建文件名必須為module 后綴為.modulemap的文件。
  2. 配置工程BuildSettingSwift Compiler - Search Paths選項刹帕,值為module.modulemap文件所在的目錄路徑或其上層目錄路徑,此處可為:
${SRCROOT}/SwiftMixSDK/ObjcSources
${SRCROOT}/SwiftMixSDK
  1. 配置module.modulemap內(nèi)容
module ObjcInFramwork {
    header "ObjcClassA.h"
    header "ObjcClassB.h"
    export *
}
  1. 使用
import ObjcInFramwork
public class SwiftMixTest: NSObject {
   public static func mixTest() {
        ObjcClassA.description()
        print("Swift MixIn OC")
    }
}

外部使用OC

如果Swift Framework外部需要調(diào)用混入的OC谎替,有兩種方法:

方法一

Swift Framework外接.h頭文件以#import <SwiftMixSDK/PublicHeader.h>的方法對外公開需要使用的OC頭文件偷溺。

  1. 配置 Frame Targetbuild Phases,使得OC頭文件公開
image.png


image.png
  1. Swift Framework外接.h文件import需要公開的OC頭文件
    image.png
  1. 使用
import UIKit
import SwiftMixSDK
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        SwiftMixTest.mixTest()
        ObjcClassA.description()
        ObjcClassB.description()
    }
}
  1. 編譯最終產(chǎn)物對外暴露的頭文件
image.png


image.png

方法二

自定義Swift Framework.modulemap文件钱贯。

  1. 自定義module.modulemap文件挫掏;此處的文件名不強制module,但建議用module秩命,因為編譯器最終會合并自定義的文件尉共,最終導(dǎo)出module.modulemap文件。
  2. 配置 Frame Targetbuild Setting弃锐,保證Define ModuleYES; Module Map File 為自定義.modulemap文件的路徑袄友。
image.png
  1. 配置module.modulemap內(nèi)容
framework module SwiftMixSDK {
    umbrella header "SwiftMixSDK.h"
    export *
    module * {export *}
    module ObjcInFramwork {
        header "/Users/*/Desktop/*/SwiftSDKExample/SwiftMixSDK/ObjcSources/ObjcClassA.h"
        header "/Users/*/Desktop/*/SwiftSDKExample/SwiftMixSDK/ObjcSources/ObjcClassB.h"
        export *
    }
}

最終SDKmodulemap:

image.png

值得注意的是,此處的header,只能使用絕對路徑霹菊,否則會出錯剧蚣。 stackoverflow此問題的QA

  1. 使用
import UIKit
import SwiftMixSDK.ObjcInFramwork
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        SwiftMixTest.mixTest()
        ObjcClassA.description()
        ObjcClassB.description()
    }
}
  1. 編譯最終產(chǎn)物對外暴露的頭文件
image.png

小結(jié)

綜上可以看出,兩種方法編譯的最終產(chǎn)物存在差異:

方法一會暴露OC頭文件的旋廷;方法二會隱藏OC的頭文件鸠按。
多人協(xié)作開發(fā)Swift Framework時,方法二會存在頻繁修改.modulemap文件文件饶碘。因此實際開發(fā)中還得基于項目決定方案目尖。

混入OC Framework

OC Framework不支持Module時,有兩種方式混入OC Framework扎运。

方法一

通過使用.modulemap文件瑟曲,實現(xiàn)對OC Framework調(diào)用饮戳。即:OC Framework支持(自動或者手動)module

方法二

參考上述 混入OC/C/C++代碼 —— 內(nèi)部使用OC 测蹲,創(chuàng)建module.modulemap文件莹捡,配置相關(guān)Building Setting。配置module.modulemap內(nèi)容如下:

module ObjcFramwork {
    ///相對于module.modulemap的相對路徑
    umbrella header "../ObjcFramwork.framework/Headers/ObjcFramwork.h"
    export *
    module * { export * }
}

最后在Swift文件中import ObjcFramwork扣甲,即可調(diào)用篮赢。

混入OC xcframework

OC xcframework不支持Module時,有兩種方式混入OC xcframework琉挖。

方法一
OC xcframework下不同架構(gòu)framework启泣,參考混入OC Framework方法一,進行操作后即可調(diào)用示辈。

方法二

參考上述 混入OC/C/C++代碼 —— 內(nèi)部使用OC 寥茫,創(chuàng)建module.modulemap文件,配置相關(guān)Building Setting矾麻;

這些操作與混入OC Framework方法二一致纱耻,唯一有區(qū)別在于:OC xcframework包含多種架構(gòu)的Framework

image.png

因此不能通過相對路徑直接引入险耀,因為不同架構(gòu)路徑下的同一個頭文件會相互覆蓋而報錯弄喘;

image.png

如何解決呢?我們可以通過新建一個ObjcXCFramwork-umbrella.h文件(可以是其它名稱)甩牺,并在其中引入xcframework的頭文件:

#import <MyTestSDK/MyTestSDK.h>

然后配置module.modulemap內(nèi)容如下:

module ObjcXCFramwork {
  umbrella header "ObjcXCFramwork-umbrella.h"

  export *
  module * { export * }
}

最后在Swift文件中import ObjcXCFramwork蘑志,即可調(diào)用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贬派,一起剝皮案震驚了整個濱河市急但,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌搞乏,老刑警劉巖波桩,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異请敦,居然都是意外死亡突委,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門冬三,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匀油,“玉大人,你說我怎么就攤上這事勾笆〉醒粒” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵窝爪,是天一觀的道長弛车。 經(jīng)常有香客問我齐媒,道長,這世上最難降的妖魔是什么纷跛? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任喻括,我火速辦了婚禮,結(jié)果婚禮上贫奠,老公的妹妹穿的比我還像新娘唬血。我一直安慰自己,他們只是感情好唤崭,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布拷恨。 她就那樣靜靜地躺著,像睡著了一般谢肾。 火紅的嫁衣襯著肌膚如雪腕侄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天芦疏,我揣著相機與錄音冕杠,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的艺谆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼魁淳!你這毒婦竟也來了飘诗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤界逛,失蹤者是張志新(化名)和其女友劉穎昆稿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體息拜,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡溉潭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了少欺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喳瓣。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赞别,靈堂內(nèi)的尸體忽然破棺而出畏陕,到底是詐尸還是另有隱情,我是刑警寧澤仿滔,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布惠毁,位于F島的核電站犹芹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏鞠绰。R本人自食惡果不足惜腰埂,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜈膨。 院中可真熱鬧屿笼,春花似錦、人聲如沸丈挟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽曙咽。三九已至蛔趴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間例朱,已是汗流浹背孝情。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留洒嗤,地道東北人箫荡。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像渔隶,于是被迫代替她去往敵國和親羔挡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容