admin管理员组

文章数量:1289425

My react native expo iOS app is working entirely though expo. Unfortunately, when doing a development build, or through test flight I get a white screen. I am struggling to debug this as within TestFlight I have no access to the console. I am able to zoom in and out (as indicated by the scroll bars appearing), however the entire content is a plain white screen.

My usual workflow to get onto TestFlight is listed below: npx expo prebuild eas build --platform ios eas submit -p ios --latest

No console or build errors in expo, so quite difficult to debug.

Any help here would be greatly appreciated!

import React, { useRef } from 'react';
import { View, StyleSheet, StatusBar } from 'react-native';
import { WebView } from 'react-native-webview';
import * as FileSystem from 'expo-file-system';
import * as MediaLibrary from 'expo-media-library';
import * as Clipboard from 'expo-clipboard';
import * as Sharing from 'expo-sharing';
import { script } from './assets/constants';
const HTML_CONTENT = require('./assets/body.html');


export default function App() {
    const webViewRef = useRef(null);

    const styles = StyleSheet.create({
        container: {
            flex: 1,
        },
        webView: {
            flex: 1,
        },
    });

    const handleMessage = async (event) => {
        const message = JSON.parse(event.nativeEvent.data);
        console.log('Message from WebView:', message);

        switch (message.type) {
            case 'copyToClipboard':
                try {
                    await Clipboard.setStringAsync(message.data);
                    webViewRef.current.injectJavaScript(`
                window.dispatchEvent(new MessageEvent('message', {
                  data: JSON.stringify({ type: 'clipboardResponse', success: true })
                }));
                true;
              `);
                } catch (error) {
                    console.error('Error copying to clipboard:', error);
                    webViewRef.current.injectJavaScript(`
                window.dispatchEvent(new MessageEvent('message', {
                  data: JSON.stringify({ 
                    type: 'clipboardResponse', 
                    success: false, 
                    error: ${JSON.stringify(error.message)} 
                  })
                }));
                true;
              `);
                }
                break;
            case 'log':
                console.log('WebView log:', message.message);
                break;

            case 'error':
                console.error('WebView error:', message.message);
                break;

            case 'exportPNG':
                try {
                    const { status } = await MediaLibrary.requestPermissionsAsync();
                    if (status === 'granted') {
                        const filename = FileSystem.documentDirectory + 'color_palette.png';
                        await FileSystem.writeAsStringAsync(filename, message.data.split(',')[1], { encoding: FileSystem.EncodingType.Base64 });
                        await MediaLibrary.saveToLibraryAsync(filename);

                        // Send success message back to WebView
                        webViewRef.current.injectJavaScript(`
                                window.dispatchEvent(new MessageEvent('message', {
                                    data: JSON.stringify({ type: 'exportSuccess' })
                                }));
                                // Reset button text
                                document.getElementById('exportPngBtn').textContent = 'Export to PNG';
                                true;
                            `);
                    } else {
                        webViewRef.current.injectJavaScript(`
                                window.dispatchEvent(new MessageEvent('message', {
                                    data: JSON.stringify({ type: 'exportError', error: 'Permission denied' })
                                }));
                                document.getElementById('exportPngBtn').textContent = 'Export to PNG';
                                true;
                            `);
                    }
                } catch (error) {
                    console.error('Error saving image:', error);
                    webViewRef.current.injectJavaScript(`
                            window.dispatchEvent(new MessageEvent('message', {
                                data: JSON.stringify({ type: 'exportError', error: ${JSON.stringify(error.message)} })
                            }));
                            document.getElementById('exportPngBtn').textContent = 'Export to PNG';
                            true;
                        `);
                }
                break;

                case 'exportProcreate':
                    try {
                        const { status } = await MediaLibrary.requestPermissionsAsync();
                        if (status === 'granted') {
                            const timestamp = Date.now();
                            const tempDir = FileSystem.cacheDirectory;
                            const acoPath = `${tempDir}my_palette.aco`;
        
                            await FileSystem.writeAsStringAsync(
                                acoPath,
                                message.data.aco,
                                { encoding: FileSystem.EncodingType.Base64 }
                            );
        
                            await Sharing.shareAsync(acoPath, {
                                mimeType: 'application/octet-stream',
                                dialogTitle: 'Save Color Palette',
                                UTI: 'public.data',
                                filename: 'my_palette.aco'  // Set default filename for sharing
                            });
        
                            try {
                                await FileSystem.deleteAsync(acoPath);
                            } catch (cleanupError) {
                                console.warn('Cleanup error:', cleanupError);
                            }
        
                            webViewRef.current.injectJavaScript(`
                                window.dispatchEvent(new MessageEvent('message', {
                                    data: JSON.stringify({ type: 'exportSuccess' })
                                }));
                                document.getElementById('exportProcreateBtn').textContent = 'Export to Procreate';
                                true;
                            `);
                        }
                    } catch (error) {
                        console.error('Error saving palette file:', error);
                        webViewRef.current.injectJavaScript(`
                            window.dispatchEvent(new MessageEvent('message', {
                                data: JSON.stringify({ 
                                    type: 'exportError', 
                                    error: ${JSON.stringify(error.message)} 
                                })
                            }));
                            document.getElementById('exportProcreateBtn').textContent = 'Export to Procreate';
                            true;
                        `);
                    }
                    break;


            default:
                console.warn('Unknown message type from WebView:', message.type);
        }
    };

    const injectedJavaScript = `
      console = {
        log: function(message) {
          window.ReactNativeWebView.postMessage(JSON.stringify({type: 'log', message: message}));
        },
        error: function(message) {
          window.ReactNativeWebView.postMessage(JSON.stringify({type: 'error', message: message}));
        }
      };
      ${script}
    `;

    return (
        <View style={styles.container}>
            <StatusBar hidden />
            <WebView
                ref={webViewRef}
                style={styles.webView}
                originWhiteList={['*']}
                source={HTML_CONTENT}
                injectedJavaScript={injectedJavaScript}
                onMessage={handleMessage}
                javaScriptEnabled={true}
                domStorageEnabled={true}
            />
        </View>
    );
}

本文标签: iosWhite Screen in TestFlight for React Native Expo AppStack Overflow