Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple filters for Safari content blocking Swift

I'm building a simple content-blockin app. It works, but i want to apply filters (which webs to block and which not) with UISwitches (saved to NSUserDefaults). Because the content blocking extension uses json it's unclear to me how can i select multiple json files to function simultaneously.

Any ideas how it can be achieved? Multiple extensions? Combining and splitting json files somehow?

like image 793
David Robertson Avatar asked Oct 01 '15 00:10

David Robertson


1 Answers

I have been in same situation. Answer to this is bit tricky, so bear with me. You cannot write to file in bundle i.e blockerList.json is not writeable. Here is what you need to do,

  1. Enable App groups from TARGETS->YOUR MAIN APP -> Capabilities -> App Groups. And add unique identifier for app groups. Do same with extension. (Use same identifier as group name which you entered for main app)
  2. Create a file in Container directory.
  3. Write rules (json) to that file.
  4. Reload extension once you have written rules.
  5. Read rules from Container directory in content blocker extension.

From your main app create file and write json rules into that file as:

let jsonData = try! JSONSerialization.data(withJSONObject: webFilters, options: JSONSerialization.WritingOptions.prettyPrinted)

//Convert back to string. Usually only do this for debugging

if let JSONString = String(data: jsonData, encoding: String.Encoding.utf8) {

                        let file = "conbo.json"


                        if let dir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "YOUR_GROUP_IDENTIFIER") {

                            let path     = dir.appendingPathComponent(file)

                            do {

                                try JSONString.write(to: path, atomically: false, encoding: String.Encoding.utf8)

                                let id = "YOUR_CONTENT_BLOCKER_BUNDLE_IDENTIFIER"
                                SFContentBlockerManager.reloadContentBlocker(withIdentifier: id) {error in



                                    guard error == nil else {
                                        print(error ?? "Error")
                                        return
                                    }

                                    print("Reloaded")
                                }

                            }
                            catch {
                            }
                        }


                    }

Now in extension read file from container as:

class ContentBlockerRequestHandler: NSObject, NSExtensionRequestHandling {

func beginRequest(with context: NSExtensionContext) {

    let file = "conbo.json"


    if let dir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "YOUR_APP_GROUP_IDENTIFIER") {

        let path     = dir.appendingPathComponent(file)

        do {



            do {
                let attachment =  NSItemProvider(contentsOf: path)!

                let item = NSExtensionItem()
                item.attachments = [attachment]

                context.completeRequest(returningItems: [item], completionHandler: nil)


            } 



        }

    }



}



}
like image 136
Saqib Omer Avatar answered Nov 03 '22 08:11

Saqib Omer