How to detect whether custom keyboard is activated from the keyboard's container app?

前端 未结 4 993
清酒与你
清酒与你 2020-12-01 03:13

I was wondering if there is a method that would allow me to detect from the keyboard container app whether the associated keyboard has been activated in the

相关标签:
4条回答
  • 2020-12-01 03:24

    Just in case here is Swift version of Kurt's brilliant and awesome answer:

       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
    }
    
    0 讨论(0)
  • The current documentation states By default, your extension and its containing app have no direct access to each other’s containers.

    It is also stating that the container app can share data with the keyboard in the following fashion:

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

    Read more on this: Communicating and persisting data between apps with App Groups

    Obstacle no 1: According to the documentation, for this to work, the RequestsOpenAccess in the plist needs to be set to YES as it would gain the following capability:

    Option to use a shared container with the keyboard’s containing app, which enables features such as providing a custom lexicon management UI in the containing app

    Requesting full access for a simple case like this is definitely not preferred on my side.

    Obstacle no 2: Using this knowledge of setting a NSUserDefault, leaves me to think of a method where this can be set in place. But there's no public method indicating an extension is installed. So this is a dead end for now.

    --

    [Update 1]

    Not super relevant but still worth stating: the shouldAllowExtensionPointIdentifier app delegate method in combination with the constant UIApplicationKeyboardExtensionPointIdentifier can deal with disallowing custom keyboards. The extension point identifiers are not unique identifiers of the extension but of their type.

    Read more on this: Can I disable custom keyboards (iOS8) for my app?

    --

    [Update 2]

    Another question with same issue, but w/o solution: How to detect an app extension is enabled in containing app on iOS 8?

    --

    This is a work-in-progress answer stating my findings so far which I hope to be updating coming days should I find a solution.

    0 讨论(0)
  • 2020-12-01 03:40

    Here is a method I have used in one of my projects. I think it is what you asked for, hope it helps you.

    - (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;
    }
    
    0 讨论(0)
  • 2020-12-01 03:41

    You can use this function (Swift 3 and 4) to check your custom keyboard extension have open access or not:

    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
           }
       }
    }
    
    0 讨论(0)
提交回复
热议问题