[iOS] Swift <-> Objective-C การใช้งานข้ามภาษา


          การพัฒนา iOS Application ต้องเป็นภาษา Objective-C หรือ Swift ซึ่งแต่ก่อน Objective-C เป็นภาษาแรกที่ Apple เลือกใช้ และพัฒนาต่อขึ้นมาเป็น Swift ดังนั้นเราจึงมีนักพัฒนาอยู่ทั้ง 2 ภาษา

          โพสนี้ผมขอแนะนำวิธีการลดช่องว่างระหว่าง Objective-C และ Swift เพื่อให้นักพัฒนาหน้าเก่าต้องการที่จะเริ่ม และนักพัฒนาหน้าใหม่ที่คงจะยังหนีของเก่าไม่พ้น ซึ่งหมายความว่า ณ ตอนนี้เรายังทิ้งภาษาไหนไม่ได้เลย

          ลองดู syntax เล่น ๆ กันก่อน เปรียบเทียบ source code ของฟังก์ชัน register remote notification
//Objective-C
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

}
//Swift 2
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

}
//Swift 3
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        
}

เตรียมความพร้อมบน Swift Project เปล่า ๆ

Objective-C TO Swift

          สร้าง View โดยเราจะเลือกภาษาเป็น Objective-C

          Xcode จะแจ้งเตือนให้เราทำ bridging header เมื่อมีการพยายามจะสร้างบางอย่างที่เป็น Objective-C


          ถ้าเราสร้างมาแล้วจะได้ไฟล์ <PROJECT_NAME>-Bridging-Header.h ซึ่งเราจะต้อง import ของจาก Objective-C เพื่อให้ swift มองเห็นและสามารถเรียกใช้งาน

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
#import <ObjcHeader.h>

          การ import ต้องเขียนแบบภาษา Objective-C และเมื่อทำเรียบร้อยแล้วก็สามารถเรียกใช้บน swift ได้โดยไม่จำเป็นต้อง import ซ้ำอีกรอบใน swift

Swift TO Objective-C 

          ขณะเดียวกัน หากเรามีของที่เป็น Swift และต้องการใช้ใน Objective-C ได้ด้วย เราจะต้องเพิ่ม code เข้าไปใน Objective-C โดย xcode จะแอบสร้างไฟล์ให้เราตัวนึง
#import "BridgingProject-Swift.h"
          <PROJECT_NAME>-Swift.h เป็นไฟล์ที่รวมทุก class ของ swift ที่พร้อมใช้งานบน Objective-C แน่นอนว่าตัวที่ไม่สามารถใช้งานจะไม่ปรากฎใน code เลย และถ้ามีชื่อเดียวตัวแปร หรือ ฟังก์ชันซ้ำกันก็อาจมีปัญหาตอน generate ไฟล์นี้ได้ **สำหรับ PROJECT_NAME ที่มีเว้นวรรค ให้ใช้ underscore "_" แทน

กลับมาดูที่ LegacyViewController และเพิ่ม import เข้าไป
//
//  LegacyViewController.m
//  BridgingProject
//
//  Created by Lord Gift on 1/15/17.
//  Copyright © 2017 LordGift. All rights reserved.
//

#import "LegacyViewController.h"
#import "BridgingProject-Swift.h" //ADD THIS LINE

@interface LegacyViewController ()

@end

@implementation LegacyViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

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

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

สรุปความแตกต่างระหว่าง 2 แบบนี้ก็คือ

  • Objective-C TO Swift
    • import class/library ใน <PROJECT_NAME>-Bridging-Header.h
  • Swift TO Objective-C
    • auto generated <PROJECT_NAME>-Swift.h
    • import <PROJECT_NAME>-Swift.h ในObjective-C ที่จะใช้งาน
swift_vs_objective_xsolve
          เท่านี้ เราก็สามารถทำงานสลับไปสลับมาได้เรียบร้อย ไม่ว่าเราจะไปเจอ source code Objective-C หรือ swift ก็สามารถใช้งานได้เลย ไม่ต้องนั่งแปลงให้เมื่อยสมองครับ 😎😎

Facebook Comment

Popular post of 7 days

[Android] เปิดเครื่องไม่ได้ โลโก้ค้าง (Boot Loop)

[Java] ความแตกต่างระหว่าง Overloading กับ Overriding

ลืมรหัสปลดล็อค Android เข้าเครื่องไม่ได้ มีทางออกครับ