Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

libc++abi.dylib: terminating with uncaught exception of type NSException, React Native iOS

Issue Description::

I am working on react-native-ios app, most of the times it stuck after splash. I have created a duplicate splash screen inside my react native code. When app started I am redirecting it to dummy splash screen which is exactly like a splash. Here I am loading complete required data of app from API. After loading complete data I am pushing it initial screen. But most of the time my stuck after splash screen, or sometimes crash after loading splash(when moving from original splash to dummy splash screen where I am loading whole app required data).

There is no error inside terminal, I am getting this following mentioned error inside xcode output window, whenever my app crashed or when app stuck on splash screen.

Error::

  • Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'

  • libc++abi.dylib: terminating with uncaught exception of type NSException

My iOS app working working fine if I am redirecting to login screen, but having issue whenever i am redirecting to dummy splash. I have also changes my dummy screen name to "initializer.js" but nothing happened. iOS app crashed or stuck after splash it redirecting it to screen where i am loading complete required data for app.

App Intializer Screen Code(dummy splash)::

/**
 * Splash Screen
 */
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import * as Animatable from 'react-native-animatable';
import { View, Text } from 'react-native';
import { Spinner } from 'native-base';
import Toast from 'react-native-simple-toast';
import NetInfo from '@react-native-community/netinfo';
import SplashScreen from 'react-native-splash-screen';
import AsyncStorage from '@react-native-community/async-storage';
//Global Components
import { ImageView } from '../../Components/GlobalComponent';
//Form Components
import { Button } from '../../Components/FormComponent';
// APIResponseMessages
import APIResponseMessages from '../../Constants/APIResponseMessages';
// Actions
import { appInitialize, loader } from '../../Actions';
//Style
import { GlobalStyles, Colors } from '../../Styles';
//Images
import Images from '../../Assets/Images';
//Navigation Screen
import { AUTH, INITIAL_SCREEN, setRootScreen } from '../../Navigation';
import LocalStorageKeys from '../../Constants/LocalStorageKeys';
// singleton class
import APIURLServiceSingleton from '../../Services/APIURLService';
// Strings
import { en } from '../../Strings';
//Base Controller
import BaseController from '../BaseController';

const { overlayContainer, flex1, w100, mb30, h100, justifyContentCenter, alignItemsCenter, mb20, px20, px10, textWhite, textCenter } = GlobalStyles;

class Splash extends BaseController {
    state = {
        showTryButton: false,
    };

    isConnected = false;

    /*
    * lifecycle method called when component mount
    */
    componentDidMount() {
        NetInfo.isConnected.addEventListener('connectionChange', this._handleConnectionChange);
        // hide splash screen

        setTimeout(() => {
            SplashScreen.hide();
            NetInfo.isConnected.fetch().done((isConnected) => {
                this._handleConnectionChange(isConnected);
                this.initializeApp();
            });
        }, 1000);
    }

    /**
     * Function to initialize Application
     */
    async initializeApp() {
        if (this.isConnected) {
            //...... connection code here
        } else {
            Toast.showWithGravity('Please check your internet connection and try again.', Toast.LONG, Toast.CENTER);
        }
    }

    /*
    * lifecycle method called when component unmount
    */
    componentWillUnmount() {
        NetInfo.isConnected.removeEventListener('connectionChange', this._handleConnectionChange);
    }

    /**
     * Function to handle connection change
     */
    _handleConnectionChange = (isConnected) => {
        if (isConnected) {
            this.isConnected = isConnected;
        } else {
            this.isConnected = isConnected;
            this.setState({ showTryButton: true });
        }
    };

    /**
     * Function called on try again
     */
    async onTryAgain() {
        if (this.isConnected) {
            this.setState({ showTryButton: false });
        }
        await this.initializeApp();
    }

    // render method
    render() {
        const { showTryButton } = this.state;
        const { serverError } = this.props;
        return (
            <View style={[flex1]}>
                <ImageView style={[overlayContainer, w100, h100]} resizeMode="cover" source={Images.splash} />
                {..... my other code here}
            </View>
        );
    }
}



export default connect(null, { appInitialize, loader })(Splash);

My AppDelegate.m file::

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <ReactNativeNavigation/ReactNativeNavigation.h>
#import "RNSplashScreen.h"


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
 
  NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  
  [ReactNativeNavigation bootstrap:jsCodeLocation launchOptions:launchOptions];
  [RNSplashScreen show];
  
  return YES;
}

@end

Environment Description::

  • "react-native": "0.61.4"

  • "react": "16.12.0"

  • "react-native-navigation": "3.5.1"

  • "react-native-splash-screen": "3.2.0"

  • xcode: 11.2.1

like image 585
Archana Sharma Avatar asked Nov 07 '25 12:11

Archana Sharma


1 Answers

From the crash message, it seems you forgot to set the root view controller for the current window.

Also, as you mentioned, it is fine if it redirects to Login page. Checking the code, I saw that setRootScreen(AUTH, INITIAL_SCREEN) is only called once the user need to login. My assumption is, you might need to set the root screen once the user logged in successful as well?

If it doesn't work, then you should check how you redirect to the splash view controller. Is the react native view embedded inside another native view controller? We might need to see your native code here to troubleshoot if it doesn't work neither.

You can refer to this article to understand more about the communication.

Hope it helps.

like image 98
Xuan-Gieng Nguyen Avatar answered Nov 09 '25 14:11

Xuan-Gieng Nguyen