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

时间:2015-10-11 15:18:54

标签: ios iphone swift ios-extensions

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

设置

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

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

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

    日志会说:

      

    致命错误:在解包可选值时意外发现nil

    例外情况是:EXC_BAD_INSTRUCTION

    原因是extensionContextnil

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

    <2>错误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
        }
    
    }
    

1 个答案:

答案 0 :(得分:0)

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