在React Native中,如何捆绑文本文件并在运行时读取它的值?

时间:2016-05-19 08:09:28

标签: android react-native

我可能会这样做的几个原因:

  • 创建一些webview并注入从文件加载的javascript
  • 将大块文本分隔成单独的文件而不是强制它们进入视图
  • 包括要在应用程序中使用的任意格式(例如,CSV)的原始数据

在React Native中,您可以使用require导入图像文件,但据我所见,这仅适用于图像文件。它(奇怪地)也适用于JSON文件(参见Importing Text from local json file in React native)。但是,我还没有看到任何关于导入普通旧文本文件的问题。

4 个答案:

答案 0 :(得分:5)

在寻找并询问周围之后,我能想到的最好的就是使用 react-native-fs库的fork访问android" assets"。这个fork是一个pull请求,一旦合并就可以使用它。

请注意,在android dev中," assets"具体是指访问文件的原始内容。为了在本机反应中执行此类操作,您需要编写一个本机模块来与react接口,因此上面的库。请参阅here(并搜索资产)。

在您的react本机项目中,创建一个名为android/app/src/main/assets/text.txt的文件。使用上面提到的react-native-fs版本,您可以:

RNFS.readFileAssets('test.txt').then((res) => {
  console.log('read file res: ', res);
})

更新:如果你想要pull request能够让这个能力通过,你应该通过在github上竖起大拇指让作者知道你想要它。

答案 1 :(得分:1)

有一个库可以解决这个确切的问题:React-Native-Local-Resource。该库允许您在运行时异步加载Android和iOS中的任何类型的文本文件。

答案 2 :(得分:1)

这是实现FS并读取IOS和Android的文件的一个简单的本机项目示例。

https://github.com/baselka/kindleapp

(实现一个简单的应用程序,以在平板电脑上的android和iOS应用程序中呈现2个文件(书本文件。该应用程序必须像在kindle应用程序中一样模仿您正在阅读书本文件的功能)

答案 3 :(得分:0)

这是我基于React Native文档Exporting Constants在iOS和iOS / tvOS / macOS的Swift和JS中同步进行操作的方式。

  • 缺点:请注意,文件将在启动后立即加载到内存中,并且不会动态重新加载。

  • 优点:它是同步的,简单的,并且可以在运行时在本机或JS中运行。

MyJSFile.js

import { NativeModules } from "react-native";

console.log(NativeModules.MyNativeModule.MyFileContents);

我们导入本地模块并访问我们在其上公开的MyFileContents常量。它可以无桥同步地工作(据我所知,它是通过JavaScriptCore注入到React Native JSContext中的。)

Build Phases中,确保将此文件添加到Copy Bundle Resources中。否则,您的应用在尝试读取时会迅速崩溃。

MyNativeModule.swift

import Foundation

@objc(MyNativeModule)
class MyNativeModule: RCTEventEmitter {
    @objc override func constantsToExport() -> [AnyHashable : Any]! {
        let contents: String = try! String(contentsOfFile: Bundle.main.path(forResource: "MyFile.min", ofType: "js")!)
        return [
            "MyFileContents": contents
        ]
    }
    @objc override func supportedEvents() -> [String]! {
        return []
    }
    @objc override static func requiresMainQueueSetup() -> Bool {
        return false
    }
}

一个人可能会比这个人做一个更简单/更精巧的本机模块(通过子类化功能比RCTEventEmitter少的东西),但这是我一直在使用的文件,所以就在这里。 / p>

MyProject-Bridging-Header.h

#import <React/RCTBridge.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTUIManager.h>
#import <React/RCTEventEmitter.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTJavaScriptLoader.h>
#import <React/RCTLinkingManager.h>
#import <React/RCTRootView.h>
#import <React/RCTEventDispatcher.h>

这是我正在使用的桥接标头。它公开的头文件比严格要求的多得多,但是以后无论如何您可能需要将其用于其他本机模块。

由于此方法使用Swift,因此请确保输入Build Settings并将Always Embed Swift Standard Libraries设置为Yes(如果尚未设置)。而且,如果这是第一次使用嵌入式Swift构建应用程序,则可能需要在构建之前清除DerivedData的运气。

...或者按照文档中的说明,在Obj-C中重写相同的Swift代码。