2011-02-03 8 views
65

Mam aplikację z wyraźną interakcją użytkownika, która wykorzystuje bieżącą lokalizację użytkownika. Jeśli użytkownik odmówi dostępu do usług lokalizacyjnych, nadal chciałbym, aby użytkownicy korzystali z kolejnych ustawień, aby przejść do ustawień i ponownie włączyć usługi lokalizacyjne dla mojej aplikacji.Jak mogę zachęcić użytkownika do włączania usług lokalizacyjnych po tym, gdy użytkownik odmówił ich używania?

Zachowanie chcę jest, że z wbudowanej aplikacji Maps:

  1. ostrzeżenia lokalizacja resetu w Ustawienia> Ogólne> Wyzeruj> Położenie ostrzeżenia.
  2. Uruchom aplikację Mapy.
  3. Dotknij przycisku Aktualna lokalizacja w lewym dolnym rogu.
  4. Prośby o mapy z opcją "" Mapy "chcą używać bieżącej lokalizacji" | "Nie pozwól" | "Dopuszczać".
  5. Wybierz opcję "Nie zezwalaj".
  6. Ponownie dotknij przycisku Aktualna lokalizacja w lewym dolnym rogu.
  7. Wyświetlenie map z "Włącz usługi lokalizacyjne do zezwolenia" Mapy "w celu określenia Twojej lokalizacji" | "Ustawienia" | "Anuluj".

W moim app, te same podstawowe wyniki przepływu w moim CLLocationManagerDelegate -locationManager: didFailWithError: metoda miano z błędem kCLErrorDenied w końcowym etapie, a użytkownik nie ma możliwość, aby otworzyć ustawienia aplikacji w celu skorygowania to.

Mogę wyświetlić swój własny alert w odpowiedzi na błąd, ale nie będzie on miał możliwości uruchomienia aplikacji Ustawienia, takiej jak alert, który system operacyjny może zapewnić zgodnie z wbudowaną aplikacją Mapy.

Czy jest coś, czego brakuje mi w klasie CLLocationManager, która mogłaby dać mi takie zachowanie?

+0

Teraz, po prostu wyświetli ostrzeżenie do użytkownika z prośbą, aby przejść do menu Ustawienia, aby ponownie ją włączyć. Bardzo chciałbym usłyszeć lepsze rozwiązanie. – donkim

+0

Chciałbym również odpowiedzi na to, z pewnością jest lepszy sposób – conorgriffin

+0

Znalazłem CoreLocation nie było zadowalające z tego powodu. Skończyłem z wykorzystaniem biblioteki Skyhook, która jest łatwa do zintegrowania i dobrze udokumentowana. Współrzędne wydają się być również bardziej precyzyjne. Jedyną wadą jest konieczność powiązania z aplikacją bloku o rozmiarze 1,5 MB. –

Odpowiedz

39

Dzięki iOS8 możesz w końcu połączyć użytkownika z aplikacją Ustawienia przez openURL. Na przykład, można utworzyć UIAlertView za pomocą jednego przycisku, który przenosi użytkownika do aplikacji ustawienia:

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

W swoim delegatem UIAlertView:

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

Jest to znacznie lepsze rozwiązanie niż w systemie iOS 7 i wcześniejszych wersjach, ale nadal nie jest doskonałe, ponieważ adres URL przenosi użytkownika do ekranu o jeden poziom wyżej, na którym użytkownik może zmienić ustawienie. – GBegen

+0

Przynajmniej od wersji iOS 10, przenosi Cię do ustawień aplikacji, gdzie znajduje się również lokalizacja. –

2

Chyba będziesz mieć odpowiedź na swoje pytanie, gdy Apple pomyśli o nowym SDK. W obecnym czasie i, o ile mi wiadomo, to nie jest możliwe:

No URL-Handler dostępny
Nie sposób użyteczny zadzwonić

Ale ... jak mapy robi, można to zrobić, ale prawdopodobnie za pomocą prywatnego API. Jeśli nie boisz się tego rodzaju kodowania, powinieneś poszukać w mojej opinii.

31

Aktualizacja:

Jako iOS 8, obecnie stała UIApplicationOpenSettingsURLString który reprezentuje adres URL, który po otwarciu otwiera aplikację Ustawienia w ustawieniach aplikacji (gdzie użytkownik może następnie ponownie włączyć lokalizację usługi).


oryginalny:

Nie ma sposobu, aby to zrobić. Jedyną realną opcją jest wyświetlenie alertu informującego użytkownika, że ​​twoja aplikacja wymaga usług lokalizacyjnych, i nakazanie im ręcznego przejścia do aplikacji Ustawienia i włączenia jej.

+0

Czytałem w Apple Docs i opublikowałem odpowiedź poniżej na podstawie dokumentów, ale nie przetestowałem tego samodzielnie. Czy jest to zmiana w SDK lub czy są one takie same. –

+0

Obawiam się, że ta odpowiedź nie jest już poprawna. Możesz zaktualizować lub usunąć swoją odpowiedź. –

+0

Oto doskonały przykład w Swift http://nshipster.com/core-location-in-ios-8/, który uważam za bardzo pomocny. Pokazuje, jak zrobić alert przekierowujący do 'Ustawienia' przy użyciu' UIApplicationOpenSettingsURLString'. – dmk12

6

Zgodnie z metodą na metodzie locationServicesEnabled.

The user can enable or disable location services from the Settings application by toggling the Location Services switch in General.

You should check the return value of this method before starting location updates to determine whether the user has location services enabled for the current device. If this method returns NO and you start location updates anyway, the Core Location framework prompts the user to confirm whether location services should be reenabled.

Nie możesz więc rozpocząć aktualizacji usług lokalizacyjnych w żaden sposób, aby spowodować wyświetlenie monitu o alert?

+14

To tak naprawdę nie działa w ten sposób i prawdopodobnie ma do czynienia z subtelnym rozróżnieniem pomiędzy locationServicesEnabled i * authorized *. Jeśli są wyłączone, monituje o włączenie, ale jeśli są włączone, ale zabronione, to nic nie zrobią. Jest to jednak bardzo zagmatwana dokumentacja. – SG1

+0

locationServicesEnabled to nieaktualna metoda. –

16

AlertViews są nieaktualnych w iOS 8. Jest teraz lepszy sposób na obsługę alertów za pomocą nowego kontrolera 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]; 
0

Swift 3 rozszerzenie do tworzenia ustawień alert kontrolera:

Fundacja import

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

Oto Swift wersja kodu w odpowiedzi Markus. Ten kod tworzy alert, który daje użytkownikowi opcję otwierania ustawień.

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

Oto szybka implementacja 3 kodu dostarczonego przez Markus i bjc.

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) 
+0

niesamowite. dzięki. –

1

W Swift 4 w jego składni znajduje się aktualizacja.

Swift 4

extension UIAlertController { 

    func createSettingsAlertController(title: String, message: String) -> UIAlertController { 

     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) 

    } 
}