1. 程式人生 > >iOS8開發~Swift(五)Swift與OC混編

iOS8開發~Swift(五)Swift與OC混編

一、概要

首先看《The Swift Programming Language》中提到“Swift’s compatibility with Objective-C lets you create a project that contains files written in either language. ”,意思是在一個專案中可以混合使用Swift和Objective-C,你可能有疑問了:

1、如何讓兩種語言在一個專案中使用? 

2、混編的專案是“Swift專案”還是“OC專案”?

3、混編過程中,需要注意哪些細節?

僅憑看文件可能會感覺沒有頭緒,所以還是實際動手試一試吧。

二、混編

1、OC專案中混編

(1)首先建立一個專案,命名TestOC,語言選擇Objective-C,不熟悉的可以參考這裡

(2)建立好專案後,在專案中新增一個新檔案 New File -> Cocoa Class 語言選擇Swift,命名為FileTest,選擇Create的時候,會彈出如下頁面:


選擇Yes,然後Xcode不僅建立了 FileTest.swift 檔案,還建立了 TestOC-Bridging-Header.h 檔案


這個檔案什麼作用,看文件:


向一個OC專案中新增Swift檔案或者向一個Swift專案中新增OC檔案,Xcode會自動生成ProName-Bridging-Header.h,作用就是告訴OC專案或Swift專案

,這個Swift檔案或者OC檔案對外提供的內容,從命名“Bridging”也能大概猜到檔案的用意。

選擇直接編譯會報錯,不要著急,修改剛建立的檔案 FileTest.swift 中的程式碼:

import Foundation

@objc(FileTest)
class FileTest: NSObject {
    @objc(initWithData:)
    init (data: String) {
        println(data)
    }
}

這裡看到了 @objc()這種奇怪到寫法,官網是這樣描述的,意思是用@objc()想讓一個Swift類被OC呼叫


 選擇Swift檔案中的類也定義好了,但發現在OC沒辦法呼叫,因為OC選擇找不到 FileTest 類,這就需要配置一個引數:Build Setting -> Product Module Name,預設是沒有配置的,Target -> Build Setting  ->Defines Module修改成Yes:


選擇在需要使用Swift檔案類的地方引入標頭檔案:#import "MyTest-Swift.h",然後在看效果:


Swift中定義的類,可以在OC中使用了,MyTest-Swift.h 檔案是什麼?他是Xcode自動建立的,點選進去看看裡邊有什麼:


這樣就幾乎明白個七七八八了。

現在可以實現OC中呼叫Swift了,那Swift中如何呼叫OC呢,直接修改Swift檔案:


發現這樣不行,Swift檔案沒有找到ViewController這個OC的檔案,這個時候橋接標頭檔案就有用處了,修改 TestOC-Bridging-Header.h


再次編譯執行,發現沒問題了。

2、Swift專案中混編

(1)首先建立一個專案,命名TestSwift,語言選擇Swift,不熟悉的可以參考這裡

(2)建立好專案後,在專案中新增一個新檔案 New File -> Cocoa Class 語言選擇OC,命名為FileTest,點選Create後仍然會提示是否建立橋接檔案,選擇Yes:


下面來說說Swift檔案中呼叫OC:

開啟ViewController.swift,新增如下程式碼

import UIKit

class ViewController: UIViewController {
                            
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        var test = FileTest()
    }
    
    func customFun() {
    }
    
    func customFun1() {
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

是不是報錯啦?


因為OC沒有告訴Swift可以訪問我哪些內容,很簡單,在橋接檔案中新增: #import"FileTest.h",告訴Swift,OC中FileTest可以訪問:


現在編譯執行,沒問題了吧!

再來說說OC檔案中呼叫Swift:

在 FileTest.m 中新增程式碼:

#import "FileTest.h"

@implementation FileTest

- (void) test {
    ViewController *viewCtr = [[ViewController alloc] init];
    NSLog(@"%@", viewCtr);
}

@end

發現報錯,找不到ViewController,沒關係,缺少標頭檔案,Target -> Build Setting  ->Product Module Name ,修改為MyTest,Target -> Build Setting  ->Defines Module修改成Yes。在FileTest.m中新增#import"MyTest-Swift.h",現在再編譯執行,沒問題了吧。
#import "FileTest.h"
#import "MyTest-Swift.h"

@implementation FileTest

- (void) test {
    ViewController *viewCtr = [[ViewController alloc] init];
    NSLog(@"%@", viewCtr);
}

@end

點選進入Xcode生成的檔案 MyTest-Swift.h ,所有可呼叫的Swift程式碼都在這裡,包括我們自己寫的方法:


如果想使用第三方Framework怎麼辦?官方文件這麼說的:


其實也不難,開啟專案配置檔案Target -> Build Phases  -> Link Binary With Libraryer,新增你要匯入的Framework,如果是第三方的庫,可以選擇Add Other(我這裡選擇的是第三方的Framework,也是我自己打包的庫):


這樣目錄結構中可以看到庫了:


使用很簡單,首先還是要配置下橋接檔案,比如我想使用 kalagame-library.framework庫中的 KalaGameApi.h 就要這樣配置:#import"kalagame-library/KalaGameApi.h"

然後這樣呼叫: var test1 = KalaGameApi(),現在基本的混編知識點就介紹完了。

更多內容見官網文件

由於對官網文件的理解可能不到位,可能對問題的理解有偏差,如果發現錯誤,還請指正,不勝感激。更多內容請點選這裡

歡迎加入群共同學習和進步:QQ群:170549973