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

标签 ios iphone swift ios-extensions

当我尝试运行 Apple 的操作扩展默认代码时,它要么不执行任何操作,要么崩溃。如何修复这两个错误?

设置

  1. 在 Xcode 7 中创建新的操作扩展目标(语言 = Swift,操作类型 = 无用户界面)
  2. 在模拟器中运行扩展程序,选择 Safari 作为要运行的应用。
  3. 导航至https://google.com在 Safari 中
  4. 调用您刚刚创建的扩展程序(您需要点击“更多”按钮才能在事件表中启用它)。

错误 1:extensionContextnil

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

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

日志会显示:

fatal error: unexpectedly found nil while unwrapping an Optional value

异常(exception)情况是:EXC_BAD_INSTRUCTION

原因是extensionContextnil .

为什么会发生这种情况?我该如何解决?

错误 2:当它不崩溃时,它不会执行任何操作

当应用程序没有崩溃时,似乎什么也没有发生。根据代码,背景颜色似乎应该更改为红色或绿色,但在我尝试过的任何网站上都没有发生这种情况。

有没有您见过它有效的网站示例?如何改进代码以使其真正执行某些操作?

<小时/>

我尝试过的事情

尝试 1:传入上下文

由于代码在 block 内运行,因此我没有通过 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 中重写了所有扩展代码,但它也不起作用。

关于ios - 运行 Apple 的默认操作扩展代码会引发异常或不执行任何操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33066616/

相关文章:

swift - 重写绑定(bind)方法 (Swift) - 错误 : Value of type 'Any' has no member 'addObserver'

ios - Swift 'WKInterfaceLabel' 没有名为 'text' 的成员

swift - IAd 横幅将整个 skscene 向上移动

iphone - 如何将并排放置的两个图像一起缩放?

ios - 基于iOS定位的图层蒙版

ios - 使用 swift 从 iOS 应用程序调用特殊号码

ios - 比较两个日期字符串

iphone - 从 1 返回第 1 个,从 2 返回第 2 个,...,从 11 返回第 11 个,

ios - UITableViewCell 中的 TapGesture 导致其他单元格状态改变

javascript - iPhone 4 screen.width 报告 320 - 我以为它更多?