Подтвердить что ты не робот

Как определить, активирована ли пользовательская клавиатура из приложения-контейнера клавиатуры?

Мне было интересно, есть ли метод, который позволит мне обнаружить из приложения-контейнера клавиатуры, была ли активирована соответствующая клавиатура в приложении настроек устройства.

Например, я заинтересован в добавлении простой функции "шагов" внутри контейнерного приложения, где шаг 1 будет "активировать клавиатуру", а шаг 2 будет зависеть от завершения этапа 1. Как таковой, мне интересно выяснить, есть ли способ определить, активировано ли расширение клавиатуры?

Спасибо!

4b9b3361

Ответ 1

Вот метод, который я использовал в одном из моих проектов. Я думаю, это то, о чем вы просили, надеюсь, что это вам поможет.

- (BOOL)isCustomKeyboardEnabled {
    NSString *bundleID = @"com.company.app.customkeyboard"; // Replace this string with your custom keyboard 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;
}

Ответ 2

На всякий случай вот Swift-версия Курта, блестящий и потрясающий ответ:

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

    guard let keyboards = UserDefaults.standard.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
}

Ответ 3

В текущем documentation указано By default, your extension and its containing app have no direct access to each other’s containers.

Также указано, что контейнерное приложение может совместно использовать данные с клавиатурой следующим образом:

// 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 account.
[mySharedDefaults setObject:theAccountName forKey:@"lastAccountName"];

Подробнее об этом: Общение и сохранение данных между приложениями с группами приложений

Препятствие № 1. Согласно документации, для этого для работы RequestsOpenAccess в plist должно быть установлено значение YES, поскольку оно может получить следующие возможности:

Возможность использовать общий контейнер с клавиатурами, содержащими приложение, который позволяет такие функции, как предоставление пользовательского управления лексикой Пользовательский интерфейс в содержащем приложении

Запрос на полный доступ для простого случая, подобного этому, определенно не является предпочтительным на моей стороне.

Препятствие нет 2. Используя это знание установки NSUserDefault, мне следует подумать о методе, где это можно установить на место. Но нет общедоступного метода, указывающего расширение. Так что теперь это тупик.

-

[Обновить 1]

Не очень важно, но все же стоит сказать: метод делегата shouldAllowExtensionPointIdentifier в сочетании с константой UIApplicationKeyboardExtensionPointIdentifier может иметь дело с отказом от пользовательских клавиатур. Идентификаторы точки расширения не являются уникальными идентификаторами расширения, а являются их типом.

Подробнее об этом: Можно ли отключить пользовательские клавиатуры (iOS8) для моего приложения?

-

[Обновить 2]

Другой вопрос с той же проблемой, но без решения: Как определить расширение приложения включено в приложении app на iOS 8?

-

Это незавершенный ответ, в котором говорится о моих выводах, которые я надеюсь обновлять в ближайшие дни, если я найду решение.

Ответ 4

Вы можете использовать эту функцию (Swift 3 и 4), чтобы проверить, что пользовательский расширение клавиатуры имеет открытый доступ или нет:

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