Расширение iOS YouTube Share не предоставляет URL

У меня есть следующий код в моем расширении общего доступа, чтобы получить общий URL-адрес.

    if let item = extensionContext?.inputItems.first as? NSExtensionItem {
        for (index, _) in (item.attachments?.enumerated())! {
            if let itemProvider = item.attachments?[index] as? NSItemProvider {
                if itemProvider.hasItemConformingToTypeIdentifier("public.url") {
                    itemProvider.loadItem(forTypeIdentifier: "public.url", options: nil, completionHandler: { (url, error) -> Void in
                        if let shareURL = url as? NSURL {
                            // send url to server to share the link
                            print (shareURL.absoluteString!)

По какой-то причине приложение YouTube для iOS возвращает false для itemProvider.hasItemConformingToTypeIdentifier("public.url").

А ниже мой Info.plist для расширения общего доступа.

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <string>
            SUBQUERY (
                extensionItems,
                $extensionItem,
                SUBQUERY (
                    $extensionItem.attachments,
                    $attachment,
                    ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url"
                ).@count == 1
            ).@count == 1
        </string>
    </dict>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
</dict>

Как я могу получить URL-адрес видео YouTube, опубликованного в моем расширении общего доступа?


person Charlie Fish    schedule 13.05.2017    source источник
comment
Если ItemProvider не может предложить вам URL-адрес, какие типы он может предложить? Если вы спросите у поставщика предметов, registeredTypeIdentifiers какие UTI будут даны?   -  person Scott Thompson    schedule 13.05.2017
comment
@ScottThompson Печать itemProvider.registeredTypeIdentifiers[0] as! String возвращает "public.plain-text"   -  person Charlie Fish    schedule 13.05.2017
comment
В порядке. Это первое. Есть ли другие? Если вы на самом деле запросите простой текст, что он содержит?   -  person Scott Thompson    schedule 13.05.2017
comment
@ScottThompson item.attachments?.count возвращает 1. Работаем над тем, чтобы увидеть, что он содержит сейчас.   -  person Charlie Fish    schedule 13.05.2017
comment
@ScottThompson О, он возвращает https://www.youtube.com/watch?v=VIDEOIDHERE&feature=share. Есть ли лучший способ настроить мой код, чтобы получить этот простой текст, ЕСЛИ он находится в форме URL? Я не хочу получать случайный текст. Я хочу получить его только в том случае, если это URL-адрес.   -  person Charlie Fish    schedule 13.05.2017
comment
Получите текст и посмотрите, сможете ли вы преобразовать его в URL, используя init?(string: String), если текст не является URL-адресом, эта функция вернет ноль   -  person Scott Thompson    schedule 13.05.2017
comment
@ScottThompson так похож на if let myURL = URL.init?(string: text) {?   -  person Charlie Fish    schedule 13.05.2017
comment
@ScottThompson Или это выдает ошибку, так что if URL.init(string: text as! String) != nil { будет работать?   -  person Charlie Fish    schedule 13.05.2017


Ответы (2)


Моя первая рекомендация — выяснить, какие типы на самом деле предоставляются itemProvider:

if let item = extensionContext?.inputItems.first as? NSExtensionItem {
    for (index, _) in (item.attachments?.enumerated())! {
        if let itemProvider = item.attachments?[index] as? NSItemProvider {

            // print out the registered type identifiers so we can see what's there
            itemProvider.registeredTypeIdentifiers.forEach { print String(describing: $0) }

В этом случае, согласно вашим комментариям, вы можете получить обычный текст или kUTTypePlainText, и этот текст содержит URL-адрес, поэтому:

if let item = extensionContext?.inputItems.first as? NSExtensionItem {
for (index, _) in (item.attachments?.enumerated())! {
    if let itemProvider = item.attachments?[index] as? NSItemProvider {
        if itemProvider.hasItemConformingToTypeIdentifier(kUTTypePlainText) {
            itemProvider.loadItem(forTypeIdentifier: kUTTypePlainText, options: nil, completionHandler: { (string, error) -> Void in
                if let string = (string as? String), let shareURL = URL(string) {
                    // send url to server to share the link
                    print (shareURL.absoluteString!)

Моя вторая рекомендация — всегда использовать константы kUTType вместо необработанных строк :-)

person Scott Thompson    schedule 13.05.2017
comment
Пару раз переделывал код. Вам может понадобиться URL(string: string). Я пытался максимально приблизиться к Playground, не имея полного набора кода для компиляции, поэтому вам, возможно, придется немного подправить. - person Scott Thompson; 13.05.2017
comment
Хорошо, а kUTTypePlainText as String вместо kUTTypePlainText? - person Charlie Fish; 13.05.2017
comment
UTTypes - это CFStrings... но видимо вам придется их типизировать :-( - person Scott Thompson; 13.05.2017
comment
Большое тебе спасибо. Немного отредактировав и поиграв, я заработал! - person Charlie Fish; 13.05.2017

Youtube предоставит kUTTypePlainText. Чтобы получить URL-адрес, вы должны преобразовать NSSecureCoding в строку, а затем создать URL-адрес с этой строкой.

func getUrl() {
  if let content = extensionContext!.inputItems[0] as? NSExtensionItem {

    let contentTypePlain = kUTTypePlainText as String

    if let contents = content.attachments {
      for attachment in contents {
        if attachment.hasItemConformingToTypeIdentifier(contentTypePlain) {
          attachment.loadItem(forTypeIdentifier: contentTypePlain, options: nil, completionHandler: { data, error in
            let urlString = data as! String
            let url = URL(string: urlString)!

            // USE URL 

          })
        }
      }
    }
  }
} 
person Albastroiu Radu    schedule 10.03.2020