【问题标题】:iOS App Extension - Action - Custom DataiOS 应用扩展 - 操作 - 自定义数据
【发布时间】:2014-08-14 04:37:40
【问题描述】:

我正在以Action 的形式开发应用扩展。

主机应用程序将以正常方式使用我的扩展程序:通过提供 UIActivityViewController 以包含 activityItems 数组,然后将其传递给我的扩展程序。

iOS 将根据项目是否匹配我在扩展程序的info.plist 中定义的NSExtensionActivationRule 设置来决定是否显示我的操作。

此功能似乎适用于内容和指向内容的指针(图像、视频、文本、文件、URL)。

相反,我需要传递结构化数据并接收回结构化数据。

我可以使用激活规则NSExtensionActivationSupportsText 将我的itemType 定义为文本,然后只传递序列化的JSON。但是,我的操作将提供给简单的纯文本。不好。

显然有一些神秘的查询语言可用于在我的NSExtensionActivationRule 设置中定义NSPredicate,它允许进行某种自定义。

但我想不通。所有示例均基于内容,而不是数据。如何将我的自定义 actionItem 定义为结构化数据并让 iOS 知道我的操作何时真正合适?

我能完成我想要的吗?如何?任何提示都表示赞赏。

更新:我怀疑这个问题的关键是custom Uniform Type Identifiers。但是,我仍然卡住了,因为 UTI 定义的所有示例仍然是内容(文件和媒体),而不是结构化数据。

【问题讨论】:

  • 为什么不构建自己的文件类型并使用文档提供程序扩展?

标签: swift ios8 ios-app-extension


【解决方案1】:

Uniform Type Identifiers 确实是这样做的正确方法。

我还没有完成这个开发,但我设法让它最低限度地工作。基本上你定义了一个自定义类型,比如com.company.app.myThing,你可以将你的自定义对象作为散列传递给你想要的任何数据结构。显然,消费者需要知道并遵循这个模式。

这是扩展中info.plist 的相关部分:

<key>NSExtensionAttributes</key>
<dict>
  <key>NSExtensionActivationRule</key>
  <string>SUBQUERY(extensionItems, $extensionItem, SUBQUERY($extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;com.company.app.myThing&quot;).@count == 1).@count == 1</string>
  <key>NSExtensionPointName</key>
  <string>com.apple.ui-services</string>
  <key>NSExtensionPointVersion</key>
  <string>1.0</string>
</dict>

ActionViewController.viewDidLoad的扩展中:

let item = self.extensionContext.inputItems[0] as NSExtensionItem
let provider = (item.attachments as Array<NSItemProvider>)[0] as NSItemProvider
provider.loadItemForTypeIdentifier("com.company.app.myThing", options: nil, completionHandler: { msg, error in
    let my_thing = (msg as? NSDictionary) as Dictionary<String, AnyObject>
    // do stuff with my_thing
})

然后在宿主应用中:

let my_thing = [
  "foo": "bar",
  "baz": 123
]
let item = NSExtensionItem()
let attachment = NSItemProvider(item: my_thing, typeIdentifier: "com.company.app.myThing")
item.attachments = [attachment]
let activityViewController = UIActivityViewController(activityItems: [item], applicationActivities: nil)
self.presentViewController(activityViewController, animated: true, completion: actionComplete)

免责声明:请不要认为这是一个权威的方法,但我希望它可以为您指明正确的方向。

【讨论】:

    猜你喜欢
    • 2017-04-22
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多