IOS开发之Objective-c与Swift混编简单示例-数字时钟

作为一个IOS软件开发者,遇到混编也是常有之事,本文通过一个简单的数字时钟示例,展示如何通过中间文件达到目的,实现混编。

本文创建的是一个OC项目,但是实际上OC项目和Swift项目混编是差不多的,下面上货。

一、创建或导入任意混编文件,生成或创建OC桥接头文件

新建混编文件时(如OC项目中新建Swift文件或Swift项目中新建OC文件),Xcode 会提示创建桥接头文件,生成的头文件名为 ModuleName-Bridging-Header.h,为Swift调用OC代码之用。如下例图:

IOS开发之Objective-c与Swift混编简单示例-数字时钟_第1张图片

                                                                           图 1.1

也可以自行创建桥接头文件,然后在 TARGETS >> Build Settings 下进行配置对应路径

IOS开发之Objective-c与Swift混编简单示例-数字时钟_第2张图片

           图1.2

二、OC项目如何调用Swift代码


导入或创建Swift文件后,Xcode会自动生成可依赖的接口文件,命名为 ModuleName-Swift.h, 如图1.2所示的IOS_App-Swift.h,编译时会更新该头文件。
需要调用Swift代码,导入该头文件即可,如:
#import "ProductModuleName-Swift.h"

需要注意的是Swift包含
===================本文所使用Swift代码如下:
import Foundation

@objc protocol UpdateObserver {
    func update ()
}

@objc class HelloWorldTimer :NSObject{
    fileprivate var updateObserver : UpdateObserver?
    fileprivate var isUpdating : Bool = false
    override init() {
        super.init()
    }
    
    func printLog ( _ printString :String ) -> Void{
        print("\(AppDelegate.getAppId()!): \(printString)")
    }
    
    func getNowTimeString () -> String{
        let date = NSDate()
        let timeFormatter = DateFormatter()
        timeFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"//yyyy-MM-dd HH:mm:ss.SSS
        return timeFormatter.string(from: date as Date) as String
    }
    
    func registerTimerChangeObserver (obs : UpdateObserver ){
        updateObserver = obs
    }
    
    func startTimer(){
        isUpdating = true
        timeUpdatePerSecond()
    }
    
    func isTimeUpdating () -> Bool{
        return self.isUpdating
    }
    
    func endTimer()  {
       isUpdating = false
     }
    
    @objc fileprivate func timeUpdatePerSecond()  {
        guard  isUpdating else {
            return
        }
        if let o = updateObserver {
            o.update()
        }
        perform(#selector(timeUpdatePerSecond), with: nil, afterDelay: 1)

    }
}

请注意,上面代码中的class和protocol都添加了 @objc属性
这样才能被OC项目调用。

=====================OC代码调用Swift代码
#import 
#import "IOS_App-Swift.h"

@interface ViewController : UIViewController 


@end


#import "ViewController.h"
#import "IOS_App-Swift.h"
@interface ViewController ()
{
    UILabel *time;
    HelloWorldTimer *world;
}
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    world = [[HelloWorldTimer alloc]init];
    [world registerTimerChangeObserverWithObs:self];
    
    time = [[UILabel alloc]initWithFrame:CGRectZero];
    time.translatesAutoresizingMaskIntoConstraints = false;
    time.text = [world getNowTimeString];
    time.font = [UIFont systemFontOfSize:33];
    time.textColor = [UIColor blueColor];
    NSLayoutConstraint  * timeCentreXConstraint = [NSLayoutConstraint constraintWithItem:time attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0];
    NSLayoutConstraint * timeCentreYConstraint = [NSLayoutConstraint constraintWithItem:time attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0];
    [self.view addSubview:time];
    [self.view addConstraints:@[timeCentreXConstraint,timeCentreYConstraint]];
    
    NSNotificationCenter* ns = [NSNotificationCenter defaultCenter];
    [ns addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
    [ns addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:nil];
}

- (void)applicationDidBecomeActive {
    [world startTimer];
    [world printLog:@"applicationDidBecomeActive"];
}

- (void) applicationWillResignActive {
    if ([world isTimeUpdating]){
    [world endTimer];
    }
    [world printLog:@"applicationWillResignActive"];
}

- (void)update {
    time.text = [world getNowTimeString];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

三、OC项目中Swift文件调用OC代码

OC和Swift代码可以相互调用,但是一个OC文件调用了Swift代码,则该文件不能被Swift代码调用,反之亦然
把相关头文件加入桥接头文件( ModuleName-Bridging-Header.h)即可
================IOS-App-Bridging-Header.h内容
//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "AppDelegate.h"


================Swift文件调用的OC相关代码
#import 
#import 
@interface AppDelegate : UIResponder 

@property (strong, nonatomic) UIWindow *window;
@property (readonly, strong) NSPersistentContainer *persistentContainer;

- (void)saveContext;
+ (NSString *) getAppId;

@end
//.....
@implementation AppDelegate

+ (NSString *)getAppId {
    return @"IOS-App";
}
//.......

=======================Swift代码调用OC代码,从上面的Swift代码中截取如下
    func printLog ( _ printString :String ) -> Void{
        print("\(AppDelegate.getAppId()!): \(printString)")
    }



效果截图

IOS开发之Objective-c与Swift混编简单示例-数字时钟_第3张图片

相关Log打印:

IOS-App: applicationDidBecomeActive

IOS-App: applicationWillResignActive


更多详情请参照:

Swift and Objective-C in the Same Project

你可能感兴趣的:(ios)