優雅的開發 Swift 和 Objective-C 混編的 Framework

發表於2017-04-06

前言

為什麼要寫這樣一篇文章,因為昨天和一個朋友討論到Swift和Objective C如何混合開發Framework,中途發現了很多有意思的坑。

用Swift封裝OC的庫是一件比較常見的事情,畢竟對於大多數公司來說,老的程式碼都是用OC寫的,而且經過多次迭代,這些OC的程式碼已經被驗證了是穩定的,用Swift重寫代價太大。這就引入了一個需求:

  • 用Swift和OC來混編一個Framework。

如果你之前沒有用Swift和Objective C混合開發,建議看看這篇文件:

這篇文件很詳細的講解了如何運用Objective C和Swift進行混合開發App和Framework。於是,我們先按照文件來寫一個混編的Framework


按照文件一步一步來

新建一個基於單頁面工程,然後新建一個一個Target,選中Cocoa Touch Framework。然後,分別新建一個Swift檔案和Objective C類,注意Target Member Ship選中Framework。類的內容如下:

OCSource.h

OCSource.m

Swift呼叫OC

新建SwiftSource.swift

然後,按照文件中,為了讓Swift檔案訪問Objective C檔案,我們應該在umbrella header,也就是MixFramework.h中,暴露所需要的header。

也就是,MixFramework.h,

然後,自信滿滿的點選build。

Boom~~~,編譯不通過。

優雅的開發 Swift 和 Objective-C 混編的 Framework

原因:OCSource.h預設編譯的時候是Project許可權. 為了在umbrella header中使用,要把這個檔案的許可權改成Public

按照圖中的方式拖過去即可。

優雅的開發 Swift 和 Objective-C 混編的 Framework

嗯,現在build,可以看到build成功了。

OC呼叫Swift

在SwiftSource.swift中,增加一個類,

然後,為了在OC中呼叫Swift的方法,我們需要匯入標頭檔案,這時候,OCSource.m檔案內容如下

然後,build,發現成功了,很開心。


外部呼叫

在ViewController.swift中,我們呼叫Framework中的內容。

然後執行,發現控制檯列印出

嗯,framework打包成功了。


問題

通常,我們希望暴露給外部的介面是純Swift,而OC檔案的具體介面應該隱藏,這就是我標題中的優雅兩個字的含義。

如果你好奇,你會發現,在ViewController.swift中你可以這麼呼叫

也就是說,OC的內容也暴露出來了,這破壞了Framework的封裝特性

通過檢視MixFramework的編譯結果,發現最後暴露出的介面是這樣子的

這一行,把OC對應的實現暴露出來了


優雅的解決方案

不再通過umbrella header的方式讓framework中的Swift呼叫OC方法。而是通過modulemap

新建一個module.modulemap檔案,內容如下

優雅的開發 Swift 和 Objective-C 混編的 Framework

這裡的#(SRCROOT)是XCode的巨集,會自動替換成專案所在的根目錄,這裡輸入的路徑是module.modulemap檔案所在的路徑。

然後,刪除MixFramework.h(umbrella header)中#import 的OC header。

把OCSource.h的許可權改回預設的project。

優雅的開發 Swift 和 Objective-C 混編的 Framework

再編譯,發現OC的類被隱藏了。


總結

如果你要開發一個framework,一定要想清楚哪些介面暴露出去,哪些封裝起來,framework不是簡單把一包檔案加個殼子。

相關文章