带有字符串而不是文件的内容拦截器扩展
Content Blocker extension with a String instead of a file
我在内容拦截器扩展程序中使用函数 NSItemProvider(contentsOfURL: NSBundle.mainBundle().URLForResource("blockerList", withExtension: "json")
。
问题是我所有的规则都存储在一些字典中,当我使用这个功能时,总是因为规则已经改变了。我目前正在从这些字典中创建一个看起来像 "[{\"trigger\": {\"url-filter\": \"webiste.com\"},\"action\": {"\type\": \"css-display-none\",\"selector\":\".testContentBlocker\"}}]"
的字符串,我必须将其转换为 JSON 文件,以便最终能够在前面描述的函数中使用它。
不必将字符串放入 JSON 文件中才能使用它,我可以做一些更简单的事情来使用 NSItemProvider()
吗?
通过在调试器中加载扩展(并使用 Hopper),您可以看到 NSItemProvider(contentsOfURL:)
只是注册以提供类型为 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。
我在内容拦截器扩展程序中使用函数 NSItemProvider(contentsOfURL: NSBundle.mainBundle().URLForResource("blockerList", withExtension: "json")
。
问题是我所有的规则都存储在一些字典中,当我使用这个功能时,总是因为规则已经改变了。我目前正在从这些字典中创建一个看起来像 "[{\"trigger\": {\"url-filter\": \"webiste.com\"},\"action\": {"\type\": \"css-display-none\",\"selector\":\".testContentBlocker\"}}]"
的字符串,我必须将其转换为 JSON 文件,以便最终能够在前面描述的函数中使用它。
不必将字符串放入 JSON 文件中才能使用它,我可以做一些更简单的事情来使用 NSItemProvider()
吗?
通过在调试器中加载扩展(并使用 Hopper),您可以看到 NSItemProvider(contentsOfURL:)
只是注册以提供类型为 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。