【Flutter】デバイスの設定画面へ遷移する

# 要件
アプリからOSの設定画面へ遷移したい

# SDK
既存のSDKで実現できるかを調べてみました。
下記のSDKでOSのアプリ設定画面が開けます。
 - [permission_handler](https://pub.dev/packages/permission_handler)
 - [app_settings](https://pub.dev/packages/app_settings)
permission_handlerについて、iOSとAndroidともOSのアプリを開けます。
サンプルソースは下記です。
```dart
import 'package:permission_handler/permission_handler.dart';

TextButton(
  onPressed: () async {
    openAppSettings();
  },
  style: TextButton.styleFrom(
    primary: Colors.blue,
  ),
  child: Text('設定を開く'),
),
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2491433/04359202-f69e-1f76-514e-a960bc4f1892.jpeg"width=250>


app_settingsについて、下記の遷移画面が用意されていますが、Android側が通常動作できますが、iOS側について、アップル社の規定により、メイン設定画面へ遷移することしか許されてないようです。詳細は下記のgithubのissuesにも掲載されています。[app_settings](https://github.com/spencerccf/app_settings/issues/153#issuecomment-1282589335)
- openAppSettings
- openWIFISettings
- openLocationSettings
- openSecuritySettings
- openBluetoothSettings
- openDataRoamingSettings
- openDateSettings
- openDisplaySettings
- openNotificationSettings
- openSoundSettings
- openInternalStorageSettings
- openBatteryOptimizationSettings
- openDevelopmentSettings

```dart
      ElevatedButton(
        child: Text("Location"),
        onPressed: () {
          AppSettings.openLocationSettings();
        },
      ),
```

# Method Channel
## iOS
iOSの場合、上記のSDKを使うとOSの対象アプリの設定画面へ遷移してしまうため、メイン設定画面へ遷移したい場合は下記の方法で遷移できる
- method channelの作成
/ios/Runner/AppDelegate.swift
上記ファイルに下記のソースを追加することで、iOSで設定画面へ遷移することが可能です。
※App-Prefs:root=***子メニューまでやったら、アップル審査にリジェクトされるそうです。

> Guideline 2.5.1 - Performance - Software Requirements   Your app uses the "prefs:root=" non-public URL scheme, which is a private entity. The use of non-public APIs is not permitted on the App Store because it can lead to a poor user experience should these APIs change.  Specifically, your app uses the following non-public URL scheme:  app-prefs:root=notifications_id&path=  Next Steps  To resolve this issue, please revise your app to provide the associated functionality using public APIs or remove the functionality using the "prefs:root" or "App-Prefs:root" URL scheme. 


```swift
    GeneratedPluginRegistrant.register(with: self)
    // 追加start
    let methodChannelName = "openSetting"
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let settingsChannel = FlutterMethodChannel(name: methodChannelName, binaryMessenger: controller as! FlutterBinaryMessenger)

    // MethodChannelからのメッセージを受け取ります
    settingsChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
      if (call.method == "openSetting") {
        let url = URL(string: "App-Prefs:root")
        let app = UIApplication.shared
        result(app.openURL(url!))
      } else {
        result(FlutterMethodNotImplemented)
      }
    })
    // 追加end
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)

```
- 呼び出し

```dart
const channel = MethodChannel("openSetting");
channel.invokeMethod('openSetting');
```

# 参考
- [iOS URLスキーマ](https://medium.com/@contact.jmeyers/complete-list-of-ios-url-schemes-for-apple-settings-always-updated-20871139d72f)
- [github issues](https://github.com/spencerccf/app_settings/issues/153#issuecomment-1282589335)