Правило активации общего доступа iOS срабатывает, когда оно не должно быть для типа public.url

У меня есть приложение для iOS с расширением общего доступа. Расширение общего доступа использует "синтаксис предиката" 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 (или любым другим типом, который соответствует public.url в соответствии с этот список). Вот вывод журнала из публикации истории NYT Now.

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

Я не могу понять, почему мое расширение отображается для этого контента, поскольку ни public.image, ни public.plain-text не соответствуют public.url. Простой текстовый элемент действительно содержит URL-адрес, но есть также куча другого текста, отличного от URL-адреса.

Я хотел бы выяснить, почему предикат моего расширения соответствует этому содержимому и как это остановить (или даже лучше, если где-то действительно есть URL-адрес, который я не могу найти).

Если я использую словарь для NSExtensionActivationRule и устанавливаю NSExtensionActivationSupportsWebURLWithMaxCount=1, расширение (правильно) не отображается для историй NYT Now, поэтому похоже, что проблема связана с правилом предиката.


person Evan    schedule 11.08.2015    source источник
comment
Я получаю то же самое, даже с вариациями строки предиката. К сожалению, я бы назвал это ошибкой в ​​системе предикатов.   -  person Tom Harrington    schedule 13.08.2015
comment
Стоит отметить, что совместное использование приложения «Подкасты» также демонстрирует это.   -  person nomad00    schedule 25.11.2015
comment
Пахнет жуком. Вы поставили радар?   -  person Matt S.    schedule 26.11.2015


Ответы (1)


Хотя это может не помочь в вашей конкретной ситуации, я хотел бы поделиться своим обходным путем.

Контекст: Ниже приведена схематическая версия NSItemProviderCompletionHandler, которую я использую, когда NSItemProvider соответствует kUTTypePlainText.

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, как в вашем случае).

person nomad00    schedule 27.11.2015