expo / expo

An open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.
https://docs.expo.dev
MIT License
33.63k stars 5.39k forks source link

expo-av requires microphone permission even when not using microphone #26730

Closed paulschreiber closed 8 months ago

paulschreiber commented 8 months ago

Summary

expo-av provides both audio/video playback and audio recording functionality, requiring NSMicrophoneUsageDescription even when only used for playback.

To protect user privacy and reduce unnecessary access to protected APIs, expo-av should not require microphone usage when only used for playback. (I suspect this would require splitting microphone access into a new module.)

Previously filed as #11532 and incorrectly closed by #17168.

Environment

  expo-env-info 1.2.0 environment info:
    System:
      OS: macOS 14.2.1
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node
      Yarn: 1.22.21 - /opt/homebrew/bin/yarn
      npm: 10.2.5 - ~/.nvm/versions/node/v20.9.0/bin/npm
      Watchman: 2023.12.04.00 - /opt/homebrew/bin/watchman
    Managers:
      CocoaPods: 1.14.2 - /Users/paul/.rbenv/shims/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 23.2, iOS 17.2, macOS 14.2, tvOS 17.2, visionOS 1.0, watchOS 10.2
      Android SDK:
        API Levels: 27, 29, 30, 33, 34
        Build Tools: 30.0.3, 33.0.0, 33.0.1, 34.0.0
        System Images: android-33 | Google APIs ARM 64 v8a
    IDEs:
      Android Studio: 2022.3 AI-223.8836.35.2231.10811636
      Xcode: 15.2/15C500b - /usr/bin/xcodebuild
expo-bot commented 8 months ago

Hi there! It looks like your issue requires a minimal reproducible example, but it is invalid or absent. Please prepare such an example and share it in a new issue.

The best way to get attention to your issue is to provide a clean and easy way for a developer to reproduce the issue on their own machine. Please do not provide your entire project, or a project with more code than is necessary to reproduce the issue.

A side benefit of going through the process of narrowing down the minimal amount of code needed to reproduce the issue is that you may get lucky and discover that the bug is due to a mistake in your application code that you can quickly fix on your own.

Resources

paulschreiber commented 8 months ago

@EvanBacon @bbarthec Can you take a look/reopen this? The bot wants me to write code (but the original issue was inadvertently closed and didn't require code).

mphill commented 8 months ago

I can confirm, Apple is rejecting our app after upgrading to SDK 50 or Apple changed something.

We have expo-av 13.10.3 installed

ITMS-90683: Missing purpose string in Info.plist - Your app’s code references one or more APIs that access sensitive user data, or the app has one or more entitlements that permit such access. The Info.plist file for the “RubberBands.app” bundle should contain a NSMicrophoneUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. If you’re using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. For details, visit: https://developer.apple.com/documentation/uikit/protecting_the_user_s_privacy/requesting_access_to_protected_resources.

quentinmodena commented 8 months ago

Same here with "expo-av": "~13.10.4"

bobOnGitHub commented 8 months ago

I decided to give react-native-track-player a go to get around this - i.e just not use expo-av. That meant having to use expo-dev-client. It didn't work (expo sdk 49) and they don't support expo even though their main page says you can use it in expo...... so I'm back to react native and have to dump everything I've invested in expo ( all the expo specific libs and APIs ) - I've even considered dumping react native and going back to Apache Cordova because of what I've experienced/seen over the last year.

Failing to separate permissions for play and record was a .... bad..... decision - for some developers it is a show-stopper and nullifies anything else expo has to offer.

focux commented 8 months ago

I can confirm, Apple is rejecting our app after upgrading to SDK 50 or Apple changed something.

We have expo-av 13.10.3 installed

ITMS-90683: Missing purpose string in Info.plist - Your app’s code references one or more APIs that access sensitive user data, or the app has one or more entitlements that permit such access. The Info.plist file for the “RubberBands.app” bundle should contain a NSMicrophoneUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. If you’re using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. For details, visit: https://developer.apple.com/documentation/uikit/protecting_the_user_s_privacy/requesting_access_to_protected_resources.

Same, just got the same email from Apple.

mzaien commented 8 months ago

Same here we tried couple of solustion but non is working ...

WadhahEssam commented 8 months ago

Not sure if that decision was intended but this was a huge move to force people to add the microphone permission.

One solution could be to add the mic permission with a dummy text in the info.plist, but this means that your app will show that you need microphone in the app store which raises users suspicion (specially for a financial app like ours)

This sounds like its impossible to fix in its current state since apple is detecting recording code and flagging releases based on it, so the only solution would be to separate the recording capabilities into a different expo package.

we trust expo packages quality and long term support, and I guess many others agree, and so many people need video/audio playback without the need for recording. so please guys fix it.

for now we are migrating to react-native-video

markusjwetzel commented 8 months ago

I had the same issue and I followed the instructions from @brentvatne (see https://github.com/expo/expo/pull/17168#issuecomment-1938064979). It worked for me. 😃

First I installed patch-package by following the installation instructions on the readme.

Then I made the following changes to node_modules\expo-av\ios\EXAV\EXAudioRecordingPermissionRequester.m:

// Copyright 2016-present 650 Industries. All rights reserved.

#import <EXAV/EXAudioRecordingPermissionRequester.h>
#import <ExpoModulesCore/EXDefines.h>

// #import <AVFoundation/AVFoundation.h>

@implementation EXAudioRecordingPermissionRequester

+ (NSString *)permissionType
{
  return @"audioRecording";
}

- (NSDictionary *)getPermissions
{
  // AVAudioSessionRecordPermission systemStatus;
  EXPermissionStatus status;

  // NSString *microphoneUsageDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSMicrophoneUsageDescription"];
  // if (!microphoneUsageDescription) {
  //   EXFatal(EXErrorWithMessage(@"This app is missing NSMicrophoneUsageDescription, so audio services will fail. Add one of these keys to your bundle's Info.plist."));
  //   systemStatus = AVAudioSessionRecordPermissionDenied;
  // } else {
  //   systemStatus = [[AVAudioSession sharedInstance] recordPermission];
  // }
  // switch (systemStatus) {
  //   case AVAudioSessionRecordPermissionGranted:
  //     status = EXPermissionStatusGranted;
  //     break;
  //   case AVAudioSessionRecordPermissionDenied:
  //     status = EXPermissionStatusDenied;
  //     break;
  //   case AVAudioSessionRecordPermissionUndetermined:
  //     status = EXPermissionStatusUndetermined;
  //     break;
  // }

  status = EXPermissionStatusDenied;

  return @{
    @"status": @(status)
  };
}

- (void)requestPermissionsWithResolver:(EXPromiseResolveBlock)resolve rejecter:(EXPromiseRejectBlock)reject
{
  // EX_WEAKIFY(self)
  // [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
  //   EX_STRONGIFY(self)
  //   resolve([self getPermissions]);
  // }];
  resolve([self getPermissions]);
}

@end

Hopefully there will be a less hacky solution in the future.

buraks commented 8 months ago

Same problem here, what is the recommended way to get around this? -- besides the patch-package solution.

We only use audio playing feature, never need to use the microphone so ideally we don't want to request microphone permission or include description of why the permission might be used.

AdamGerthel commented 7 months ago

Same issue here. This needs to be optional.

Update: The patch solution works as a workaround.

IjzerenHein commented 6 months ago

Thanks for this thread guys, we ran into this problem as well and this was super helpful! ❤️

I've created a PR to tackle this problem: https://github.com/expo/expo/pull/28006

Kudo commented 6 months ago

we are proposing a different solution in #28236. could someone get rejected by the store that could help to try with the patch and see whether it works? would be much appreciated for the help!