Запуск кода Apple Action Extension по умолчанию вызывает исключение или ничего не делает

Когда я пытаюсь запустить код Apple по умолчанию для расширения действия, он либо ничего не делает, либо падает. Как я могу исправить эти две ошибки?

Настраивать

  1. Создайте новую цель расширения действия в Xcode 7 (язык = Swift, тип действия = без пользовательского интерфейса)
  2. Запустите расширение в симуляторе, выбрав Safari в качестве запускаемого приложения.
  3. Перейдите на страницу https://google.com в Safari.
  4. Вызовите расширение, которое вы только что создали (вам нужно будет нажать кнопку «Дополнительно», чтобы включить его на листе действий).

Ошибка 1: extensionContext равно nil

Нажмите кнопку действия, затем кнопку расширения от 1 до 5 раз в Safari. В конце концов расширение рухнет на этой строке:

self.extensionContext!.completeRequestReturningItems([resultsItem], completionHandler: nil)

В журнале будет сказано:

фатальная ошибка: неожиданно найдено nil при развертывании необязательного значения

Исключение: EXC_BAD_INSTRUCTION

Причина в том, что extensionContext это nil.

Почему это происходит, и как я могу это исправить?

Ошибка 2: когда он не падает, он ничего не делает

Когда приложение не падает, кажется, что ничего не происходит. Исходя из кода, кажется, что цвет фона должен был измениться на красный или зеленый, но этого не происходит ни на одном из веб-сайтов, на которых я пробовал.

Есть ли примеры веб-сайтов, на которых вы видели, как это работает? Как я могу улучшить код, чтобы он действительно что-то делал?


Вещи, которые я пробовал

Попытка 1: пройти в контексте

Поскольку код запускается внутри блока, вместо ссылки на контекст через self.extensionContext я попытался передать его функциям, которым он нужен (itemLoadCompletedWithPreprocessingResults(_:context:) и doneWithResults(_:context:)).

Это кажется более стабильным (пока только один раз произошел сбой), но по-прежнему не изменяет цвет фона.


Ссылка

Для справки, вот код по умолчанию для ActionRequestHandler.swift:

import UIKit
import MobileCoreServices

class ActionRequestHandler: NSObject, NSExtensionRequestHandling {

    var extensionContext: NSExtensionContext?

    func beginRequestWithExtensionContext(context: NSExtensionContext) {
        // Do not call super in an Action extension with no user interface
        self.extensionContext = context

        var found = false

        // Find the item containing the results from the JavaScript preprocessing.
        outer:
            for item: AnyObject in context.inputItems {
                let extItem = item as! NSExtensionItem
                if let attachments = extItem.attachments {
                    for itemProvider: AnyObject in attachments {
                        if itemProvider.hasItemConformingToTypeIdentifier(String(kUTTypePropertyList)) {
                            itemProvider.loadItemForTypeIdentifier(String(kUTTypePropertyList), options: nil, completionHandler: { (item, error) in
                                let dictionary = item as! [String: AnyObject]
                                NSOperationQueue.mainQueue().addOperationWithBlock {
                                    self.itemLoadCompletedWithPreprocessingResults(dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as! [NSObject: AnyObject])
                                }
                                found = true
                            })
                            if found {
                                break outer
                            }
                        }
                    }
                }
        }

        if !found {
            self.doneWithResults(nil)
        }
    }

    func itemLoadCompletedWithPreprocessingResults(javaScriptPreprocessingResults: [NSObject: AnyObject]) {
        // Here, do something, potentially asynchronously, with the preprocessing
        // results.

        // In this very simple example, the JavaScript will have passed us the
        // current background color style, if there is one. We will construct a
        // dictionary to send back with a desired new background color style.
        let bgColor: AnyObject? = javaScriptPreprocessingResults["currentBackgroundColor"]
        if bgColor == nil ||  bgColor! as! String == "" {
            // No specific background color? Request setting the background to red.
            self.doneWithResults(["newBackgroundColor": "red"])
        } else {
            // Specific background color is set? Request replacing it with green.
            self.doneWithResults(["newBackgroundColor": "green"])
        }
    }

    func doneWithResults(resultsForJavaScriptFinalizeArg: [NSObject: AnyObject]?) {
        if let resultsForJavaScriptFinalize = resultsForJavaScriptFinalizeArg {
            // Construct an NSExtensionItem of the appropriate type to return our
            // results dictionary in.

            // These will be used as the arguments to the JavaScript finalize()
            // method.

            let resultsDictionary = [NSExtensionJavaScriptFinalizeArgumentKey: resultsForJavaScriptFinalize]

            let resultsProvider = NSItemProvider(item: resultsDictionary, typeIdentifier: String(kUTTypePropertyList))

            let resultsItem = NSExtensionItem()
            resultsItem.attachments = [resultsProvider]

            // Signal that we're complete, returning our results.
            self.extensionContext!.completeRequestReturningItems([resultsItem], completionHandler: nil)
        } else {
            // We still need to signal that we're done even if we have nothing to
            // pass back.
            self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
        }

        // Don't hold on to this after we finished with it.
        self.extensionContext = nil
    }

}

person Senseful    schedule 11.10.2015    source источник


Ответы (1)


Та же проблема. На самом деле я могу запустить свой проект на симуляторе, но эта проблема возникает только тогда, когда я пытаюсь запустить проект на устройстве. И я обнаружил, что это не потому, что я использую swift 2, потому что я также переписываю весь код расширения в objC, и он тоже не работает.

person felipelmota    schedule 13.10.2015