Integrasi Mobile•React Native

Implementasi React Native

Panduan integrasi lengkap untuk aplikasi **React Native** menggunakan library standar industri react-native-webview.

1. Install Dependency

Terminal
npm install react-native-webview react-native-permissions
cd ios && pod install

2. Komponen Lengkap (QoinWebviewScreen.tsx)

QoinWebviewScreen.tsx
import React, { useRef, useEffect } from 'react';
import { StyleSheet, View, ActivityIndicator, PermissionsAndroid, Platform } from 'react-native';
import { WebView, WebViewMessageEvent } from 'react-native-webview';

interface QoinWebviewScreenProps {
  signature: string;
  palette?: string;
  baseUrl?: string;
  onClose: (resultData?: any) => void;
}

export const QoinWebviewScreen: React.FC<QoinWebviewScreenProps> = ({
  signature,
  palette = 'original',
  baseUrl = 'https://seamless.qoin.id',
  onClose,
}) => {
  const webViewRef = useRef<WebView>(null);

  useEffect(() => {
    requestPermissions();
  }, []);

  const requestPermissions = async () => {
    if (Platform.OS === 'android') {
      await PermissionsAndroid.requestMultiple([
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
        PermissionsAndroid.PERMISSIONS.CAMERA,
      ]);
    }
  };

  const handlePageLoad = () => {
    const payload = JSON.stringify({ Signature: signature, Palette: palette });
    
    // Injeksi bridge agar postMessage diteruskan ke window.ReactNativeWebView.postMessage
    const script = `
      window.addEventListener('message', function(event) {
        if (window.ReactNativeWebView) {
          var d = typeof event.data === 'string' ? event.data : JSON.stringify(event.data);
          window.ReactNativeWebView.postMessage(d);
        }
      });
      window.postMessage(${payload}, '*');
      true;
    `;

    webViewRef.current?.injectJavaScript(script);

    // Retry 500ms kemudian
    setTimeout(() => {
      webViewRef.current?.injectJavaScript(`window.postMessage(${payload}, '*'); true;`);
    }, 500);
  };

  const handleMessage = (event: WebViewMessageEvent) => {
    try {
      const data = JSON.parse(event.nativeEvent.data);
      if (data && data.close === true) {
        onClose(data);
      }
    } catch (e) {
      console.log('Pesan non-JSON:', event.nativeEvent.data);
    }
  };

  return (
    <View style={styles.container}>
      <WebView
        ref={webViewRef}
        source={{ uri: `${baseUrl}/` }}
        onLoadEnd={handlePageLoad}
        onMessage={handleMessage}
        javaScriptEnabled={true}
        domStorageEnabled={true}
        geolocationEnabled={true}
        startInLoadingState={true}
        renderLoading={() => (
          <ActivityIndicator size="large" color="#f59e0b" style={styles.loader} />
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#ffffff' },
  loader: { position: 'absolute', top: '50%', left: '50%', transform: [{ translateX: -18 }, { translateY: -18 }] },
});
Penanganan Hardware Back Button di Android
Gunakan hook BackHandler di Android untuk memeriksa webViewRef.current?.goBack() ketika pengguna menekan tombol fisik kembali agar tidak langsung keluar dari layar.