AsyncStorage参考崩溃会对iOS上的本机应用做出反应

时间:2018-11-12 16:05:09

标签: ios react-native expo

我一直在使用ExpoKit开发一个依赖于AsyncStorage使用的应用程序,在我希望将其部署到产品中之前,一切工作都很好。

在我的package.json中,我有: "react-native": "https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz" 并且Pod和我的项目的iOS Deployment Target都设置为10.0。 如果需要,我可以提供更多的调试信息,不确定在这种情况下有什么意义。

出于不同的原因,我不想使用ExpoKit的默认方式在生产应用程序中托管捆绑软件,但仍然希望保留expo的开发工具,因此我将AppDelegate.m的代码更改为:

#import "AppDelegate.h"
#import "ExpoKit.h"
#import "EXViewController.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

@interface AppDelegate ()

@property (nonatomic, strong) EXViewController *rootViewControllerExpo;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    #ifdef DEBUG
        // Expo
        [[ExpoKit sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
        _rootViewControllerExpo = [ExpoKit sharedInstance].rootViewController;

        _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _window.backgroundColor = [UIColor whiteColor];
        _window.rootViewController = _rootViewControllerExpo;
        [_window makeKeyAndVisible];
    #else
        // React Native
        NSURL *jsCodeLocation;
        jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];

        RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                            moduleName:@"RentalCollectorsApp"
                                                     initialProperties:nil
                                                         launchOptions:launchOptions];

        UIViewController *rootViewController = [UIViewController new];
        rootViewController.view = rootView;

        _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _window.backgroundColor = [UIColor whiteColor];
        _window.rootViewController = rootViewController;
        [_window makeKeyAndVisible];

        //        UIView* launchScreenView = [[[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil] objectAtIndex:0];
        //        launchScreenView.frame = self.window.bounds;
        //        rootView.loadingView = launchScreenView;
    #endif

    return YES;
}

然后,我的应用程序与ExpoKit完全兼容,在执行带有以下消息的发布方案时,在打开时开始崩溃。使用Expo的rootViewController

时,它在调试模式下可以正常工作
[error][tid:com.facebook.react.JavaScript] undefined is not an object (evaluating 'l.multiMerge')
[fatal][tid:com.facebook.react.ExceptionsManagerQueue] Unhandled JS Exception: undefined is not an object (evaluating 'l.multiMerge')
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

经过数小时的调试,我已经确定了导致崩溃的最基本情况。本身导入AsyncStorage不会使应用程序崩溃,但是在变量中引用它会立即导致崩溃:

import React, { Component } from 'react';
import { Text, View, AsyncStorage } from 'react-native';

export default class AppContainer extends Component {
  render() {
    const bar = AsyncStorage;
    // const bar = {
    //   storage: AsyncStorage,
    // };

    return (
      <View
        style={{
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center',
          backgroundColor: 'yellow',
        }}
      >
        <Text>Hello!</Text>
      </View>
    );
  }
}

在我的特定情况下,崩溃是由使用redux-persist引起的,但问题似乎更广泛,因为当我删除redux-persist的初始化时,它开始崩溃于{{1 }}。仅供参考,代码为react-native-mapbox-gl https://github.com/rt2zz/redux-persist/blob/master/src/storage/index.native.js

Google搜索给了我一些结果,但是没有答案:

Undefined is not an object (evaluating 'RCTAsyncStorage.multiMerge' (React-native-asyncstorage)

https://github.com/facebook/react-native/issues/21948

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您不应直接将AsyncStorage分配给任何变量。如果用户启用了缓存,则要在AsyncStorage中设置一项,请执行以下操作:

import AsyncStorage from 'react-native';
const persistTest = {
   AsyncStorage
};

persistTest.AsyncStorage.setItem("testCache", "Y");

并检索此内容并继续:

persistTest.AsyncStorage.getItem("testCache").then(res => {
  this.continueTest(res);
});

我不确定100%是否能回答您的问题,因为我没有完全按照您的问题做所有事情,但这只是我的经验。如果我可以进一步帮助,请告诉我。 :)

答案 1 :(得分:0)

对于正在阅读此书并在类似问题中挣扎的人,最终在将我的头发拉了三天之久后,我们最终完全退出了世博会。基本上,我们引导了没有expo RN项目的vanilla,将所有代码移到了那里,魔术般地一切开始正常工作。

我们认为,发生这种情况的主要原因是某些本机lib之间相互冲突,并且访问某些API导致运行时崩溃,这是我们经历过的。

好消息是,我们现在有4个RN应用程序正在生产中,整个展览会永远落后于我们。

自我促销开始

如果您有兴趣从事类似这样的工作,请按相同的方式在某些Twitter中为我打气。我们正在用Bolt中的React Native做一些很棒的事情。

自我促销结束