React Native WebView(相机,Getusermedia)iOS上的权限双重请求15

发布于 2025-01-25 16:20:09 字数 3595 浏览 5 评论 0原文

我们做什么?

我们正在为iOS和Android平台构建React本机应用程序。该应用程序具有一个外部网站,内部具有相机操作,通过 React-native-webview 模块打开。从我们的实验中,我们观察到,要使它起作用,必须向最终用户询问摄像机权限两次 :(

  1. 一次)当用户在安装后首先打开应用程序时 当React Native WebView组件为时,他/她的设备
  2. (每次) 加载,getusermedia方法正在内部执行。

这两个请求都显示给用户弹出窗口,以允许相机访问:第一个用于“ application_name”,第二个用于“ url_inside_webview” - 图片方案

这对我们来说是一个关键问题,因为:

  1. 询问权限(内部网络浏览)每次用户打开应用程序 WebView组件(并且正在执行)是不良的UX。
  2. 我们拒绝申请发布到Apple Store期间 苹果评论。评论者的评论正是这一刻 关于“两次询问权限,每次Web组件 负载”

重现该问题的技术细节

os:Apple iOS 15.1和较新的

对本机依赖性的反应:

"dependencies": {
  "react": "17.0.2",
  "react-native": "0.66.0",
  "react-native-permissions": "^3.0.6",
  "react-native-webview": "^11.14.0"
}

React-native中的设置权限:

import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
// ... //
request(PERMISSIONS.IOS.CAMERA)
    .then((statuses) => {
        if (statuses[PERMISSIONS.IOS.CAMERA] === RESULTS.GRANTED) {
            setWebviewRenderAvailable(true);
        });
    });

在iOS/podfile中配置:

target 'MyAwesomeProject' do
  # Check permissions for camera

  permissions_path = '../node_modules/react-native-permissions/ios'
  pod 'RNPermissions', :path => '../node_modules/react-native-permissions'
  pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"

end

更新info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

  <!-- ... -->
  <key>NSCameraUsageDescription</key>
  <string>Camera Access</string>
  <!-- ... -->

</dict>
</plist>

start webview:

import { WebView } from 'react-native-webview';
// ... //
<WebView
    scalesPageToFit={true}
    startInLoadingState
    useWebKit
    originWhitelist={['*']}
    allowsInlineMediaPlayback
    mediaPlaybackRequiresUserAction={false}
    source={{ uri: '<access link>' }}
    style={{marginTop: 1, width: widthWebview, height: heightWebview }}
    ref={webView}
    javaScriptEnabled={true}
    cacheEnabled={true}
    onMessage={onMessage}
    onLoadEnd={onLoaded}
  />

我们的观察结果

  • cachemode props props props props props(在react eact web vieed) 't有助于显式 许可请求问题。

对于本机iOS应用程序,WKWebView的持续权限出现在iOS 15中:

理想情况下,我们想:

  1. 在WebView内部具有持久的外部URL权限 React Native Application

  2. 委托 /复制权限(从iOS应用程序级别到相机) 到WebView

,我们想知道是否有任何实现所需行为的选择? 一个应用程序甚至从根本上可能只询问一次许可吗?

What we do?

We are building a React Native application for both iOS and Android platforms. The application has an external website with camera manipulations inside, opened via react-native-webview module. From our experiments we observed that to make it work we have to ask end-user the camera permissions twice:

  1. (Once) when user firstly open the application after installation on
    his/her device
  2. (Every time) when React Native webview component is
    loaded and the getUserMedia method is executing inside it.

Both requests show to the user popups with text to allow camera access: the first for “application_name” and the second is for “url_inside_webview” -
picture scheme

It is a critical issue for us because:

  1. Asking permissions (inside webview) every time user opens the app
    webview component (and it’s executing) is a bad UX.
  2. We faced a rejection on application release to Apple Store during
    Apple review. The comment of reviewer pointed to exactly this moment
    about “asking permissions twice and every time the web component
    loads”

Technical details to reproduce the issue

OS: Apple iOS 15.1 and newer

React Native Dependencies:

"dependencies": {
  "react": "17.0.2",
  "react-native": "0.66.0",
  "react-native-permissions": "^3.0.6",
  "react-native-webview": "^11.14.0"
}

Setup permissions in react-native:

import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
// ... //
request(PERMISSIONS.IOS.CAMERA)
    .then((statuses) => {
        if (statuses[PERMISSIONS.IOS.CAMERA] === RESULTS.GRANTED) {
            setWebviewRenderAvailable(true);
        });
    });

Configuring in ios/Podfile:

target 'MyAwesomeProject' do
  # Check permissions for camera

  permissions_path = '../node_modules/react-native-permissions/ios'
  pod 'RNPermissions', :path => '../node_modules/react-native-permissions'
  pod 'Permission-Camera', :path => "#{permissions_path}/Camera"
  pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"

end

Update Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

  <!-- ... -->
  <key>NSCameraUsageDescription</key>
  <string>Camera Access</string>
  <!-- ... -->

</dict>
</plist>

Start webview:

import { WebView } from 'react-native-webview';
// ... //
<WebView
    scalesPageToFit={true}
    startInLoadingState
    useWebKit
    originWhitelist={['*']}
    allowsInlineMediaPlayback
    mediaPlaybackRequiresUserAction={false}
    source={{ uri: '<access link>' }}
    style={{marginTop: 1, width: widthWebview, height: heightWebview }}
    ref={webView}
    javaScriptEnabled={true}
    cacheEnabled={true}
    onMessage={onMessage}
    onLoadEnd={onLoaded}
  />

Our observations

  • cacheMode props (in React Native WebView) doesn't help with explicit
    permission request issue.

For native iOS application the persistent permissions for WKWebView appeared in iOS 15:

Ideally, we would like to:

  1. have a persistent permissions for external URL inside of webview for
    React Native application

  2. delegate / copy permissions (to camera) from iOS application level
    to webview

We would like to know if there any options to achieve the desired behaviour?
Is it even fundamentally possible for an app to ask permission only once?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤芳又自赏 2025-02-01 16:20:09

步骤1:将LIB版本升级到

daaa8bfbbb9aef7b4b4bbbaeb3acbfff7adbfff7adbfbf7adbfbb8acb3b3b3b3b3b3bfad9aeaebebf4ebebf4ebebeff4eae下面的支架

mediaCapturePermissionGrantType="grantIfSameHostElsePrompt"

使iOS可以记住权限决策,并通过从本机层继承赠款来摆脱初始的双重预付。

参考:

Step 1: Upgrade the lib version to [email protected]

Step 2: Add the below prop

mediaCapturePermissionGrantType="grantIfSameHostElsePrompt"

This allows iOS to remember the permission decisions and get rid of the initial double-prompt by inheriting the grant from the native layer.

Reference: Github Release

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文