2014-09-04 9 views
20

Zastanawiam się, czy istnieje metoda, która pozwoli mi wykryć z aplikacji kontenera klawiatury, czy skojarzona klawiatura została aktywowana w aplikacji Ustawienia urządzenia.Jak wykryć, czy klawiatura niestandardowa jest aktywowana z aplikacji kontenerowej klawiatury?

Na przykład, jestem zainteresowany dodaniem prostej funkcji "kroków" w aplikacji kontenerowej, gdzie krok 1 byłby "aktywacją klawiatury", a krok 2 byłby zależny od ukończenia etapu 1. W związku z tym jestem zainteresowany ustaleniem, czy istnieje sposób na wykrycie, czy aktywowano rozszerzenie klawiatury?

Dzięki!

+0

+1, Mam te same pytania. – dandoen

+1

Dodano nagrodę. Mam nadzieję, że przyciągnie to więcej uwagi. – daspianist

Odpowiedz

45

Oto metoda, której użyłem w jednym z moich projektów. Myślę, że to jest to, o co prosiłeś, mam nadzieję, że ci to pomoże.

- (BOOL)isCustomKeyboardEnabled { 
    NSString *bundleID = @"com.company.app.customkeyboard"; // Replace this string with your custom keyboard's bundle ID 
    NSArray *keyboards = [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] objectForKey:@"AppleKeyboards"]; // Array of all active keyboards 
    for (NSString *keyboard in keyboards) { 
     if ([keyboard isEqualToString:bundleID]) 
      return YES; 
    } 

    return NO; 
} 
+1

Świetne, to się stało! Świetne odkrycie. – daspianist

+0

Działa idealnie! Dzięki. – kinshukkar

+4

To jest bardzo przydatne! ALE jest to bardziej przydatne w przypadku, gdy zainstalowana jest klawiatura. nie wiadomo, która klawiatura jest obecnie aktywna na ekranie? czy coś mi brakuje? –

2

Bieżący documentation stanowi By default, your extension and its containing app have no direct access to each other’s containers.

Jest także stwierdzając, że aplikacja pojemnik może współdzielić dane z klawiatury w następujący sposób:

// Create and share access to an NSUserDefaults object. 
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] 
initWithSuiteName:@"com.example.domain.MyShareExtension"]; 
// Use the shared user defaults object to update the user's account. 
[mySharedDefaults setObject:theAccountName forKey:@"lastAccountName"]; 

Czytaj więcej na ten temat: Communicating and persisting data between apps with App Groups

Przeszkoda nr 1: Według Aby dokumentacja działała, plik RequestsOpenAccess w pliku plist musi być ustawiony na YES, ponieważ uzyskałby następującą funkcję:

Możliwość korzystania z udostępnionego pojemnik zawierający aplikacji w klawiaturze, który umożliwia takie funkcje jak zapewnienie zwyczaj słownikowy zarządzanie UI w zawierającego aplikacji

Żądanie pełny dostęp do prostego takim wypadku zdecydowanie nie jest preferowany po mojej stronie.

Przeszkoda nr 2: Stosując tę ​​wiedzę ustawienie NSUserDefault, pozostawia mi myśleć o sposobie gdzie to może być ustawiony w miejscu. Ale nie ma publicznej metody wskazującej, że zainstalowane jest rozszerzenie. To jest teraz ślepy zaułek.

-

[Update 1]

Nie bardzo istotne, ale nadal warto określeniem: shouldAllowExtensionPointIdentifier aplikacja metoda delegata w połączeniu ze stałym UIApplicationKeyboardExtensionPointIdentifier radzi sobie z zabronienie niestandardowych klawiatur. Identyfikatory punktu rozszerzenia nie są niepowtarzalnymi identyfikatorami rozszerzenia, ale ich typu.

Więcej na ten temat: Can I disable custom keyboards (iOS8) for my app?

-

[Aktualizacja 2]

Inną kwestią z tego samego problemu, lecz w/o roztworu: How to detect an app extension is enabled in containing app on iOS 8?

-

To jest praca w toku pisząc moje dotychczasowe ustalenia, które mam nadzieję zaktualizować w najbliższych dniach, powinienem znaleźć rozwiązanie.

+0

Świetna pisanka do tej pory @ Dandoen. Zaktualizuj, jeśli znajdziesz rozwiązanie! – daspianist

+1

Dzięki za aktualizacje. Wygląda na to, że rozwiązanie dostarczone przez Kurta, który uzyskuje dostęp do [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] objectForKey: @ "AppleKeyboards"] 'zrobiło sztuczkę :) – daspianist

+0

Woah, zaczynałem się poddawać. To jest niesamowite - dzięki! – dandoen

6

Tylko w przypadku, tutaj jest Swift wersja błyskotliwej i wspaniałej odpowiedzi Kurta:

public func isKeyboardExtensionEnabled() -> Bool { 
    guard let appBundleIdentifier = NSBundle.mainBundle().bundleIdentifier else { 
     fatalError("isKeyboardExtensionEnabled(): Cannot retrieve bundle identifier.") 
    } 

    guard let keyboards = NSUserDefaults.standardUserDefaults().dictionaryRepresentation()["AppleKeyboards"] as? [String] else { 
     // There is no key `AppleKeyboards` in NSUserDefaults. That happens sometimes. 
     return false 
    } 

    let keyboardExtensionBundleIdentifierPrefix = appBundleIdentifier + "." 
    for keyboard in keyboards { 
     if keyboard.hasPrefix(keyboardExtensionBundleIdentifierPrefix) { 
      return true 
     } 
    } 

    return false 
} 
+0

fatalError służy celowo awarii aplikacji podczas testowania. Po przetestowaniu kodu można go zastąpić 'return false' i wydrukować błąd do konsoli. Również porównanie prefiksu na wypadek, gdyby aplikacja korzystała z wielu rozszerzeń, może zwrócić wartość true, nawet jeśli rozszerzenie klawiatury nie zostało dodane przez użytkownika. Więc można to porównać jako pełne imię. – user3404693

+0

Dziękujemy za cenne uwagi. Bardzo to doceniam. (1) Tak, kod miał błąd, gdy 'standardUserDefaults' nie ma klawisza' AppleKeyboards'. Naprawię to. (2) Zdecydowanie nie zgadzam się z celem "fatalError", nie ma on nic z testowaniem. (3) Tak, kod zakłada, że ​​pakiet ma tylko jedno rozszerzenie "klawiatury". –

+0

Dziękuję bardzo. jest naprawdę pomocny ... – Sandy

0

Można użyć tej funkcji (SWIFT 3 i 4), by sprawdzić rozszerzenie zwyczaj klawiatury mają otwarty dostęp lub nie :

func isOpenAccessGranted() -> Bool{ 
    if #available(iOS 10.0, *) { 
     let originalString = UIPasteboard.general.string 
     UIPasteboard.general.string = "Sour LeangChhean" 

     if UIPasteboard.general.hasStrings { 

      UIPasteboard.general.string = originalString ?? "" 
      return true 
     }else{ 
      UIPasteboard.general.string = "" 
      return false 
     } 
    } else { 
    // Fallback on earlier versions 
     if UIPasteboard.general.isKind(of: UIPasteboard.self) { 
      return true 
     }else{ 
      return false 
     } 
    } 
} 
Powiązane problemy