在 React Native 中访问相机

Posted

技术标签:

【中文标题】在 React Native 中访问相机【英文标题】:Accessing camera in React Native 【发布时间】:2016-10-29 15:18:25 【问题描述】:

TL;DR:不适用于 IOS10 模拟器。不过,IOS9 似乎还不错。

我一直在尝试实现 L Wansbrough 的 react-native-camera 模块,似乎每个人都推荐它。在 10 小时未能让它工作之后,我真的需要一些帮助。

我放弃了尝试将它融入我现有的项目,所以现在我只是尝试在一个全新的领域从头开始做这件事。这就是我正在做的:

react-native init cameraProject

好的,新项目制作完成。让我们确保版本正确:

react-native -v

我得到了react-native-cli: 1.0.0 react-native: 0.36.0 返回。只是为了全面检查要求:

java -version

返回:java 版本“1.8.0_112” Java(TM) SE 运行时环境 (build 1.8.0_112-b16) Java HotSpot(TM) 64 位服务器 VM(内部版本 25.112-b16,混合模式)

所以要求看起来很可靠。现在:

react-native run-ios

成功 - 应用程序在模拟器中运行,一切正常。现在我尝试按照文档安装 react-native-camera。首先,有一个关于我的模拟器正在运行的 iOS10 的新要求部分。您需要将有关相机的隐私密钥添加到 Info.plist 文件中。这似乎已从源代码的示例信息文件中省略,并且文档没有所需的代码。我已经挖掘并将以下内容添加到cameraProject/ios/cameraProject/Info.plist

<key>NSPhotoLibraryUsageDescription</key>
<string>Going to use some photos</string>

这是在列表中按字母顺序添加的,在第 25 行附近。令人耳目一新的模拟器,一切都很好。下一个:

npm install react-native-camera@https://github.com/lwansbrough/react-native-camera.git --save

后跟:

react-native link react-native-camera

完美;我收到了我期望的消息:

rnpm-install info Linking react-native-camera android dependency 
rnpm-install info Android module react-native-camera has been successfully linked 
rnpm-install info Linking react-native-camera ios dependency 
rnpm-install info iOS module react-native-camera has been successfully linked 

一切仍然正常。进入“使用”部分。我将从 GitHub 复制代码并将其粘贴到名为 BadInstagramCloneApp.js 的模块中,然后将其导入 index.ios.js 并使用基本的import BadInstagramCloneApp from './BadInstagramCloneApp'; 并将其粘贴在主体中&lt;BadInstagramCloneApp /&gt;

刷新模拟器: Error

好的,所以退出模拟器,关闭终端并重新运行react-native run-ios,因为我认为应该重建。还是不行,抛出:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.  Check the render method of 'cameraProject'.

我已经加载了 Xcode 并查看了链接文件的手动说明。我的库文件夹已经有RCTCamera.xcodeproj 文件。在 cameraProject->Build Phases->Link Binary with Libraries 部分中也已经有了libRCTCamera.a。标头搜索路径中包含正确的项目,并且根据说明将它们都标记为“递归”。然后 CMD+R 运行项目。新的模拟器加载,看起来它会工作,然后以相同的红色屏幕摔倒。退出 Xcode,再次从终端运行 react-native run-ios(说构建成功),它仍然给出与上述相同的错误。

我已经尝试了所有我能想到的排列方式。我已经尝试从示例文件中复制代码,我已经尝试过旧版本的模块,并且我已经在网上遵循了一些应该启动 react-native-camera 的教程。除了红屏或应用程序崩溃之外,我尝试过的任何事情都没有结束。

建议?我要做的就是允许用户拍照,然后将该照片作为 Base64 编码对象返回。

index.ios.js

import React,  Component  from 'react';
import 
  AppRegistry,
  StyleSheet,
  Text,
  View
 from 'react-native';

import BadInstagramCloneApp from './BadInstagramCloneApp';

export default class cameraProject extends Component 
  render() 
    return (
      <View style=styles.container>
        <BadInstagramCloneApp />
      </View>
    );
  


const styles = StyleSheet.create(
  container: 
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  
);

AppRegistry.registerComponent('cameraProject', () => cameraProject);

BadInstagramCloneApp.js

'use strict';
import React,  Component  from 'react';
import 
  AppRegistry,
  Dimensions,
  StyleSheet,
  Text,
  TouchableHighlight,
  View
 from 'react-native';
import Camera from 'react-native-camera';

class BadInstagramCloneApp extends Component 
  render() 
    return (
      <View style=styles.container>
        <Camera
          ref=(cam) => 
            this.camera = cam;
          
          style=styles.preview
          aspect=Camera.constants.Aspect.fill>
          <Text style=styles.capture onPress=this.takePicture.bind(this)>[CAPTURE]</Text>
        </Camera>
      </View>
    );
  

  takePicture() 
    this.camera.capture()
      .then((data) => console.log(data))
      .catch(err => console.error(err));
  


const styles = StyleSheet.create(
  container: 
    flex: 1
  ,
  preview: 
    flex: 1,
    justifyContent: 'flex-end',
    alignItems: 'center',
    height: Dimensions.get('window').height,
    width: Dimensions.get('window').width
  ,
  capture: 
    flex: 0,
    backgroundColor: '#fff',
    borderRadius: 5,
    color: '#000',
    padding: 10,
    margin: 40
  
);

// AppRegistry.registerComponent('BadInstagramCloneApp', () => BadInstagramCloneApp);
// AppRegistry.registerComponent('cameraProject', () => BadInstagramCloneApp);
module.exports = (BadInstagramCloneApp);

console.log 然后抛出这个:

ExceptionsManager.js:62Cannot read property 'Aspect' of undefinedhandleException @ ExceptionsManager.js:62handleError @ InitializejavascriptAppEngine.js:120reportFatalError @ error-guard.js:30guardedLoadModule @ require.js:60_require @ require.js:49(anonymous function) @ require-0.js:1executeApplicationScript @ debuggerWorker.js:20onmessage @ debuggerWorker.js:38
RCTLog.js:38Running application cameraProject (
    initialProps =     
    ;
    rootTag = 1;
)
ExceptionsManager.js:62Module AppRegistry is not a registered callable module (calling runApplication)handleException @ ExceptionsManager.js:62handleError @ InitializeJavaScriptAppEngine.js:120reportFatalError @ error-guard.js:30guard @ MessageQueue.js:48callFunctionReturnFlushedQueue @ MessageQueue.js:107onmessage @ debuggerWorker.js:44
ExceptionsManager.js:82Unhandled JS Exception: Cannot read property 'Aspect' of undefinedreactConsoleError @ ExceptionsManager.js:82logIfNoNativeHook @ RCTLog.js:38__callFunction @ MessageQueue.js:236(anonymous function) @ MessageQueue.js:108guard @ MessageQueue.js:46callFunctionReturnFlushedQueue @ MessageQueue.js:107onmessage @ debuggerWorker.js:44
ExceptionsManager.js:82Unhandled JS Exception: Module AppRegistry is not a registered callable module (calling runApplication)

如果我退出所有内容,重新加载,使用react-native run-ios 重建,那么项目会正确构建,但在显示初始屏幕后崩溃。控制台不记录任何错误,但如果我从开发工具中选择“暂停所有捕获的异常”,那么它会在此处显示停止:

**_nodeUtil.js**
/** Used to access faster Node.js helpers. */
var nodeUtil = (function() 
  try 
    return freeProcess && freeProcess.binding('util');
   catch (e) 
());

如果我尝试从 Xcode 而不是终端运行,那么它会正确构建,模拟器会启动,但在 Xcode 中它会打开 cameraProject->Libraries->RCTCamera.xcodeproj->RCTCameraManager.m 并突出显示第 988 行:

[self.session commitConfiguration]; <Thread 1: EXC_BAD_ACCESS (code=1, address=0x50)

对此有什么想法吗?

【问题讨论】:

应该发布您的相机组件的完整代码。 你是对的。按建议修改。 module.exports = (BadInstagramCloneApp); badInstagramCloneApps.js 而不是 AppRegistry.registerComponent('BadInstagramCloneApp', () => BadInstagramCloneApp); 这当然有所作为;一旦您启动应用程序,模拟器就会退出并返回主屏幕。我尝试退出模拟器并从终端重新运行 react-native run-ios 并且构建成功,但应用程序仍然立即崩溃并退出到主屏幕。 这看起来像是 IOS10 模拟器的问题(不确定真正的硬件)。我已经安装了IOS9,相机似乎可以工作了! 12 小时来解决这个问题...... 【参考方案1】:

我正在处理的项目中遇到同样的问题。根据this gitHub issue 的说法,问题是新的 iOS 10 相机权限的组合,也可能是模拟器相机支持本身的问题。我发现如果我直接在 XCode 中打开 xcodeproj 文件,模拟器可以正常打开。我仍然没有找到永久修复,但是从 XCode 而不是 react-native run-ios 运行构建对我来说绕过了这个问题。如果我找到更好的选择,我会跟进。

【讨论】:

在 XCode 中试过这个。构建失败。得到 27 个与 RCTCamera 相关的错误。重置缓存以及什么都没有。【参考方案2】:

如果我退出所有内容,重新加载,使用react-native run-ios 重建,然后 该项目正确构建,但在启动画面后崩溃 被陈列。控制台不记录任何错误,但如果我选择“暂停” 从开发工具中捕获的所有异常,然后显示停止 这里:

_nodeUtil.js

用于访问更快的 Node.js 助手。

var nodeUtil = (function()    
    try 
      return freeProcess && freeProcess.binding('util');   
     catch (e)  
 ());

我只能告诉你,这与你的问题无关,它总是会发生。看这里: React Native - debugging exception

【讨论】:

以上是关于在 React Native 中访问相机的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 react-native-webview 访问相机

在 react-Native 中退出相机视图

react-native:无法使用发布模式访问Android权限

使用 react-native-camera,如何访问保存的图片?

如何使用 react-native 将图像放在相机视图的顶部

如何使用 react-native-camera 从相机胶卷 url 显示图像?