Programing

사용자가 사용을 거부 한 후 사용자에게 위치 서비스를 켜도록 프롬프트하려면 어떻게해야합니까?

crosscheck 2020. 10. 30. 07:44
반응형

사용자가 사용을 거부 한 후 사용자에게 위치 서비스를 켜도록 프롬프트하려면 어떻게해야합니까?


사용자의 현재 위치를 사용하는 명시적인 사용자 상호 작용이있는 응용 프로그램이 있습니다. 사용자가 위치 서비스에 대한 액세스를 거부하는 경우에도 후속 사용을 통해 사용자에게 설정으로 이동하고 내 앱에 대한 위치 서비스를 다시 활성화하라는 메시지를 표시하고 싶습니다.

내가 원하는 동작은 내장 된지도 앱의 동작입니다.

  1. 설정> 일반> 재설정> 위치 경고 재설정에서 위치 경고를 재설정합니다.
  2. 지도 앱을 시작합니다.
  3. 왼쪽 하단 모서리에있는 현재 위치 버튼을 누릅니다.
  4. ""지도 "는 현재 위치를 사용하고 싶습니다"와 함께지도 프롬프트 | "허용 안 함"| "허용하다".
  5. "허용 안 함"옵션을 선택하십시오.
  6. 왼쪽 하단의 현재 위치 버튼을 다시 누릅니다.
  7. 지도에서 ""지도 "가 사용자의 위치를 ​​결정할 수 있도록 위치 서비스를 켜십시오"라는 메시지가 표시됩니다. "설정"| "취소".

내 앱에서 동일한 기본 흐름으로 인해 최종 단계에서 kCLErrorDenied 오류와 함께 내 CLLocationManagerDelegate -locationManager : didFailWithError : 메서드가 호출되고 사용자에게 설정 앱을 열어 수정할 수있는 옵션이 제공되지 않습니다.

오류에 대한 응답으로 내 자신의 경고를 표시 할 수는 있지만 기본 제공지도 앱에서 사용하는대로 OS가 제공 할 수있는 경고와 같은 설정 앱을 시작할 수는 없습니다.

CLLocationManager 클래스에이 동작을 제공 할 수있는 누락 된 것이 있습니까?


iOS8에서는 사용자를 openURL을 통해 설정 앱에 연결할 수 있습니다. 예를 들어 사용자를 설정 앱으로 이동하는 단일 버튼으로 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]];
}

최신 정보:

iOS 8부터는 UIApplicationOpenSettingsURLStringURL을 나타내는 상수가 있습니다.이 상수 는 열릴 때 애플리케이션 설정에 대한 설정 앱을 엽니 다 (사용자가 위치 서비스를 다시 활성화 할 수 있음).


실물:

당신이 이것을 할 방법이 없습니다. 유일한 실제 옵션은 사용자에게 애플리케이션에 위치 서비스가 필요함을 알리고 수동으로 설정 앱으로 이동하여 켜도록 지시하는 경고를 표시하는 것입니다.


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];

locationServicesEnabled 메서드 에 대한 Apple의 문서따르면 .

사용자는 일반에서 위치 서비스 스위치를 토글하여 설정 애플리케이션에서 위치 서비스를 활성화 또는 비활성화 할 수 있습니다.

위치 업데이트를 시작하기 전에이 메서드의 반환 값을 확인하여 사용자가 현재 장치에 대해 위치 서비스를 활성화했는지 확인해야합니다. 이 메서드가 NO를 반환하고 어쨌든 위치 업데이트를 시작하면 Core Location 프레임 워크는 사용자에게 위치 서비스를 다시 활성화해야하는지 여부를 확인하라는 메시지를 표시합니다.

그럼 그냥 위치 서비스 업데이트를 시작하여 경고를 표시 할 수 없습니까?


다음은 Markus와 bjc에서 제공하는 코드의 신속한 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)

Swift 4에는 구문이 업데이트되었습니다.

스위프트 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)

   }
}

Apple이 새로운 SDK에 대해 생각할 때 귀하의 질문에 대한 답변을 얻을 수있을 것 같습니다. 현재로서는 내가 아는 한 불가능합니다.


사용할 수있는 URL 처리기가 없습니다. 호출 할 사용 가능한 메서드가 없습니다.

하지만 ...지도처럼이 작업은 수행 할 수 있지만 아마도 비공개 API를 사용합니다. 이런 종류의 코딩이 두렵지 않다면 제 생각에는 그곳을 검색해야합니다.


다음은 Markus의 답변에있는 Swift 버전의 코드입니다. 이 코드는 사용자에게 설정을 열 수있는 옵션을 제공하는 경고를 생성합니다.

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)

스위프트 ,

앱에 대한 위치 서비스를 비활성화하면 위치 관리자 위임 메서드가 오류를 표시하기 시작합니다. 따라서 수신 오류시 위치 서비스가 활성화 / 비활성화되었는지 확인할 수 있습니다. 결과에 따라 사용자에게 설정으로 이동하여 위치 서비스를 사용하도록 요청할 수 있습니다.

In your location manager delegate method for error, add location permission check

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

Code for location permission checking

//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: ""))
        }
    }

Code to open settings app,

//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)
}

Swift 3 extension for creating settings alert controller:

import Foundation

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
    }
}

latest swift version based on answers above.

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)
    }

참고URL : https://stackoverflow.com/questions/4891950/how-can-i-prompt-the-user-to-turn-on-location-services-after-user-has-denied-the

반응형