版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.08.13 |
前言
OC
和Swift
进行混编时,就需要桥接文件的设定,这样就可以OC
和Swfit
达到混编和实现功能。
Swift工程代码中混编OC
下面我们先看一个例子。
1. 创建OC文件
先建立一个工程JJBridgeSwift
,在这个swift
工程文件里面我们新建立个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. 自动生成桥接文件
这里我点击第三个生成桥接文件。
这里桥接文件里面什么都不用写。
我们点击文件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
后记
这些东西都很简单,大家看看就好,没事的时候就总结下。