Cara integrasi React Native dengan Swift dan CodePush (Panduan lengkap) β€” Bag. 1

abdul fattah ikhsan
7 min readAug 26, 2018

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:

Coba sendiri deh! πŸ‘Œ

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:

Luar biasa πŸ‘

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.

coba sendiri ya πŸ‘

kemudian pilih template file nya, kita pilih Swift File lalu klik Next.

Pilih Swift File

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.

Satu folder dengan AppDelegate.m / .h

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.

Pilih RCTBundleURLProvider
Pilih sharedSettings()
Pilih jsBundleURL(forBundleRoot: String!, fallbackResource: String!)

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.

Ketik RCTRootView(

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?

ld: 1 duplicate symbol for architecture x86_64

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.

Klik 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.

Hasil akhirnya!

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

--

--

abdul fattah ikhsan

If I am immortal, I will spend my time to learn everything in the universe.