React Native应用在调试模式下可以运行,但在iOS的发布模式下无法运行。

9

我有一个基于React Native的应用程序。在iOS上,调试模式可以正常工作。但是发布模式无法正常工作。我尝试更改优化级别,但没有帮助。问题在于我没有看到任何错误。只是某些功能不起作用。而且我无法调试发布版本的应用程序。如何解决这个问题?

最后我们添加了以下saga,当我们删除调用此saga时,它可以正常工作。

import { select, take, takeLatest, call, put, fork, race } from 'redux-saga/effects';
import R from 'ramda';
import V from 'o-validator';
import * as actionCreators from './actions';
import { redirectTo, showModalError, showModal, showOtp, closeOtp, errorOtp, loader, keychainSet } from '../../../actions/app-actions';
import { storeSession, refreshSession } from '../../../actions/session-actions';
import I18n from 'react-native-i18n';
import {
  KEYCHAIN_RESET,
  KEYCHAIN_GET,
  KEYCHAIN_RESULT
} from '../../../constants/action-types';


import { validatePassword, createCustomError, serverError } from '../../../services/utils';

const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))


export function * ChangePasswordWatcher( api, action ) {
        yield fork( ChangePasswordFormWatcher, api, action );
}

export function * ChangePasswordFormWatcher(api, action){
  while (true) {
    yield race({
      changePasswordProcess: call(ChangePasswordStart, api),
      cancel: take(['CHANGE_PASSWORD_PASSWORD_RESET'])
    });
    //yield put( loader('hide') );
        yield put( loader('hide') );


  }
}




/**
 * Change Password Sagas starter
 *
 * @param {function} api - api object
 * @param {object} action - action from dispatch
 * @returns
 */
export function * ChangePasswordStart(api, action) {
    try {
            while (true) {
                const { formData } = yield take('CHANGE_PASSWORD_FORM_SUBMIT');
                                let oldPassword = formData.oldPassword;
                                let newPassword = formData.newPassword;
                                let newPasswordConfirmation = formData.newPasswordConfirmation;


                                yield put({
                                type: 'CHANGE_PASSWORD_FORM_VALID'
                              });

                                const validate = validateForm( 'changePasswordForm', formData );
                                if ( validate.valid ) {
                                        yield put( actionCreators.submitChangePasswordFormValid() );
                                        yield put( loader('show') );


                                        let newPasswordResponse = yield call( api.setChangePassword, oldPassword, newPassword);
                    yield put( loader('hide') );
                    if ( !newPasswordResponse.ok ) {

                                            let errors = serverError(newPasswordResponse);
                                            console.log(errors);
                                      console.log('errors newPasswordResponse');

                                      yield put( showModalError({ error: errors }));
                                      yield put( actionCreators.submitNewPasswordFormFailed( errors ) );

                                        //  return false;
                                        }
                                        else {


                                        yield put({
                                            type: KEYCHAIN_GET,
                                            // resultAction: ''
                                        });


                                        const keychain = yield take(KEYCHAIN_RESULT);

                    // Save to Keychain
                                        yield put( keychainSet({
                                            login: keychain.login || false,
                                            password: keychain.password || false
                                        }) );

                            // final screen
                                        yield put( redirectTo('thankyou') );
                                        yield call( delay, 300 );
                                        yield put( actionCreators.changePasswordResetState() );
                                    }

                                }
                                else {
                                    yield put( showModalError({ error: validate.errors }));
                                    yield put( actionCreators.submitChangePasswordFormFailed( validate.errors ));
                                    yield put( actionCreators.changePasswordFailed() );


                    //                      yield put( actionCreators.submitFinFormFailed( ret.errors ) );
                //                      yield put( actionCreators.registrationFailed());
                              }
          // Reset login
         //  yield call( delay, 300 );
        //  yield put( actionCreators.resetState() );

        }

    } catch (e) {
            console.log(e);
    }


}




export function validateForm( formKey, formData ) {
  let
  ret = {
    valid: true,
    errors: false
  },
  schema: {};

  switch ( formKey ) {
    case 'changePasswordForm':
        schema = {
                    oldPassword: V.required( validatePassword ),
                    newPassword: V.required( validatePassword ),
                    newPasswordConfirmation: V.required( R.equals( formData.newPassword ) )
                };
      break;

    default:
      break;
  }

  ret.valid = V.validate( schema, formData );

  if ( !ret.valid ) {
    ret.errors = V.getErrors( schema, formData );
    ret.errors = R.zipObj( R.pluck('property', ret.errors), ret.errors );
  }

  console.log('isValid: ' + ret.valid.toString());

  return ret;
}

为所有 Console.log 语句添加注释并不起作用。
import { select, take, takeLatest, call, put, fork, race } from 'redux-saga/effects';
import R from 'ramda';
import V from 'o-validator';
import * as actionCreators from './actions';
import { redirectTo, showModalError, showModal, showOtp, closeOtp, errorOtp, loader, keychainSet } from '../../../actions/app-actions';
import { storeSession, refreshSession } from '../../../actions/session-actions';
import I18n from 'react-native-i18n';
import {
  KEYCHAIN_RESET,
  KEYCHAIN_GET,
  KEYCHAIN_RESULT
} from '../../../constants/action-types';


import { validatePassword, createCustomError, serverError } from '../../../services/utils';

const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))


export function * changePasswordScreenWatcher( api, action ) {
        yield fork( ChangePasswordFormWatcher, api, action );
}

export function * ChangePasswordFormWatcher(api, action){
  while (true) {
    yield race({
      changePasswordProcess: call(ChangePasswordStart, api),
      cancel: take(['CHANGE_PASSWORD_PASSWORD_RESET'])
    });
    //yield put( loader('hide') );
        yield put( loader('hide') );


  }
}




/**
 * Change Password Sagas starter
 *
 * @param {function} api - api object
 * @param {object} action - action from dispatch
 * @returns
 */
export function * ChangePasswordStart(api, action) {
    try {
            while (true) {
                const { formData } = yield take('CHANGE_PASSWORD_FORM_SUBMIT');
                                let oldPassword = formData.oldPassword;
                                let newPassword = formData.newPassword;
                                let newPasswordConfirmation = formData.newPasswordConfirmation;


                                yield put({
                                type: 'CHANGE_PASSWORD_FORM_VALID'
                              });

                                const validate = validateForm( 'changePasswordForm', formData );
                                if ( validate.valid ) {
                                        yield put( actionCreators.submitChangePasswordFormValid() );
                                        yield put( loader('show') );


                                        let newPasswordResponse = yield call( api.setChangePassword, oldPassword, newPassword);
                    yield put( loader('hide') );
                    if ( !newPasswordResponse.ok ) {

                                            let errors = serverError(newPasswordResponse);
                                            //console.log(errors);
                                      //console.log('errors newPasswordResponse');

                                      yield put( showModalError({ error: errors }));
                                      yield put( actionCreators.submitNewPasswordFormFailed( errors ) );

                                        //  return false;
                                        }
                                        else {


                                        yield put({
                                            type: KEYCHAIN_GET,
                                            // resultAction: ''
                                        });


                                        const keychain = yield take(KEYCHAIN_RESULT);

                    // Save to Keychain
                                        yield put( keychainSet({
                                            login: keychain.login || false,
                                            password: keychain.password || false
                                        }) );

                            // final screen
                                        yield put( redirectTo('thankyou') );
                                        yield call( delay, 300 );
                                        yield put( actionCreators.changePasswordResetState() );
                                    }

                                }
                                else {
                                    yield put( showModalError({ error: validate.errors }));
                                    yield put( actionCreators.submitChangePasswordFormFailed( validate.errors ));
                                    yield put( actionCreators.changePasswordFailed() );


                    //                      yield put( actionCreators.submitFinFormFailed( ret.errors ) );
                //                      yield put( actionCreators.registrationFailed());
                              }
          // Reset login
         //  yield call( delay, 300 );
        //  yield put( actionCreators.resetState() );

        }

    } catch (e) {
            //console.log(e);
    }


}




export function validateForm( formKey, formData ) {
  let ret = {
    valid: true,
    errors: false
  };

  switch ( formKey ) {
    case 'changePasswordForm':
        schema = {
                    oldPassword: V.required( validatePassword ),
                    newPassword: V.required( validatePassword ),
                    newPasswordConfirmation: V.required( R.equals( formData.newPassword ) )
                };
      break;

    default:
      break;
  }

  ret.valid = V.validate( schema, formData );

  if ( !ret.valid ) {
    ret.errors = V.getErrors( schema, formData );
    ret.errors = R.zipObj( R.pluck('property', ret.errors), ret.errors );
  }

  //console.log('isValid: ' + ret.valid.toString());

  return ret;
}

你能分享一个样例代码库以便复现问题吗? - Pritish Vaidya
如果您希望其他人理解您的问题,您需要更好地描述“发布模式不起作用”的含义。因此,请首先张贴您遇到的任何错误或详细描述问题。 - Mihai Fratu
@MihaiFratu,没有语法错误,只是没有关闭加载对话框。 - Kamil Ibadov
你确定在发布产品时没有编译任何 console.log 吗?你的真实手机没有所谓的 console 全局对象,这会导致你的应用崩溃。 - Jimi Pajala
一个问题,为什么你要在代码中使用 while (true)?我认为这会使你的代码运行一个无限循环,并最终崩溃。 - Alfian Busyro
显示剩余3条评论
3个回答

0
根据提供的信息,似乎在切换调试模式和发布模式时,您正在加载不同的捆绑包。
确保您已经配置您的应用程序在发布模式下使用静态捆绑包
然后您的应用程序将在两种模式下呈现相同的捆绑包,其行为可能是您所期望的。

0

有一个库与你的iOS应用程序版本冲突。尝试逐个删除库,看每次尝试是否起作用。

一个捷径是检查你正在使用的库的代码,并查看库正在使用的任何API是否已弃用。

我遇到了类似的问题,在我的情况下,是lottie-animation引起了问题。希望你能解决它。


-3

看起来你在代码中使用了console.log。由于你的真实手机环境没有console-全局变量,请确保在编译到生产版本之前将其清除。

编辑

先前的说法并不完全正确。尽管我自己遇到过一些边缘情况,其中console.log在非调试模式下运行时会导致应用程序崩溃,但似乎并非总是如此,生产构建也可以在其位置上运行。无论如何,应考虑通过删除它们可能实现的性能提升https://facebook.github.io/react-native/docs/performance.html#performance


2
你的观点是错误的。React Native在底层有JavascriptCore引擎,因此console.log甚至可以在生产环境中使用。自己试试吧,你不会受到伤害的。 - Alfian Busyro
看起来你是对的。在生产环境中删除它们的唯一相关原因似乎是为了提高性能。https://facebook.github.io/react-native/docs/performance.html#performance - Jimi Pajala
如果你记录了大量数据,那么它会影响性能。因此,明智地使用console.log。此外,如果你关注性能的话,渲染比console.log更为重要。 - Alfian Busyro
我不知道为什么有人给了这些负面评价,但这对我起作用了。 - Gandalf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接