混编下桥接文件的配置和使用

版本记录

版本号 时间
V1.0 2017.08.13

前言

OCSwift进行混编时,就需要桥接文件的设定,这样就可以OCSwfit达到混编和实现功能。

Swift工程代码中混编OC

下面我们先看一个例子。

1. 创建OC文件

先建立一个工程JJBridgeSwift,在这个swift工程文件里面我们新建立个OC文件,如下图所示。

新建立OC文件

这个时候,有一点注意,由于工程是swift写的,后加的OC文件,只有这种第一次新建不同语言文件的时候会弹出下面的对话框。

新建立桥接文件对话框

3. 弹出创建桥接文件对话框

这里有两个结果:

  • Don‘t Create : 点击这个以后,不会建立桥接文件,并且以后无论在工程里面创建多少个异种语言写的文件都不会再弹出这个对话框,也就是说这个对话框只自动跳出来一次。

  • Create Bridging Header:点击这个就会创建桥接文件,如下所示。

自动创建的桥接文件

我这里点击Create Bridging Header

4. 桥接文件自动配置

我这里点击的创建桥接文件,下面就要对桥接文件进行配置。

注意:我这里单击的是自动创建桥接文件,所以工程已经给配置好了,并不需要我们手动进行配置,可以看见如下图所示。

桥接文件的自动配置

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

下面看输出结果

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

至此,swift工程中混编OC文件结束了,下面我们就看手动的配置桥接文件的过程。

6. 手动创建桥接文件

首先创建一个OC文件JJAddManualVC,设置桥接文件。

生成桥接文件

我们要给桥接文件起一个名字,如下图所示。

给桥接文件起名字

接着就开始编辑桥接文件。

//
//  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文件拖进去,这里要注意,拖进去后里面显示的是全路径,而我们要将其设置为相对路径,如下图所示,删掉绿色的部分。

桥接文件的设置

这里代码就不多给出了,还是一样的测试代码,给出输出结果。

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

上面给出了swift工程里面oc文件自动生成桥接文件和手动生成桥接文件的方法。


OC工程代码中混编Swift

下面我们就看一下OC工程中混编Swift的情况。

1. 自动生成桥接文件

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

这里我点击第三个生成桥接文件。

系统进行自动配置
桥接文件的编辑

这里桥接文件里面什么都不用写。

我们点击文件JJProjectOCVC中的JJAddSwiftVC,就会跳转到自动生成的文件中,这个文件是系统自动生成的。

// 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")
    }
}

下面看输出结果

I am here

2. 手动生成桥接文件

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

下面我们就看一下手动配置桥接文件,也就是说在弹出创建桥接文件的时候选择Don't Create

用同样的方法建立一个Header文件。下面我们就会发现刚才系统自动生成的文件#import "JJBridgeVC-Swift.h"中多出来新建立的swift类的相关代码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

我们将这文件里面所有的东西都复制到新的桥接文件Header.h中,这个时候我们就在OC文件中引用头文件Header.h即可;还有一个方法就是不做任何处理,这个时候就需要在OC文件中引用头文件#import "JJBridgeVC-Swift.h",这样也是可以编译通过的。

下面对Header.h文件进行工程配置。

工程配置

下面看一下代码。

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")
    }
}

下面看输出结果

I am also here

后记

这些东西都很简单,大家看看就好,没事的时候就总结下。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 前言: Swift语言出来后,可能新的项目直接使用Swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好...
    疯狂的电脑阅读 2,253评论 0 9
  • 前言 点击简书写文章的时候发现还有几篇文章只写了标题,内容还没有写。所以现在趁着午休时间,把这篇文章完善一下。看到...
    CoderXLL阅读 31,729评论 12 31
  • 亮点一:对于Xcode提示建立桥接文件时,误点cancel后的处理方法 亮点二:SDK开发的时候,OC与Swift...
    素颜约定阅读 2,446评论 0 1
  • 为什么要选择Swift 从2014年苹果推出Swift1.0到今年9月份的Swift5.1已经过去了5年,平均每年...
    quantiza阅读 11,562评论 1 17
  • 前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了i...
    仁伯阅读 18,850评论 30 76