【问题标题】:How to check the "Allow Full Access" is enabled in iOS 8?如何检查 iOS 8 中是否启用了“允许完全访问”?
【发布时间】:2014-10-17 19:19:47
【问题描述】:

在 iOS 8 中,当开发自定义键盘并在 info.plist 中将 RequestsOpenAccess 属性设置为 YES 时,在 Settings-> Add New Keyboard 处有一个名为“Allow Full Access”的切换按钮。自定义键盘代码如何知道用户启用或禁用了此切换?

【问题讨论】:

  • 另外我不明白为什么在 iOS 8 GM 中,他们在启用键盘时没有显示允许完全访问开关,必须添加它然后单击它..
  • 您可以在这里找到更好的答案:stackoverflow.com/a/42307723/6392347

标签: keyboard ios8


【解决方案1】:

2017 年 8 月 23 日更新 iOS 10 兼容性:

func isOpenAccessGranted() -> Bool{
    UIPasteboard.general.string = "CHECK"
    return UIPasteboard.general.hasStrings
}

iOS 8:

-(BOOL)isOpenAccessGranted{
   return [UIPasteboard generalPasteboard];
}

请注意,模拟器总是会告诉您您拥有完全访问权限,因此要使其正常工作,您需要从设备上运行它。

【讨论】:

  • 您找到合适的解决方案了吗?
  • 但是如果我把它放在视图控制器中,它需要很长时间才能显示视图。无论如何让它更快?
  • 您可能想加粗您的最后一个语句以使其脱颖而出,我花了一些时间试图弄清楚为什么它在返回这里之前总是返回 true。 :p
  • 请注意,由于 iOS 8.3 中的行为发生了变化,这不再有效 - 在设备上运行时始终返回 true
  • @JulioBailon fisch2 的回答对我有用。 iOS 8.3 中的新功能即使未授予完全访问权限,您也可以从共享组容器中读取,因此上述代码始终返回 true,但除非您具有完全访问权限,否则您无法写入。不确定这是错误还是预期行为 - 在 8.4 测试版中也是如此。
【解决方案2】:

这是迄今为止最简单的答案,不需要您设置应用组。它在应用商店的生产环境中进行了测试。

+ (BOOL)isOpenAccessGranted
{
    return [UIPasteboard generalPasteboard];
}

【讨论】:

  • 很快就会是UIPasteboard.generalPasteboard().isKindOfClass(UIPasteboard)
  • @hoiberg42 - 好电话。当所有其他方法都失败时(在 8.3 中)
  • 1.上面的方法应该返回一个 BOOL。因此使用: return [[UIPasteboard generalPasteboard] isKindOfClass:[UIPasteboard class]]; 2. iOS 8.2 似乎破坏了通过应用程序组进行的完全访问检测。其他人可以确认吗?
  • 是否有人在加载没有完全访问权限的键盘时遇到延迟,并在加载视图时使用此方法?
  • 苹果拒绝了我的应用。我正在使用上述方法( UIPasteboard.generalPasteboard().isKindOfClass(UIPasteboard) )。它在设备上工作,但不在模拟器上(在模拟器上它总是返回 true)。似乎Apple正在模拟器中进行测试。有没有人使用这种方法获得了他们的应用程序的批准?
【解决方案3】:

对于 iOS 10(Beta 5),他们更改了 UIPasteboard API,但我发现以下方法可行:

let originalString = UIPasteboard.general.string
UIPasteboard.general.string = "TEST"
if UIPasteboard.general.hasStrings
{
    UIPasteboard.general.string = originalString
    hasFullAccess = true
}
else
{
     hasFullAccess = false
}

【讨论】:

  • 也可以在 Xcode 8(非测试版)中使用。干得好,谢谢!
  • 更新:它可以工作,但每次运行代码中的第 5 行时它都会打印 Returning local object of class NSStringPBItemCollectionServicer connection disconnected
  • @hoiberg42 我相信我只是通过缓存答案来解决这个问题,所以我只需要做一次。
  • @aircraft 你可以把它放在一个函数中并让它返回结果
  • @schlaegerz 您正在将字符串分配给粘贴板。即使您没有在设置中打开Allow Full Access,它也会返回true 值。可以解释一下吗?
【解决方案4】:

我今天在 iOS 10 中对此进行了测试,但访问粘贴板似乎还不够。在 iOS 10 中,您可以将粘贴板设置为没有完全访问权限的 var。这是我想出的解决方案...

func checkFullAccess() -> Bool
{
    var hasFullAccess = false
    if #available(iOSApplicationExtension 10.0, *) {
        let pasty = UIPasteboard.general
        if pasty.hasURLs || pasty.hasColors || pasty.hasStrings || pasty.hasImages {
            hasFullAccess = true
        } else {
            pasty.string = "TEST"
            if pasty.hasStrings {
                hasFullAccess = true
                pasty.string = ""
            }
        }
    } else {
        // Fallback on earlier versions
        var clippy : UIPasteboard?
        clippy = UIPasteboard.general
        if clippy != nil {
            hasFullAccess = true
        }
    }
    return hasFullAccess
}

测试粘贴板是否有一些内容会在完全访问关闭的情况下返回 false,即使粘贴板上有内容也是如此。当然它实际上可能是空的,所以在所有这些测试之后,您可以安全地尝试在粘贴板上设置一些东西,而不必担心替换已经存在的东西。如果你有访问权限并且粘贴板有内容,那么测试会返回 true,如果你没有访问权限,那么你就不能覆盖那里的内容。

HTH, 迈克

【讨论】:

    【解决方案5】:

    更新:不需要启用应用组,正如其他人所提到的,只需检查对粘贴板的访问权限:

    - (BOOL)isFullAccessGranted
    {
        return !![UIPasteboard generalPasteboard];
    }
    

    注意:以下内容不再有效,即使您启用了App Group...

    对于启用了App Group 的自定义键盘,以下是测试“允许完全访问”开关状态的快速、可靠的方法:

    func isOpenAccessGranted() -> Bool {
        let fm = NSFileManager.defaultManager()
        let containerPath = fm.containerURLForSecurityApplicationGroupIdentifier(
                            "group.com.example")?.path
        var error: NSError?
        fm.contentsOfDirectoryAtPath(containerPath!, error: &error)
        if (error != nil) {
            NSLog("Full Access: Off")
            return false
        }
        NSLog("Full Access: On");
        return true
    }
    

    【讨论】:

    • 这在键盘扩展中完美运行。但是,这总是在包含应用程序中返回 true。你知道如何在包含的应用中检查 Allow Full Access 的状态吗?
    • 尝试了几种方法,但还没有找到从包含应用程序中执行此操作的方法。
    • 我在 `fm.contentsOfDirectoryAtPath(containerPath!, error: &error)` 行遇到错误:fatal error: unexpectedly found nil while unwrapping an Optional value`
    • fatal error 很可能是由配置错误的应用组引起的。错误配置的应用程序组将导致containerURLForSecurityApplicationGroupIdentifier 返回nil。您是否确认您的 App Group 配置正确?见developer.apple.com/library/ios/documentation/IDEs/Conceptual/…
    • 这个答案需要更新,现在(iOS 10)键盘扩展可以在没有完全访问权限的情况下访问容器。现在我们需要尝试写一个文件来检查
    【解决方案6】:

    对于使用 Swift 2.3 的 iOS 10(如果您不想将文件转换为 Swift 3.0)

    func isOpenAccessGranted() -> Bool {
        if #available(iOSApplicationExtension 10.0, *) {
    
        let originalString = UIPasteboard.generalPasteboard().string
        UIPasteboard.generalPasteboard().string = "Test"
    
        if UIPasteboard.generalPasteboard().hasStrings {
                UIPasteboard.generalPasteboard().string = originalString
                return true
            } else {
                return false
            }
        } else {
            return UIPasteboard.generalPasteboard().isKindOfClass(UIPasteboard)
        }
    }
    

    【讨论】:

      【解决方案7】:

      iOS 11 不再需要任何 hack。

        override var hasFullAccess: Bool {
          if #available(iOS 11.0, *) {
            return super.hasFullAccess// super is UIInputViewController.
          }
          if #available(iOS 10.0, *) {
            let original: String? = UIPasteboard.general.string
            UIPasteboard.general.string = " "
            let val: Bool = UIPasteboard.general.hasStrings
            if let str = original {
              UIPasteboard.general.string = str
            }
            return val
          }
          return UIPasteboard.general.isKind(of: UIPasteboard.self)
        }
      

      【讨论】:

      • 但是如果我想从包含应用程序的键盘上检查这个怎么办?
      【解决方案8】:

      此代码适用于我,我也在应用组:https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html#//apple_ref/doc/uid/TP40012582-CH26-SW61

      也许它在没有应用组的情况下也可以工作。

      我使用了这段代码:

      if(isOpenAccessGranted()){ 
                  NSLog("FULL ACCESS ON")                
              }
              else{
                  NSLog("FULL ACCESS OFF")               
              }
      }
      
      func isOpenAccessGranted() -> Bool {
              return UIPasteboard.generalPasteboard().isKindOfClass(UIPasteboard)
      }
      

      【讨论】:

        【解决方案9】:

        @hoiberg42 提供的有用 Swift 解决方案:

        func isOpenAccessGranted() -> Bool {
            return UIPasteboard.generalPasteboard().isKindOfClass(UIPasteboard)
        }
        

        像魅力一样工作!

        【讨论】:

          【解决方案10】:

          对于那些使用 iOS 10 和 Objective-C 的人来说,这将按预期工作。

          - (BOOL)hasFullAccess
          {
              UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
              NSString *originalString = pasteboard.string;
              pasteboard.string = @"TEST";
              if (pasteboard.hasStrings) {
                  pasteboard.string = originalString;
                  return YES;
              } else {
                  return NO;
              }
          }
          

          【讨论】:

          • 为我工作(iOS 10+)。请注意,originalstring 可能为 nil,这会导致 pasteboard.string = originalString; 崩溃。
          【解决方案11】:

          只需使用

              dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),     
          ^{
              AudioServicesPlaySystemSound(1104);
              });
          

          问题是,启用完全访问时,会播放声音,如果没有,因为它的调用是在后台线程中,不会阻塞主线程

          【讨论】:

          • 好的,你如何判断代码后面是否播放了声音?
          【解决方案12】:

          快速解决方案

           if let test = UIPasteboard.generalPasteboard() as? UIPasteboard{
                  NSLog("Full Access: On")
                  return true
              }else{
                  NSLog("Full Access: Off")
                  return false
              }
          

          当然在上面的函数里面。

          【讨论】:

            【解决方案13】:

            今天,对于 iOS 9.2,您可以通过以下方式检查已打开的访问权限

            func isOpenAccessGranted() -> Bool {
                return UIPasteboard(name: "checkOpenedAccess", create: true) != nil
            }
            

            【讨论】:

            • @ValentinShergin,说了什么?
            【解决方案14】:

            具有应用组的应用可以使用:

             func isOpenAccessGranted() -> Bool {
                let fm = NSFileManager.defaultManager()
                let containerPath = fm.containerURLForSecurityApplicationGroupIdentifier(
                    AppGroup)?.path
                return fm.isWritableFileAtPath(containerPath!)
            }
            

            【讨论】:

              【解决方案15】:

              iOS11 及以上版本很简单。

              iOS10 解决方案:勾选所有可复制类型,如果其中一个可用,则您有完全访问权限,否则没有。

              -- 斯威夫特 4.2--

              override var hasFullAccess: Bool
              {
                  if #available(iOS 11.0, *){
                      return super.hasFullAccess// super is UIInputViewController.
                  }
              
                  if #available(iOSApplicationExtension 10.0, *){
                      if UIPasteboard.general.hasStrings{
                          return  true
                      }
                      else if UIPasteboard.general.hasURLs{
                          return true
                      }
                      else if UIPasteboard.general.hasColors{
                          return true
                      }
                      else if UIPasteboard.general.hasImages{
                          return true
                      }
                      else  // In case the pasteboard is blank
                      {
                          UIPasteboard.general.string = ""
              
                          if UIPasteboard.general.hasStrings{
                              return  true
                          }else{
                              return  false
                          }
                      }
                  } else{
                      // before iOS10
                      return UIPasteboard.general.isKind(of: UIPasteboard.self)
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 2017-01-17
                • 2017-08-30
                • 2015-10-08
                • 2017-01-25
                • 1970-01-01
                • 2014-11-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多