Cara integrasi React Native dengan Swift dan CodePush (Panduan lengkap) β Bag. 1
Bagian 2 udah publish guys di sini
Dari judulnya penasaran ga sih atau udah tau atau mungkin terkesima? π . Whatever, cerita ini gua buat sebagai penyaluran energi, pengetahuan dan harapan untuk orang yang membutuhkan πΌ. Karena belakangan ini gua baru mempelajari Swift (Β±10 hari) dan yang gua rasakan beneran fun π. Singkat cerita gua pengen project React Native gua udah pake Swift. Untuk mencapai tujuan itu langkah yang gua ambil adalah setidaknya gua tau sintaks Objective-C dan paham editor nya Apple alias Xcode.
Gua udah coba ini pada React Native versi 0.56 dan berhasil. Untuk versi yang lebih rendah atau lebih tinggi belum dicoba. Maka dari itu jika kalian berhasil karena tutorial ini jangan lupa komen ya dibawah. Nah, langsung kita mulai dengan buat project β nya. Pertama-tama kita bener-bener buat dari awal, karena tutorial ini umum untuk semua level.
Setup project
Instal peralatan yang dibutuhkan yaitu react-native-cli
npm i -g react-native-cli
Setelah itu kita buat project β nya dengan nama ReactNativeSwift (cuma contoh, terserah kalian mau namanya apa)
react-native init ReactNativeSwift
tunggu sampai selesai, jika dah selesai tampilannya bakal kayak gini:
Nah sesuai hint yang ada di CLI kita, ketik cd ReactNativeSwift
kemudian react-native run-ios
. Nah kalau dah selesai tampilannya bakal kayak gini kan:
Integrasi dengan Swift
Nah sekarang buka Xcode (masih di terminal) dengan perintah open -a Xcode ios/ReactNativeSwift.xcodeproj
. Setelah terbuka, di bagian Navigation Pane (sebelah kiri / project struktur) klik kanan pada folder ReactNativeSwift kemudian klik new file.
kemudian pilih template file nya, kita pilih Swift File lalu klik Next.
maka akan muncul panel create. by default, panel create ini akan membuat file di dalam folder ios. tapi karena kita mengikuti struktur dari React Native maka kita masuk ke folder ReactNativeSwift (satu folder dengan AppDelegate.m /.h). Selanjutnya di bagian input Save As, kita beri nama AppDelegate saja. Pastikan di bagian Targets, paling pertama sudah tercentang. Kalau sudah lengkap klik Create.
Setelah kita klik Create maka akan muncul panel untuk membuat bridging header. Klik Create Bridging Header. Gunanya sebagi jembatan atau menampakkan class, properties dan method (APIs) Objective-C di Swift file. Keren kan! π.
Nah jika sudah selesai maka dua file baru tercipta yaitu AppDelegate.swift dan ReactNativeSwift-Bridging-Header.h. mungkin diantara kalian ada yang penasaran atau ada yang missed di bagian bridging header. Sebenarnya dia ga cuma membuat file nya aja tapi juga set konfigurasi pada Build Settings > Swift Compiler - General > Objective-C Bridging Header. bagian ini menyimpan informasi path dimana file itu berada dan nama filenya. Dan nge set nilai pada install Objective-C Compatibility Header ke Yes.
oke, buka AppDelegate.m (cukup klik sekali) dan copy kode seperti dibawah:
#import <React/RCTBundleURLProvider.h>#import <React/RCTRootView.h>
paste ke file bridging header yang baru aja dibuat tadi. disini namanya ReactNativeSwift-Bridging-Header.h kemudian save (βS). Selanjutnya klik Play βΆοΈ sebelah kiri atas atau Product > Build (βB). Maka akan jalan seperti sebelumnya dan dimaksudkan agar file di bridging header ke deteksi dan akan muncul suggestion pada editor Xcode π saat kita ngoding di file Swift.
Buka AppDelegate.swift, pasti di file kalian cuma ada import Foundation
ya kan?. nah, hapus ganti dengan import UIKit
. Note: Saran jangan copas ya, ketik aja dan lihat kerennya editor Xcode. Kemudian kita buat class namanya AppDelegate yang inherit (turunan) dari UIResponder dan delegasi dari UIApplicationDelegate.
class AppDelegate: UIResponder, UIApplicationDelegate {}
Dan sebenarnya itu equivalent atau sama aja dengan yang ada di AppDelegate.h di baris kode ini.
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
nah, baris selanjutnya pada AppDelegate.h tampak seperti di bawah ini.
@property (nonatomic, strong) UIWindow *window;
terus di Swift gimana? kembali ke AppDelegate.swift, di dalam class coba ketik aja window terus nanti akan muncul suggestionβ nya kemudian tekan enter.
class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? // nah kan}
Selanjutnya jika kita lihat di AppDelegate.m ada baris kode atau function (method) yang return β nya boolean.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ // ada kode disini return YES;}
Itu sebenarnya adalah function (method) dari UIApplicationDelegate. Yang gua singgung di atas bahwa class AppDelegate kita adalah delegasi dari UIApplicationDelegate. Oke, buka AppDelegate.swift class, coba kita ketik application maka akan muncul suggestion β nya, pilih yang ada didFinishLaunchingWithOptions. Kemudian tekan enter.
Jangan lupa di dalam method β nya di return true. Jika sudah maka akan seperti ini.
class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
return true }}
Hampir selesai, mantap!. Di dalam AppDelegate.m ada dua class yang di panggil. Class yang di buat oleh React Native team (facebook), yaitu: RCTBundleURLProvider dan RCTRootView.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"ReactNativeSwift" initialProperties:nil launchOptions:launchOptions]; // ada kode disini return YES;}
Dan akan berubah jadi Swift way di setiap file Swift karena kita udah import di file bridging header tadi. Oke, kita kembali ke AppDelegate.swift, kita buat variable bernama jsCodeLocation dan nilainya adalah RCTBundleURLProvider. Seperti biasa kita ketik nanti akan muncul suggestion β nya.
Lebih enak dibaca kan? Swift ==
π. Tinggal kita masukkan nilai di masing-masing parameternya, yaitu di forBundleRoot dan di fallbackResource.
let jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index", fallbackResource: nil)
Selanjutnya kita buat variable bernama rootView yang di beri nilai RCTRootView. Sebagai penyimpan instance.
Kita masukkan ke masing-masing parameternya.
let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "ReactNativeSwift", initialProperties: nil, launchOptions: launchOptions)
Miripkan dengan kode yang ada di AppDelegate.m di atas (versi Objective-C)? menurut kalian mana yang lebih enak dibaca? tentu aja JavaScript π
udah sisanya Kopas aja ya! hehe π.
Dah selesai kan! easy peasy! π. apakah masih bisa jalan? ya masih bisa tapi Xcode masih eksekusi versi Objective-C. Loh kok!, ya karena kita belum membuat file main.swift dan Xcode mengeksekusi yang ada di main.m.
/*** Copyright (c) 2015-present, Facebook, Inc.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.*/#import <UIKit/UIKit.h>#import "AppDelegate.h"int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); }}
Seperti di atas isi dari main.m, mari kita ubah jadi Swift way. Pertama kita buat dulu file main.swift. Di Swift, agak ribet karena masalah manggil si argc dan argv. lengkapnya di sini.
Lagi-lagi mirip, lebih enak mana?. Oke, coba kita jalanin, pasti error kan. Errornya apa?
Itu karena kita punya dua main file. Xcode komplen karena kita punya dua file yang sama (duplicate) dan bikin bentrok. Oke, kalau gitu kita hapus main.m. Klik kanan pada main.m dan pilih Delete > Move to Trash.
Tada π aplikasi jalan lagi dengan normal. Sukses π π₯. Kalau masih bermasalah bisa coba di clean dulu dengan cara klik Product > Clean kemudian jalan kan kembali dengan klik Play βΆοΈ.
Sebenarnya tanpa membuat main.swift file kita bisa jalanin dengan hanya AppDelegate.swift file. Loh kok bukan dari tadi ngasih taunya π’. Sengaja biar jadi panjang artikelnya π
. Tidak hanya itu, tujuannya agar di buat mirip kayak bawaan React Native. Nah lanjutkan!, cukup menambahkan attributes @UIApplicationMain
di atas class AppDelegate. Ini sama halnya ketika kita buat project baru (Swift project) di Xcode maka otomatis AppDelegate tercipta tanpa main file. Oke, jika sudah ditambahkan maka hapus main.swift yang tadi kita buat.
Mirip Decorator di JavaScript kan? dan lebih simple dari yang pertama.
Kesimpulan
Sebagai developer React Native yang sebelumnya sebagai developer Web, kita perlu merasa tertantang untuk mempelajari bahasa baru terutama di dunia Mobile App. Yang kita rasakan ketika pertama kali terjun ke dunia Mobile App pakai React Native, semua terasa berbeda dari yang kita ketahui di Web App, dan seru bukan?
Perlu dicatat, ketika kalian melakukan modifikasi ini maka kemungkinan penggunaan react-native-git-upgrade
ga bekerja di bagian platform iOS ini. Karena perintah tersebut akan mencari AppDelegate.m /. h. Tapi jangan kuatir kalian kan udah ngerti cara ubahnya, tau cara membuat bridging header dan pada dasarnya semua bahasa pemograman itu ada kemiripan dan logic β nya sama dan lebih memudahkan kita sebagai programmer (syntactic sugar). Agar semakin paham, kalian bisa mencoba menambahkan package baru yaitu react-native-code-push.
Karena niatnya hari Senin 27 Agustus 2018 akan di publish. mungkin ini lebih enak di bikin jadi 2 bagian. Oh ya, jangan lupa untuk cek lagi bagian pertama ini, karena akan ada link bagian keduanya (integrasi dengan react-native-code-push) dan niatnya mau masukin video detil untuk bagian ini biar lebih jelas. Gua harap ini bisa bermanfaat, jika ada kritik dan saran yang membangun bisa komen dibawah.
π Bagian 2