Nge-build Enterprise Warehouse App: Kombinasi Maut React Native, Swift & C++

Advertisement

Pernah kaga lu bayangin, narik ribuan data stok gudang bahan kimia sambil nge-render grafik real-time di layar HP, tapi aplikasinya tetep jalan mulus 60fps tanpa ngelag sedikitpun?

Selamat dateng di series mahakarya gua. Di sini kita bakal ngebangun sistem manajemen gudang kelas enterprise dari nol, case study nya: PT Putra Armssy Perkasa (Pabrik deterjen, softener, dan pewangi laundry).

Kita kaga bakal pake cara standar. Biar performanya ngacir, kita bakal tanem C++ sebagai otak utama buat ngurusin database (SQLite) dan kalkulasi mutasi biar kaga kena race condition. Terus kita pake Swift sebagai jembatan tol buat ngakses hardware HP (kamera scanner, printer thermal Bluetooth, & generator PDF). Semuanya dibalut pake UI React Native yang cakep dan responsif.

Total ada 10 sesi di series ini, mulai dari setup arsitektur awal sampe bikin sistem Role-Based Access dan Cloud Sync. Siapin kopi lu yang paling item, buka Code Editor, dan mari kita obrak-abrik mesinnya!

Nge-build Enterprise Warehouse App

sesi 1: Setup & Arsitektur Inti

Di sesi 1 ini, kita bakal setting arsitektur awalnya dulu. Kita bakal sikat pake React Native sebagai framework cross-platform nya. Kenapa? Biar gampang jembatanin UI ke C++ (buat core logic yang butuh kalkulasi berat dan ngebut) terus kita pake Swift buat bikin native module khusus di ekosistem iOS.

Bahan baku racikan kayak MES, Texapon, dan LABS sampai ke produk jadi, semuanya bakal aman kecatat di sistem ini. Yuk, langsung kita bedah dalemannya!

1. C++ Core Engine (Otak Gudangnya)

Kita mulai dari mesin bawahnya. C++ di mari tugasnya ngurusin mutasi barang yang masuk dan keluar. Karena transaksi gudang bisa rame, kita pake konsep Multithreading dan Mutex di C++ biar kaga terjadi Race Condition pas aplikasi lagi narik data stok bahan kimia barengan.

InventoryEngine.h (C++)
#include <iostream>
#include <string>
#include <unordered_map>
#include <mutex>

class InventoryEngine {
private:
    std::unordered_map<std::string, int> stock;
    std::mutex mtx;

public:
    // Fungsi buat nambah stok masuk gudang
    void addStock(const std::string& item, int qty) {
        std::lock_guard<std::mutex> lock(mtx); // Kunci data biar kaga bentrok
        stock[item] += qty;
        std::cout << "Gudang Update: " << item << " nambah " << qty << " liter/kg.\n";
    }

    // Fungsi buat cek sisa stok
    int checkStock(const std::string& item) {
        std::lock_guard<std::mutex> lock(mtx);
        return stock[item];
    }
};
💻 Hasil Tampilan (Log Console C++)
Gudang Update: Texapon nambah 50 liter/kg.
Gudang Update: LABS nambah 20 liter/kg.

Status: Mesin gudang siap, stok aman kaga bakal tabrakan datanya pas diakses.

2. Swift Native Module (Jembatan ke iOS)

Nah, biar aplikasi lu jalan mulus jaya di iPhone, kita harus bungkus fungsi C++ tadi terus kita panggil pake Swift buat dijadiin bridge (jembatan) ke tampilan React Native-nya.

WarehouseBridge.swift (Swift)
import Foundation
import React

@objc(WarehouseBridge)
class WarehouseBridge: RCTEventEmitter {

    // Fungsi yang bakal dipanggil dari React Native
    @objc func updateStockIOS(_ itemName: String, quantity: Int) {
        
        // Di sini harusnya kita manggil instance dari InventoryEngine C++
        // Buat tutorial awal, kita simulasikan sukses balikan datanya dulu
        let statusMessage = "Sukses update \(itemName) sebanyak \(quantity) drum via iOS Native Bridge."

        print(statusMessage)
        
        // Kirim event notifikasi balik ke UI
        sendEvent(withName: "onStockUpdated", body: ["message": statusMessage])
    }

    // Daftarin event biar dikenali sama JavaScript
    override func supportedEvents() -> [String]! {
        return ["onStockUpdated"]
    }
}
📱 Hasil Tampilan (Log Debugger Xcode)
Sukses update Deterjen Cair Putra Armssy sebanyak 100 drum via iOS Native Bridge.

3. Cross-Platform UI (Tampilan Layar HP)

Biar kaga usah ngoding dua kali buat Android sama iOS, front-end nya kita rakit pake React Native (JavaScript/TypeScript). Tampilannya kita bikin cakep, minimalis, dan yang pasti ringan biar kaga ada drama aplikasi nge-lag.

App.tsx (React Native)
import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, NativeEventEmitter, NativeModules } from 'react-native';

const { WarehouseBridge } = NativeModules;
const warehouseEmitter = new NativeEventEmitter(WarehouseBridge);

const App = () => {
  const [stockLog, setStockLog] = useState<string>('Gudang masih anteng, belum ada pergerakan.');

  useEffect(() => {
    // Dengerin bisikan dari Swift
    const subscription = warehouseEmitter.addListener(
      'onStockUpdated',
      (event) => {
        setStockLog(event.message);
      }
    );
    return () => subscription.remove();
  }, []);

  const handleUpdateStock = () => {
    // Lempar data dari UI ke Swift, terus diterusin ke C++
    WarehouseBridge.updateStockIOS('Softener Wangi Bunga', 50);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.headerTitle}>Gudang PT Putra Armssy Perkasa</Text>
      
      <View style={styles.card}>
        <Text style={styles.logText}>{stockLog}</Text>
      </View>

      <TouchableOpacity style={styles.button} onPress={handleUpdateStock}>
        <Text style={styles.buttonText}>TAMBAH STOK SOFTENER</Text>
      </TouchableOpacity>
    </View>
  );
};
📱 Visual Simulasi di Layar HP

Gudang PT Putra Armssy Perkasa

Sukses update Softener Wangi Bunga sebanyak 50 drum via iOS Native Bridge.

TAMBAH STOK SOFTENER

sesi 2: Database Storage & UI List Barang

Masa iya tiap nutup aplikasi, data stoknya nguap gitu aja? Bikin puyeng ntar orang gudang. Makanya, di sesi 2 ini kita bakal pasang Database Lokal (SQLite) langsung di level C++. Kenapa di C++? Biar urusan query data bahan baku racikan kayak MES, Texapon, LABS, sampe ke produk jadi tetep ngacir kaga pake loading lama.

1. C++ SQLite Engine (Gudang Ingatan)

DatabaseEngine.cpp (C++)
#include <iostream>
#include <sqlite3.h>
#include <string>

class DatabaseEngine {
private:
    sqlite3* db;
    char* zErrMsg = 0;

public:
    // Buka atau bikin file database baru
    void initDB() {
        int rc = sqlite3_open("gudang_armssy.db", &db);
        if (rc) {
            std::cerr << "Waduh, gagal buka DB: " << sqlite3_errmsg(db) << "\n";
        } else {
            std::cout << "Mantap, Database gudang_armssy.db sukses kebuka!\n";
            
            // Bikin tabel kalo belom ada
            std::string sql = "CREATE TABLE IF NOT EXISTS INVENTORY("
                              "ID INTEGER PRIMARY KEY AUTOINCREMENT,"
                              "NAMA_BARANG TEXT NOT NULL,"
                              "KATEGORI TEXT NOT NULL,"
                              "QTY INT NOT NULL);";
            sqlite3_exec(db, sql.c_str(), 0, 0, &zErrMsg);
        }
    }
};

sesi 3: Form Input Barang & Validasi

Kalo ada barang baru masuk dari supplier (kayak drum Texapon baru), gimana cara masukin datanya? Kita bikin form inputan yang cakep di React Native, terus datanya kita lempar lewat jembatan Swift, dan berujung dieksekusi sama C++ buat disimpen ke SQLite.

AddInventoryScreen.tsx (React Native)
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, Alert, NativeModules } from 'react-native';

const { InventoryInputBridge } = NativeModules;

const AddInventoryScreen = () => {
  const [namaBarang, setNamaBarang] = useState('');
  const [qty, setQty] = useState('');

  const handleSimpanData = async () => {
    if (!namaBarang || !qty) {
      Alert.alert('Eitss!', 'Isi dulu dong kolom nama sama jumlahnya, ngab.');
      return;
    }
    try {
      const response = await InventoryInputBridge.addNewItem(namaBarang, 'Bahan Baku', parseInt(qty, 10));
      Alert.alert('Mantap!', response);
    } catch (error) {
      Alert.alert('Error', error.message);
    }
  };
  // UI Render logic...
};

sesi 4: Scan Barcode/QR Code Biar Sat-Set!

Kalo orang gudang PT Putra Armssy Perkasa suruh ngetik satu-satu pake jari, bisa keriting tuh tangan, rawan typo pula. Mending kita manfaatin kamera iPhone/Android buat nge-jepret QR Code yang nempel di drumnya.

QRParserEngine.cpp (C++)
class QRParserEngine {
public:
    // Fungsi utama nerima scan dari HP
    bool processScannedData(const std::string& rawQR) {
        // Kita belek teksnya pake pembatas '|' misal: TEXAPON|Bahan Baku|200
        std::vector<std::string> data = splitQRData(rawQR, '|');
        
        if (data.size() != 3) {
            std::cerr << "Waduh, format QR Code kaga valid ngab!\n";
            return false;
        }
        std::cout << "C++ Berhasil nge-decode QR: " << data[0] << " - " << data[2] << " Liter/Kg.\n";
        return true;
    }
};

sesi 5: Fitur Barang Keluar & Validasi Anti-Minus!

Kalo stok di gudang sisa 50 jerigen, tapi mau ngeluarin 100 jerigen, sistem harus tereak: "Eitss, stok kaga cukup bray!" biar kaga terjadi yang namanya stok minus.

💻 Hasil Validasi C++ Engine (Outbound)
Waduh ngab, stok Deterjen Cair Matic cuma sisa 20. Kaga cukup buat ngeluarin 50!

C++: Mantap! 15 Deterjen Cair Matic sukses dikeluarin dari gudang.

Status: Logika pertahanan C++ udah jalan. Gudang lu sekarang anti boncos.

sesi 6: Dashboard Analytics & Chart Kece!

Kita bakal tarik datanya pake C++, balut di Swift, dan kita gambar jadi Grafik Visual (Bar Chart) di React Native. Biar bureh dan decision making jadi sat-set!

AnalyticsEngine.cpp (C++)
// Fungsi narik Top 5 Barang Paling Laris
std::vector<ItemStat> getTopMovingItems() {
    std::string sql = "SELECT NAMA_BARANG, SUM(QTY) as TOTAL "
                      "FROM OUTBOUND_LOG "
                      "GROUP BY NAMA_BARANG "
                      "ORDER BY TOTAL DESC LIMIT 5;";
    // Eksekusi ke SQLite trus return datanya ke Swift
}

sesi 7: Auto-Generate Laporan PDF Buat Rapat Bos!

Cuma modal sekali pencet, sistem bakal ngerangkum semua data, nyetak jadi file PDF yang rapih, dan siap di-share ke WhatsApp grup pabrik!

PDFGeneratorBridge.swift (Swift)
let fmt = UIMarkupTextPrintFormatter(markupText: htmlStringFromCPP)
let render = UIPrintPageRenderer()
render.addPrintFormatter(fmt, startingAtPageAt: 0)

// Proses Nggambar PDF ukuran A4
let pdfData = NSMutableData()
UIGraphicsBeginPDFContextToData(pdfData, .zero, nil)
UIGraphicsBeginPDFPage()
render.drawPage(at: 0, in: UIGraphicsGetPDFContextBounds())
UIGraphicsEndPDFContext()

// Simpen ke Documents iOS

sesi 8: Integrasi Printer Thermal Bluetooth

Kita bakal nyulap aplikasi lu biar bisa Konek ke Printer Thermal Bluetooth. Kita bakal pake standar bahasa mesin printer namanya ESC/POS.

ReceiptBuilder.cpp (C++)
// Kode ESC/POS (Standar mesin printer)
std::string INIT = "\x1B\x40";       // Reset printer
std::string BOLD_ON = "\x1B\x45\x01"; // Huruf tebal nyala
std::string CUT_PAPER = "\x1D\x56\x41\x10"; // Potong kertas

receipt += INIT + BOLD_ON + "PT PUTRA ARMSSY PERKASA\n";

sesi 9: Sistem Login & Hak Akses (Role System)

Kalo berhasil masuk, kita simpen Role nya, trus kita pake logic sederhana buat nyembunyiin tombol "Tambah/Keluar Barang" buat si Viewer.

💻 C++ Bouncer Auth Log
C++: Akses diterima! Selamat datang bos_armssy (Akses: ADMIN)
C++: Ditolak! Username atau password salah ngab.

sesi 10: Cloud Sync - Backup Data ke Server

C++ bakal ngerangkum semua isi gudang jadi format teks JSON, lempar ke Swift, trus Swift bakal ngirim data itu lewat jalur internet (HTTP POST) ke server pusat PT Putra Armssy Perkasa.

CloudSyncBridge.swift (Swift)
var request = URLRequest(url: urlServer)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = payloadJSONFromCPP.data(using: .utf8)
// Terbangin data ke awan ☁️

FAQ (Pertanyaan Paling Sering Muncul)

Q: Ngab, kenapa repot-repot pake C++ sih? Kan pake React Native + AsyncStorage di JS juga bisa?
A: Emang bisa bray! Tapi kalo data gudang lu udah puluhan ribu item, proses JS bisa ngos-ngosan (bottleneck). C++ itu ototnya kawat tulang besi, ngurusin heavy lifting biar UI di layar HP tetep jalan mulus 60fps tanpa nge-lag.
Q: Bang, kalo Bos gue pakenya HP Android gimana ceritanya?
A: Kode React Native (UI) sama kode C++ (Core Engine) lu tetep sama persis. Lu tinggal bikin jembatan baru khusus Android pake Java atau Kotlin (JNI). Mesin sama bodi tetep satu, ganti kabel doang.
Q: Kodenya udah aman belom nih buat langsung dipake operasional besok?
A: Buat Proof of Concept (pamer ke manajemen) udah mantap! Tapi buat Production, lu wajib nambahin enkripsi (hash password) di C++, sama State Management (Redux/Zustand) di React Native nya.

Baca Juga (Sponsor)