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

版本记录

版本号 时间
V1.0 2017.08.13

前言

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

Swift工程代码中混编OC

下面我们先看一个例子。

1. 创建OC文件

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

混编下桥接文件的配置和使用_第1张图片
新建立OC文件

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

混编下桥接文件的配置和使用_第2张图片
新建立桥接文件对话框

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

这里有两个结果:

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

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

混编下桥接文件的配置和使用_第3张图片
自动创建的桥接文件

我这里点击Create Bridging Header

4. 桥接文件自动配置

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

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

混编下桥接文件的配置和使用_第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 

@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,设置桥接文件。

混编下桥接文件的配置和使用_第5张图片
生成桥接文件

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

混编下桥接文件的配置和使用_第6张图片
给桥接文件起名字

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

//
//  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 */

接着就配置桥接文件的路径。

混编下桥接文件的配置和使用_第7张图片
配置桥接文件路径

这里桥接文件的配置路径不用自己写,双击直接将Header文件拖进去,这里要注意,拖进去后里面显示的是全路径,而我们要将其设置为相对路径,如下图所示,删掉绿色的部分。

混编下桥接文件的配置和使用_第8张图片
桥接文件的设置

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

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

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


OC工程代码中混编Swift

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

1. 自动生成桥接文件

混编下桥接文件的配置和使用_第9张图片
添加swift文件
混编下桥接文件的配置和使用_第10张图片
提示生成桥接文件

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

混编下桥接文件的配置和使用_第11张图片
系统进行自动配置
混编下桥接文件的配置和使用_第12张图片
桥接文件的编辑

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

我们点击文件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()
# include 
#endif

#pragma clang diagnostic ignored "-Wauto-import"
#include 
#include 
#include 
#include 

#if !defined(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# if defined(__has_include) && __has_include()
#  include 
# 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文件进行工程配置。

混编下桥接文件的配置和使用_第13张图片
工程配置

下面看一下代码。

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

后记

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

混编下桥接文件的配置和使用_第14张图片

你可能感兴趣的:(混编下桥接文件的配置和使用)