版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.08.13 |
前言
OC
和Swift
進(jìn)行混編時,就需要橋接文件的設(shè)定,這樣就可以OC
和Swfit
達(dá)到混編和實現(xiàn)功能。
Swift工程代碼中混編OC
下面我們先看一個例子。
1. 創(chuàng)建OC文件
先建立一個工程JJBridgeSwift
,在這個swift
工程文件里面我們新建立個OC
文件,如下圖所示。
這個時候,有一點注意,由于工程是swift寫的,后加的OC文件,只有這種第一次新建不同語言文件的時候會彈出下面的對話框。
3. 彈出創(chuàng)建橋接文件對話框
這里有兩個結(jié)果:
Don‘t Create
: 點擊這個以后,不會建立橋接文件,并且以后無論在工程里面創(chuàng)建多少個異種語言寫的文件都不會再彈出這個對話框,也就是說這個對話框只自動跳出來一次。Create Bridging Header
:點擊這個就會創(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è)置為相對路徑,如下圖所示,刪掉綠色的部分。
這里代碼就不多給出了,還是一樣的測試代碼,給出輸出結(jié)果。
2017-08-13 19:53:31.431244+0800 JJBridgeSwift[9335:4132540] 10
上面給出了swift
工程里面oc
文件自動生成橋接文件和手動生成橋接文件的方法。
OC工程代碼中混編Swift
下面我們就看一下OC
工程中混編Swift
的情況。
1. 自動生成橋接文件
這里我點擊第三個生成橋接文件。
這里橋接文件里面什么都不用寫。
我們點擊文件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é)下。