Repository: flutter
Issue: Fails to Load Info.plist in macOS with vscode and Android Studio
Labels: engine,platform-mac,a: desktop,has reproducible steps,P2,c: fatal crash,team-tool,triaged-tool,found in release: 3.13,found in release: 3.14

### Is there an existing issue for this?

- [X] I have searched the [existing issues](https://github.com/flutter/flutter/issues)
- [X] I have read the [guide to filing a bug](https://flutter.dev/docs/resources/bug-reports)

### Steps to reproduce

1. create project with macOS enable
2. replace main.dart to
```dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: FilledButton(
            onPressed: () async => const MethodChannel('example')
                .invokeMethod<void>('requestPermission'),
            child: const Text('requestPermission'),
          ),
        ),
      ),
    );
  }
}
```
3. replace info.plist to
```
<?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>
	<!-- ADD THIS KEY -->
	<key>NSPhotoLibraryUsageDescription</key>
	<string>Description</string>
	<!-- ADD THIS KEY -->

	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIconFile</key>
	<string></string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>$(FLUTTER_BUILD_NAME)</string>
	<key>CFBundleVersion</key>
	<string>$(FLUTTER_BUILD_NUMBER)</string>
	<key>LSMinimumSystemVersion</key>
	<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
	<key>NSHumanReadableCopyright</key>
	<string>$(PRODUCT_COPYRIGHT)</string>
	<key>NSMainNibFile</key>
	<string>MainMenu</string>
	<key>NSPrincipalClass</key>
	<string>NSApplication</string>
</dict>
</plist>
```
4. replace MainFlutterWindow.swift to
```swift
import Cocoa
import FlutterMacOS
import Photos

class MainFlutterWindow: NSWindow {
  override func awakeFromNib() {
    let flutterViewController = FlutterViewController()
    let windowFrame = frame
    contentViewController = flutterViewController
    setFrame(windowFrame, display: true)

    let channel = FlutterMethodChannel(
      name: "example",
      binaryMessenger: flutterViewController.engine.binaryMessenger
    )

    channel.setMethodCallHandler { call, result in
      switch call.method {
      case "requestPermission":
        PHPhotoLibrary.requestAuthorization { _ in }
      default:
        result(FlutterMethodNotImplemented)
      }
    }

    RegisterGeneratedPlugins(registry: flutterViewController)
    super.awakeFromNib()
  }
}
```

### Expected results

A permissions dialog will appear, or if already allowed, nothing will happen.
At least it does not crash.

### Actual results

Info.plist does not load properly and crashes.

If I run `flutter run -d macos` from a terminal app on a mac, it does not crash and works fine.
With vscode, the app crashes whether I run it from the GUI or from the terminal.
Android studio shows a crash report in addition to the crash. If I select `re-open` in that window, the app runs fine. I think this is a clue to the solution. Furthermore, it seems that info.plist is not loaded properly, as you can see from the following log in that crash report.
```
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.
```

However, when I check to see if the key exists from the application, I find that it is loaded correctly. The steps to check thet are as follows

1. update main.dart to
```dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

const channel = MethodChannel('example');

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              FilledButton(
                onPressed: () async =>
                    channel.invokeMethod<void>('requestPermission'),
                child: const Text('requestPermission'),
              ),
              FilledButton(
                onPressed: () async {
                  final hasKey = await channel.invokeMethod<bool>('hasKey');
                  print(hasKey);
                },
                child: const Text('hasKey'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
```
2. update MainFlutterWindow.swift to
```swift
import Cocoa
import FlutterMacOS
import Photos

class MainFlutterWindow: NSWindow {
  override func awakeFromNib() {
    let flutterViewController = FlutterViewController()
    let windowFrame = frame
    contentViewController = flutterViewController
    setFrame(windowFrame, display: true)

    let channel = FlutterMethodChannel(
      name: "example",
      binaryMessenger: flutterViewController.engine.binaryMessenger
    )

    channel.setMethodCallHandler { call, result in
      switch call.method {
      case "requestPermission":
        PHPhotoLibrary.requestAuthorization { _ in }
      case "hasKey":
        result(Bundle.main.object(forInfoDictionaryKey: "NSPhotoLibraryUsageDescription") != nil)
      default:
        result(FlutterMethodNotImplemented)
      }
    }

    RegisterGeneratedPlugins(registry: flutterViewController)
    super.awakeFromNib()
  }
}
```

Similar issue #70374 

### Screenshots or Video

<details>
<summary>Screenshots / Video demonstration</summary>



https://github.com/flutter/flutter/assets/50433979/67f75bec-d78c-485c-989b-db685beddc0c

https://github.com/flutter/flutter/assets/50433979/35e50ad1-a8be-4e00-9fb5-6dc33e71afea



</details>


### Logs

<details><summary>Logs</summary>

```
-------------------------------------
Translated Report (Full Report Below)
-------------------------------------

Process:               example [84248]
Path:                  /Users/USER/*/example.app/Contents/MacOS/example
Identifier:            com.example.example
Version:               1.0.0 (1)
Code Type:             ARM-64 (Native)
Parent Process:        dart [84133]
Responsible:           studio [82163]
User ID:               501

Date/Time:             2023-09-07 12:22:48.4832 +0900
OS Version:            macOS 13.5.1 (22G90)
Report Version:        12
Anonymous UUID:        42AFA833-CC36-059C-4787-DBCEEAAD40B7

Sleep/Wake UUID:       EC96F29A-8D9B-4DB9-9C1A-0DEFAFAE8E62

Time Awake Since Boot: 32000 seconds
Time Since Wake:       4191 seconds

System Integrity Protection: enabled

Crashed Thread:        2  Dispatch queue: com.apple.root.default-qos

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000

Termination Reason:    Namespace TCC, Code 0 
This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.
```
For more:
[crash_log.txt](https://github.com/flutter/flutter/files/12544462/crash_log.txt)

</details>


### Flutter Doctor output

<details><summary>Doctor output</summary>

```console
[✓] Flutter (Channel beta, 3.14.0-0.2.pre, on macOS 13.5.1 22G90 darwin-arm64, locale ja-JP)
    • Flutter version 3.14.0-0.2.pre on channel beta at /Users/xxx/Hack/Tools/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 123453dc41 (6 days ago), 2023-08-31 13:50:44 -0700
    • Engine revision b93c76ab94
    • Dart version 3.2.0 (build 3.2.0-42.2.beta)
    • DevTools version 2.26.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/xxx/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E300c
    • CocoaPods version 1.12.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] VS Code (version 1.81.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.73.20230904

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.5.1 22G90 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 116.0.5845.140

[✓] Network resources
    • All expected network resources are available.

• No issues found!
```

</details>