iOS 操作扩展示例代码不工作

iOS Action Extension Sample Code Not Working

iOS 操作扩展示例代码似乎不起作用。

  1. 在 xCode 中,我创建了一个新的 Swift 项目并选择了 Single View Application。

  2. 然后我 select 文件 > 新建 > 目标,然后选择操作扩展。我输入一个名称,选择 Swift,然后 select 操作类型:无用户界面

  3. 然后我通过 运行 连接项目并选择 Safari 来测试扩展。我导航到 Google 网站。

  4. 我通过 Safari 中的“操作”图标启用扩展。然后我在 Safari 中按扩展图标 运行 它,但没有任何反应。

  5. 我希望网页背景颜色发生变化,因为 Action.js 代码(本应是 运行)设置了背景颜色:document.body.style.background= "blue"

好像 Action.js 代码从未被调用过。 所有代码均来自默认的 Action Extension 模板,未进行任何修改。

Info.plist

<key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>NSExtensionActivationRule</key>
            <dict>
                <key>NSExtensionActivationSupportsFileWithMaxCount</key>
                <integer>0</integer>
                <key>NSExtensionActivationSupportsImageWithMaxCount</key>
                <integer>0</integer>
                <key>NSExtensionActivationSupportsMovieWithMaxCount</key>
                <integer>0</integer>
                <key>NSExtensionActivationSupportsText</key>
                <false/>
                <key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
                <integer>1</integer>
            </dict>
            <key>NSExtensionJavaScriptPreprocessingFile</key>
            <string>Action</string>
        </dict>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.services</string>
        <key>NSExtensionPrincipalClass</key>
        <string>$(PRODUCT_MODULE_NAME).ActionRequestHandler</string>
    </dict>

我找到了一个解决方案:在 Objective C 而不是 Swift 中创建项目和应用程序扩展,一切正常。所以显然 Swift 实现中存在错误。

在 Swift 版本的 Xcode 项目模板中存在一个错误,显然是因为有人从 Objective-C 转换为 Swift.

长话短说:"found = true" 行放错了地方。这会导致方法 doneWithResults 在只应调用一次时被调用两次。在第一次调用时它设置 self.extensionContext = nil。在第二次调用时,它尝试使用 self.extensionContext 并由于展开 nil 可选值而抛出异常。但是异常消息被扩展系统吞没了,所以没有任何线索。

如果您在项目模板中更改此代码:

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

看起来像这个:

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

...然后它按预期工作。

我提交了关于此的错误 rdar://22482042,我鼓励您也提交一个。