iOS 共享扩展激活规则不应该用于 public.url 类型时触发

Posted

技术标签:

【中文标题】iOS 共享扩展激活规则不应该用于 public.url 类型时触发【英文标题】:iOS share extension activation rule triggered when it shouldn't be for public.url type 【发布时间】:2015-08-11 02:14:51 【问题描述】:

我有一个带有共享扩展的 ios 应用。共享扩展使用"predicate syntax"NSExtensionActivationRule plist 设置。这是使用的谓词字符串。

SUBQUERY (
    extensionItems,
    $extensionItem,
    SUBQUERY (
        $extensionItem.attachments,
        $attachment,
        ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url"
    ).@count == 1
).@count == 1

目标是匹配具有一个 URL 的内容,而不管它具有哪些其他属性。不幸的是,在某些情况下,这似乎与没有任何 URL 的内容匹配(由 public.url 类型或任何符合它的类型定义)。

出于一个简单示例的目的,我用这个简化的类替换了视图控制器。

import UIKit
import Social
import MobileCoreServices

class ShareViewController: SLComposeServiceViewController 
  override func viewDidLoad() 
    super.viewDidLoad()
    self.logAttachments()
    // do nothing
    self.extensionContext?.completeRequestReturningItems([]) (_:Bool) -> Void in
  

  func logAttachments() 
    if let items:[NSExtensionItem] = self.extensionContext?.inputItems as? [NSExtensionItem] 
      for item in items 
        self.logItemAttachments(item)
      
     else 
      println("No items")
    
  

  func logItemAttachments(item:NSExtensionItem) 
    if let attachments = item.attachments as? [NSItemProvider] 
      for a in attachments 
        println(a.registeredTypeIdentifiers)
      
     else 
      println("No attachments")
    
  

这个类所做的只是打印每个共享项目附件的类型。大多数情况下,我会得到我所期望的一个带有public.url 类型的附件。这是 iOS Chrome 应用中网页的示例。

[public.plain-text]
[public.url]

对于没有 URL 的内容,通常(如预期的那样)共享选项不可用。如果我将NSExtensionActivationRule 更改为TRUEPREDICATE,我可以在从 Simplenote 共享笔记文件时看到这样的示例。

[public.plain-text]

不幸的是,我在 NYT Now 应用程序中遇到了一个案例,其中我的原始谓词 确实 匹配,但内容没有任何 public.url 类型(或任何符合 @987654333 的类型)的附件@根据this list)。这是分享 NYT Now 故事的日志输出。

[public.image]
[public.plain-text]

我无法弄清楚为什么我的扩展会出现在此内容中,因为 public.imagepublic.plain-text 都不符合 public.url。纯文本项确实有一个 URL,但也有一堆其他的非 URL 文本。

我很想弄清楚为什么我的扩展程序的谓词与此内容匹配以及如何停止它(或者更好的是,如果在某个地方实际上有一个我找不到的 URL)。

如果我为 NSExtensionActivationRule 使用字典并设置 NSExtensionActivationSupportsWebURLWithMaxCount=1 扩展名(正确)不会出现在 NYT Now 故事中,因此问题似乎出在谓词规则上。

【问题讨论】:

我得到了同样的结果,即使谓词字符串有变化。不幸的是,我将其称为谓词系统中的错误。 说从播客应用分享也证明了这一点。 闻起来像虫子。你装雷达了吗? 【参考方案1】:

虽然这可能对您的具体情况没有帮助,但我想分享一下我的解决方法。

上下文:以下是我在NSItemProvider 符合kUTTypePlainText 时使用的NSItemProviderCompletionHandler 的骨架版本。

lazy var textHandler: NSItemProviderCompletionHandler =  [unowned self]
(result: NSSecureCoding?, error: NSError!) in
    if let text = result as? String 
        print("Text: \(text)")
        // If NSDataDetector thinks we have a link - use it!
        let types: NSTextCheckingType = [.Link]
        let detector = try? NSDataDetector(types: types.rawValue)
        if let match = detector?.firstMatchInString(text, options: [], range: NSMakeRange(0, (text as NSString).length))
            where match.resultType == .Link  
                print("URL: \(match.URL!.absoluteString)")
        
    

值得注意的是,即使该应用并未宣传对 public.plain-text 的支持(就像您的情况一样,只是 public.url)。

【讨论】:

以上是关于iOS 共享扩展激活规则不应该用于 public.url 类型时触发的主要内容,如果未能解决你的问题,请参考以下文章

用于在用户之间共享数据的 Firestore 安全规则

我应该使用操作扩展的共享扩展吗?

具有多个目标的iOS扩展

使用 iOS 中的共享扩展从 Mail App 共享附件

从 iOS 容器应用与应用扩展共享 Firebase 身份验证会话

当点击按钮(在 UICollectionViewController 中)时如何激活共享扩展(UIActivityViewController)?