运行 Apple 的默认操作扩展代码会引发异常或不执行任何操作



当我试图运行苹果的默认代码为一个动作扩展,它要么什么也不做或崩溃。我该如何修复这两个bug ?

置>
    在Xcode 7中创建一个新的动作扩展目标(语言= Swift,动作类型=无用户界面)
  1. 在模拟器中运行扩展,选择Safari作为应用程序运行。
  2. 在Safari中导航到https://google.com
  3. 调用您刚刚创建的扩展(您需要在活动表中点击More按钮以启用它)。
缺陷1:extensionContextnil

点击操作按钮,然后在Safari中点击扩展按钮1-5次。最后扩展将在这一行崩溃:

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

日志显示:

致命错误:在展开可选值

时意外发现nil

例外:EXC_BAD_INSTRUCTION

原因是extensionContextnil

为什么会发生这种情况,我该如何修复它?

Bug 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
    }
}

同样的问题。实际上,我可以在模拟器上运行我的项目,但只有当我尝试在设备上运行项目时才会出现这个问题。我发现这并不是因为我使用swift 2,因为我在objC中重写了所有扩展代码,而且它也不起作用。

相关内容

最新更新