我一直在使用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
的初始化时,它开始崩溃在react-native-mapbox-gl
的中间。仅供参考,redux-persist
的代码https://github.com/rt2zz/redux-persist/blob/master/src/storage/index.native.js
谷歌搜索给了我一些结果,但没有答案:
Undefined is not an object (evaluating 'RCTAsyncStorage.multiMerge' (React-native-asyncstorage)
https://github.com/facebook/react-native/issues/21948
任何帮助表示赞赏。
最佳答案
您不应直接将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%确定这是否能回答您的问题,因为我没有完全按照您的问题做所有事情,但这只是我的经验。如果我可以进一步帮助,请告诉我。 :)
关于ios - AsyncStorage引用崩溃对iOS上的 native 应用使用react,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53265915/