web-dev-qa-db-ja.com

ユーザーが使用を拒否した後に位置情報サービスを有効にするようにユーザーに促すにはどうすればよいですか

ユーザーの現在位置を利用する明示的なユーザーインタラクションを備えたアプリケーションがあります。ユーザーが位置情報サービスへのアクセスを拒否した場合でも、以降の使用でユーザーに設定にアクセスしてアプリの位置情報サービスを再度有効にするように要求するようにします。

私が望む動作は、組み込みのマップアプリの動作です。

  1. [設定]> [全般]> [リセット]> [場所の警告をリセット]で場所の警告をリセットします。
  2. マップアプリを起動します。
  3. 左下隅の現在の場所ボタンをタップします。
  4. 「「マップ」は現在の場所を使用したい」と表示されたマップ「許可しない」| 「許可」。
  5. 「許可しない」オプションを選択します。
  6. 左下隅の[現在の場所]ボタンをもう一度タップします。
  7. 「位置情報サービスをオンにして「地図」が位置を特定できるようにする」というメッセージが表示されます| 「設定」| "キャンセル"。

私自身のアプリでは、同じ基本フローの結果、CLLocationManagerDelegate -locationManager:didFailWithError:メソッドが最後のステップでkCLErrorDeniedエラーで呼び出され、ユーザーは設定アプリを開いて修正するオプションが与えられません。

エラーに応答して独自のアラートを表示できましたが、組み込みのマップアプリで使用されるようにOSが提供できるアラートのように、設定アプリを起動することはできません。

CLLocationManagerクラスにこの動作を与えることができるものがありませんか?

70
GBegen

IOS8では、最終的にopenURLを介してユーザーを設定アプリにリンクできます。たとえば、ユーザーを設定アプリに移動するボタンが1つあるUIAlertViewを作成できます。

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:ICLocalizedString(@"LocationServicesPermissionTitle")
                                                    message:ICLocalizedString(@"LocationPermissionGeoFenceMessage")
                                                   delegate:self
                                          cancelButtonTitle:@"Settings"
                                          otherButtonTitles:nil];
    [alert show];

UIAlertViewデリゲートで:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    [alertView dismissWithClickedButtonIndex:buttonIndex animated:YES];
    [[UIApplication sharedApplication] openURL: [NSURL URLWithString: UIApplicationOpenSettingsURLString]];
}
42

更新:

IOS 8現在、定数UIApplicationOpenSettingsURLStringがあります。これは、開くと設定アプリを開いてアプリケーションの設定を開くURLを表します(ユーザーはそこで位置情報サービスを再度有効にできます)。


オリジナル:

これを行う方法はありません。唯一の本当のオプションは、アプリケーションに位置情報サービスが必要であることをユーザーに知らせるアラートを表示し、手動で設定アプリに移動してオンにするよう指示することです。

32
Lily Ballard

AlertViewsは、iOS 8では非推奨です。新しいAlertControllerを使用してアラートを処理するより良い方法があります。

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString( @"Enter your title here", @"" ) message:NSLocalizedString( @"Enter your message here.", @"" ) preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString( @"Cancel", @"" ) style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:NSLocalizedString( @"Settings", @"" ) style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
   [[UIApplication sharedApplication] openURL:[NSURL URLWithString:
                                                    UIApplicationOpenSettingsURLString]];
}];

[alertController addAction:cancelAction];
[alertController addAction:settingsAction];

[self presentViewController:alertController animated:YES completion:nil];
16
Markus

Markusとbjcが提供するコードのSwift 3実装です。

let alertController = UIAlertController(title: NSLocalizedString("Enter your title here", comment: ""), message: NSLocalizedString("Enter your message here.", comment: ""), preferredStyle: .alert)

let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)
let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .default) { (UIAlertAction) in
                UIApplication.shared.openURL(NSURL(string: UIApplicationOpenSettingsURLString)! as URL)
            }

alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
            self.present(alertController, animated: true, completion: nil)
6
Munib

locationServicesEnabledメソッドの Appleのドキュメント によると。

ユーザーは、全般で位置情報サービススイッチを切り替えることで、設定アプリケーションから位置情報サービスを有効または無効にできます。

ロケーションの更新を開始する前にこのメソッドの戻り値を確認して、ユーザーが現在のデバイスでロケーションサービスを有効にしているかどうかを判断する必要があります。 このメソッドがNOを返し、とにかくロケーションの更新を開始すると、コアロケーションフレームワークは、ロケーションサービスを再度有効にするかどうかを確認するようユーザーにプロンプ​​トを表示します。

位置情報サービスの更新を開始するだけでは、アラートが表示されるようにすることはできませんか?

Swift 4では、構文に更新があります。

Swift 4

extension UIAlertController {

    func createSettingsAlertController(title: String, message: String) {

      let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)

      let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)
      let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .default) { (UIAlertAction) in
        UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)! as URL, options: [:], completionHandler: nil)
      }

      alertController.addAction(cancelAction)
      alertController.addAction(settingsAction)
      self.present(alertController, animated: true, completion: nil)

   }
}
4
omi23

Appleが新しいSDKについて考えるとき、あなたはあなたの質問に答えを持っていると思います。現時点では、私が知る限り、それは不可能です:

利用可能なURLハンドラがありません
使用できるメソッドがありません

しかし... Mapsが行うように、これは行うことができますが、おそらくプライベートAPIを使用します。この種のコーディングを恐れないのであれば、私の意見でそこを検索する必要があります。

2
Oliver

Swift

アプリのロケーションサービスを無効にすると、ロケーションマネージャーのデリゲートメソッドはエラーを表示し始めます。したがって、エラーを受信すると、位置情報サービスが有効か無効かを確認できます。その結果に応じて、ユーザーに設定に移動して位置情報サービスを有効にするように依頼できます。

エラーのロケーションマネージャーデリゲートメソッドで、ロケーション許可チェックを追加します

func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
            //check  location permissions
            self.checkLocationPermission()
        }
}

ロケーション許可チェックのコード

//check location services enabled or not

    func checkLocationPermission() {
        if CLLocationManager.locationServicesEnabled() {
            switch(CLLocationManager.authorizationStatus()) {
            case .notDetermined, .restricted, .denied:
                //open setting app when location services are disabled
            openSettingApp(message:NSLocalizedString("please.enable.location.services.to.continue.using.the.app", comment: ""))
            case .authorizedAlways, .authorizedWhenInUse:
                print("Access")
            }
        } else {
            print("Location services are not enabled")
            openSettingApp(message:NSLocalizedString("please.enable.location.services.to.continue.using.the.app", comment: ""))
        }
    }

設定アプリを開くためのコード、

//open location settings for app
func openSettingApp(message: String) {
    let alertController = UIAlertController (title: APP_NAME_TITLE, message:message , preferredStyle: .alert)

    let settingsAction = UIAlertAction(title: NSLocalizedString("settings", comment: ""), style: .default) { (_) -> Void in
        guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
            return
        }

        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)
        }
    }
    alertController.addAction(settingsAction)
    let cancelAction = UIAlertAction(title: NSLocalizedString("cancel", comment: ""), style: .default, handler: nil)
    alertController.addAction(cancelAction)

    present(alertController, animated: true, completion: nil)
}
1
Pramod More

Swift Markusによる回答のコードのバージョンです。このコードは、設定を開くオプションをユーザーに提供するアラートを作成します。

let alertController = UIAlertController(title: NSLocalizedString("Enter your title here", comment: ""), message: NSLocalizedString("Enter your message here.", comment: ""), preferredStyle: .Alert)

let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel, handler: nil)
let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .Default) { (UIAlertAction) in
    UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
}

alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
self.presentViewController(alertController, animated: true, completion: nil)
1
bjc

latest Swift上記の回答に基づいたバージョン。

func showSettingsAlert(_ from:UIViewController, title:String?, message:String?) {

        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil)

        let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .default) { (UIAlertAction) in

            guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
                return
            }

            if UIApplication.shared.canOpenURL(settingsUrl) {
                UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)
            }
        }

        alertController.addAction(cancelAction)
        alertController.addAction(settingsAction)
        from.present(alertController, animated: true, completion: nil)
    }
0
Chris

設定アラートコントローラーを作成するためのSwift 3拡張:

輸入財団

extension UIAlertController {
    func createSettingsAlertController(title: String, message: String) -> UIAlertController {
        let controller = UIAlertController(title: title, message: message, preferredStyle: .alert)

        let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment:"" ), style: .cancel, handler: nil)
        let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment:"" ), style: .default, handler: { action in
            UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
        })
        controller.addAction(cancelAction)
        controller.addAction(settingsAction)

        return controller
    }
}
0
Roman Barzyczak