[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-CXcode จะแจ้งเตือนให้เราทำ 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 ที่จะใช้งาน