混編下橋接文件的配置和使用

版本記錄

版本號 時間
V1.0 2017.08.13

前言

OCSwift進(jìn)行混編時,就需要橋接文件的設(shè)定,這樣就可以OCSwfit達(dá)到混編和實現(xiàn)功能。

Swift工程代碼中混編OC

下面我們先看一個例子。

1. 創(chuàng)建OC文件

先建立一個工程JJBridgeSwift,在這個swift工程文件里面我們新建立個OC文件,如下圖所示。

新建立OC文件

這個時候,有一點注意,由于工程是swift寫的,后加的OC文件,只有這種第一次新建不同語言文件的時候會彈出下面的對話框。

新建立橋接文件對話框

3. 彈出創(chuàng)建橋接文件對話框

這里有兩個結(jié)果:

  • Don‘t Create : 點擊這個以后,不會建立橋接文件,并且以后無論在工程里面創(chuàng)建多少個異種語言寫的文件都不會再彈出這個對話框,也就是說這個對話框只自動跳出來一次。

  • Create Bridging Header:點擊這個就會創(chuàng)建橋接文件,如下所示。

自動創(chuàng)建的橋接文件

我這里點擊Create Bridging Header

4. 橋接文件自動配置

我這里點擊的創(chuàng)建橋接文件,下面就要對橋接文件進(jìn)行配置。

注意:我這里單擊的是自動創(chuàng)建橋接文件,所以工程已經(jīng)給配置好了,并不需要我們手動進(jìn)行配置,可以看見如下圖所示。

橋接文件的自動配置

5. 代碼驗證

下面我們就看一下代碼驗證。

1. AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        window = UIWindow(frame: UIScreen.main.bounds);
        let vc = JJProjectSwiftVC()
        let nav = UINavigationController(rootViewController: vc)
        window?.rootViewController = nav
        window?.makeKeyAndVisible()

        return true
    }
}
2. JJProjectSwiftVC.swift
import UIKit

class JJProjectSwiftVC: UIViewController
{

    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        let vc = JJAddOCVC()
        vc.label = 10;
    }
}
3. JJAddOCVC.h
#import <UIKit/UIKit.h>

@interface JJAddOCVC : UIViewController

@property (nonatomic, assign) NSInteger label;

@end
4. JJAddOCVC.m
#import "JJAddOCVC.h"

@interface JJAddOCVC ()

@end

@implementation JJAddOCVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
}

#pragma mark - Getter && Setter

- (void)setLabel:(NSInteger)label
{
    _label = label;
    
    NSLog(@"%ld", self.label);
}

@end

下面看輸出結(jié)果

2017-08-13 19:25:13.525795+0800 JJBridgeSwift[9331:4127976] 10

至此,swift工程中混編OC文件結(jié)束了,下面我們就看手動的配置橋接文件的過程。

6. 手動創(chuàng)建橋接文件

首先創(chuàng)建一個OC文件JJAddManualVC,設(shè)置橋接文件。

生成橋接文件

我們要給橋接文件起一個名字,如下圖所示。

給橋接文件起名字

接著就開始編輯橋接文件。

//
//  Header.h
//  JJBridgeSwift
//
//  Created by lucy on 2017/8/13.
//  Copyright ? 2017年 com.qunar.com. All rights reserved.
//

#ifndef Header_h
#define Header_h

#import "JJAddManualVC.h"

#endif /* Header_h */

接著就配置橋接文件的路徑。

這里橋接文件的配置路徑不用自己寫,雙擊直接將Header文件拖進(jìn)去,這里要注意,拖進(jìn)去后里面顯示的是全路徑,而我們要將其設(shè)置為相對路徑,如下圖所示,刪掉綠色的部分。

橋接文件的設(shè)置

這里代碼就不多給出了,還是一樣的測試代碼,給出輸出結(jié)果。

2017-08-13 19:53:31.431244+0800 JJBridgeSwift[9335:4132540] 10

上面給出了swift工程里面oc文件自動生成橋接文件和手動生成橋接文件的方法。


OC工程代碼中混編Swift

下面我們就看一下OC工程中混編Swift的情況。

1. 自動生成橋接文件

添加swift文件
提示生成橋接文件

這里我點擊第三個生成橋接文件。

系統(tǒng)進(jìn)行自動配置
橋接文件的編輯

這里橋接文件里面什么都不用寫。

我們點擊文件JJProjectOCVC中的JJAddSwiftVC,就會跳轉(zhuǎn)到自動生成的文件中,這個文件是系統(tǒng)自動生成的。

// Generated by Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)
#pragma clang diagnostic push

#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif

#pragma clang diagnostic ignored "-Wauto-import"
#include <objc/NSObject.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#if !defined(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# if defined(__has_include) && __has_include(<uchar.h>)
#  include <uchar.h>
# elif !defined(__cplusplus) || __cplusplus < 201103L
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
# endif
typedef float swift_float2  __attribute__((__ext_vector_type__(2)));
typedef float swift_float3  __attribute__((__ext_vector_type__(3)));
typedef float swift_float4  __attribute__((__ext_vector_type__(4)));
typedef double swift_double2  __attribute__((__ext_vector_type__(2)));
typedef double swift_double3  __attribute__((__ext_vector_type__(3)));
typedef double swift_double4  __attribute__((__ext_vector_type__(4)));
typedef int swift_int2  __attribute__((__ext_vector_type__(2)));
typedef int swift_int3  __attribute__((__ext_vector_type__(3)));
typedef int swift_int4  __attribute__((__ext_vector_type__(4)));
typedef unsigned int swift_uint2  __attribute__((__ext_vector_type__(2)));
typedef unsigned int swift_uint3  __attribute__((__ext_vector_type__(3)));
typedef unsigned int swift_uint4  __attribute__((__ext_vector_type__(4)));
#endif

#if !defined(SWIFT_PASTE)
# define SWIFT_PASTE_HELPER(x, y) x##y
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
#endif
#if !defined(SWIFT_METATYPE)
# define SWIFT_METATYPE(X) Class
#endif
#if !defined(SWIFT_CLASS_PROPERTY)
# if __has_feature(objc_class_property)
#  define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
# else
#  define SWIFT_CLASS_PROPERTY(...)
# endif
#endif

#if defined(__has_attribute) && __has_attribute(objc_runtime_name)
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
#else
# define SWIFT_RUNTIME_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(objc_method_family)
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
#else
# define SWIFT_METHOD_FAMILY(X)
#endif
#if defined(__has_attribute) && __has_attribute(noescape)
# define SWIFT_NOESCAPE __attribute__((noescape))
#else
# define SWIFT_NOESCAPE
#endif
#if defined(__has_attribute) && __has_attribute(warn_unused_result)
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define SWIFT_WARN_UNUSED_RESULT
#endif
#if !defined(SWIFT_CLASS_EXTRA)
# define SWIFT_CLASS_EXTRA
#endif
#if !defined(SWIFT_PROTOCOL_EXTRA)
# define SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_ENUM_EXTRA)
# define SWIFT_ENUM_EXTRA
#endif
#if !defined(SWIFT_CLASS)
# if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted)
#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
#  define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# else
#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
#  define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# endif
#endif

#if !defined(SWIFT_PROTOCOL)
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
#endif

#if !defined(SWIFT_EXTENSION)
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
#endif

#if !defined(OBJC_DESIGNATED_INITIALIZER)
# if defined(__has_attribute) && __has_attribute(objc_designated_initializer)
#  define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
#  define OBJC_DESIGNATED_INITIALIZER
# endif
#endif
#if !defined(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
# if defined(__has_feature) && __has_feature(generalized_swift_name)
#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type
# else
#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name)
# endif
#endif
#if !defined(SWIFT_UNAVAILABLE)
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#if !defined(SWIFT_AVAILABILITY)
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
#endif
#if !defined(SWIFT_DEPRECATED)
# define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#if defined(__has_feature) && __has_feature(modules)
@import UIKit;
#endif

#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
@class NSBundle;
@class NSCoder;

SWIFT_CLASS("_TtC10JJBridgeVC12JJAddSwiftVC")
@interface JJAddSwiftVC : UIViewController
- (void)viewDidLoad;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end

#pragma clang diagnostic pop

下面看一下驗證代碼。

1. JJProjectOCVC.m
#import "JJProjectOCVC.h"
#import "JJBridgeVC-Swift.h"

@interface JJProjectOCVC ()

@end

@implementation JJProjectOCVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    JJAddSwiftVC *vc = [[JJAddSwiftVC alloc] init];
    vc.view.backgroundColor = [UIColor greenColor];
}

@end
2. JJAddSwiftVC.swift
import UIKit

class JJAddSwiftVC: UIViewController {

    override func viewDidLoad()
    {
        super.viewDidLoad()

        print("I am here")
    }
}

下面看輸出結(jié)果

I am here

2. 手動生成橋接文件

重新建立一個新的swift文件JJAddManualSwiftVC.swift

下面我們就看一下手動配置橋接文件,也就是說在彈出創(chuàng)建橋接文件的時候選擇Don't Create

用同樣的方法建立一個Header文件。下面我們就會發(fā)現(xiàn)剛才系統(tǒng)自動生成的文件#import "JJBridgeVC-Swift.h"中多出來新建立的swift類的相關(guān)代碼JJAddManualSwiftVC,如下圖所示。

SWIFT_CLASS("_TtC10JJBridgeVC18JJAddManualSwiftVC")
@interface JJAddManualSwiftVC : UIViewController
- (void)viewDidLoad;
- (void)didReceiveMemoryWarning;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end


SWIFT_CLASS("_TtC10JJBridgeVC12JJAddSwiftVC")
@interface JJAddSwiftVC : UIViewController
- (void)viewDidLoad;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end

我們將這文件里面所有的東西都復(fù)制到新的橋接文件Header.h中,這個時候我們就在OC文件中引用頭文件Header.h即可;還有一個方法就是不做任何處理,這個時候就需要在OC文件中引用頭文件#import "JJBridgeVC-Swift.h",這樣也是可以編譯通過的。

下面對Header.h文件進(jìn)行工程配置。

工程配置

下面看一下代碼。

1. JJProjectOCVC.m
#import "JJProjectOCVC.h"

//自動
#import "JJBridgeVC-Swift.h"

//手動
//#import "Header.h"

@interface JJProjectOCVC ()

@end

@implementation JJProjectOCVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    JJAddManualSwiftVC *vc = [[JJAddManualSwiftVC alloc] init];
    vc.view.backgroundColor = [UIColor greenColor];
}

@end
2. JJAddManualSwiftVC.swift
import UIKit

class JJAddManualSwiftVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        print("I am also here")
    }
}

下面看輸出結(jié)果

I am also here

后記

這些東西都很簡單,大家看看就好,沒事的時候就總結(jié)下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 前言: Swift語言出來后,可能新的項目直接使用Swift來開發(fā),但可能在過程中會遇到一些情況,某些已用OC寫好...
    瘋狂的電腦閱讀 2,318評論 0 9
  • 前言 點擊簡書寫文章的時候發(fā)現(xiàn)還有幾篇文章只寫了標(biāo)題,內(nèi)容還沒有寫。所以現(xiàn)在趁著午休時間,把這篇文章完善一下。看到...
    CoderXLL閱讀 32,355評論 12 31
  • 亮點一:對于Xcode提示建立橋接文件時,誤點cancel后的處理方法 亮點二:SDK開發(fā)的時候,OC與Swift...
    素顏約定閱讀 2,597評論 0 1
  • 為什么要選擇Swift 從2014年蘋果推出Swift1.0到今年9月份的Swift5.1已經(jīng)過去了5年,平均每年...
    quantiza閱讀 11,728評論 1 17
  • 前言 Swift已推出數(shù)年,與Objective-C相比Swift的語言機制及使用簡易程度上更接地氣,大大降低了i...
    仁伯閱讀 18,992評論 30 76