3

NSItemProvider(contentsOfURL: NSBundle.mainBundle().URLForResource("blockerList", withExtension: "json")在内容拦截器扩展中使用该功能。

问题是我所有的规则都存储在几个字典中,当我使用这个功能时,总是因为规则发生了变化。我目前正在从这些字典中创建一个看起来像的字符串,"[{\"trigger\": {\"url-filter\": \"webiste.com\"},\"action\": {"\type\": \"css-display-none\",\"selector\":\".testContentBlocker\"}}]"我必须将其转换为 JSON 文件,以便最终能够在前面描述的函数中使用它。

不必将字符串放在 JSON 文件中才能使用它,我可以做一些更简单的使用NSItemProvider()吗?

4

1 回答 1

8

通过在调试器中加载扩展(并使用Hopper),您可以看到它NSItemProvider(contentsOfURL:)只是注册以提供来自文件内容的数据 type public.json

(lldb) po attachment
<NSItemProvider: 0x7fd4c250f2a0> {types = (
    "public.file-url",
    "public.json"
)}

它大致相当于:

// possible implementation of NSItemProvider.init(contentsOfURL:)
convenience init?(contentsOfURL fileURL: NSURL!)
{
    self.init(item: fileURL, typeIdentifier: (fileURL.fileURL ? kUTTypeFileURL : kUTTypeURL) as String)

    let type = UTTypeCreatePreferredIdentifierForTag(
        kUTTagClassFilenameExtension, fileURL.pathExtension!, nil)?.takeRetainedValue() as! String

    registerItemForTypeIdentifier(type) { completionHandler, expectedValueClass, options in
        let data = try! NSData(contentsOfURL: fileURL, options: .DataReadingMappedAlways)
        completionHandler(data, nil)
    }
}

因此,您可以自己在内存中执行此操作:

// get the data
let data = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("blockerList", withExtension: "json")!)

// put the data in an item provider
let attachment = NSItemProvider(item: data, typeIdentifier: kUTTypeJSON as String)

// send the item to Safari
let item = NSExtensionItem()
item.attachments = [attachment]
context.completeRequestReturningItems([item], completionHandler: nil);

如果要动态提供内容,可以使用NSJSONSerialization在运行时将字典转换为 NSData。

于 2015-08-16T19:56:31.037 回答