Content Blocker extension with a String instead of a file

烈酒焚心 提交于 2019-12-04 13:47:21

By loading the extension up in the debugger (and by using Hopper), you can see that NSItemProvider(contentsOfURL:) is simply registering to provide data from the file's contents with type public.json.

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

It's roughly equivalent to this:

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

So you can do this yourself, in memory:

// 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);

If you want to provide content dynamically, you can use NSJSONSerialization to transform a dictionary into NSData at runtime.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!