Hi I am writing a simple content blocker app. In this app I want to allow the user add a website that he wants to block and block it but for some reasons my content blocker doesn't block newly added website for some reasons. I used SFContentBlockerManager.reloadContentBlocker(withIdentifier: blockerIdentifier) it prints success but for some reasons it doesn't work.
import UIKit
import Cartography
import SwiftyJSON
import SafariServices
protocol MyProtocol{
func DeleteSite(num:Int)
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, MyProtocol {
var tableView: UITableView = UITableView()
var arr = [String]()
func DeleteSite(num: Int) {
if let path = Bundle.main.path(forResource: "blockerList", ofType: "json"){
guard let data = NSData(contentsOf: URL(fileURLWithPath: path)) else{
return
}
// JSON(data: data as Data)[num] = nil
var jsonObj = JSON(data: data as Data)
// jsonObj.arrayObject?.remove(at: num)
print(jsonObj)
if jsonObj != JSON.null {
// jsonObj.arrayObject[num] =
jsonObj[num] = nil
// print("Hello I do work here \(jsonObj.arrayValue.remove(at: num))")
tableView.reloadData()
// jsonObj.arrayObject?.remove(at: num)
} else {
print("Could not get json from file, make sure that file contains valid json.")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
let blockerIdentifier = "saltaim.SelfControl2.blocker"
SFContentBlockerManager.reloadContentBlocker(withIdentifier: blockerIdentifier) {error in
if error == nil {
print("Success")
} else {
print("----------------------------------------------")
print(error)
print("----------------------------------------------")
}
}
super.view.backgroundColor = UIColor.red;
//let blockerIdentifier = "com.appsfoundation.ContentBlocker.Blocker"
//SFContentBlockerManager.
// print("--------------------")
//print(FileManager.default.c)
//Bundle(for: ContentBlockerRequestHandler)
//print(Bundle.main.path(forResource: "blocker/blockerList", ofType: "json"))
//print(Bundle.main.path(forResource: "blockerList", ofType: "json"))
//print("--------------------")
//Bundle.main.url
//Bundle.main.pa
//FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: <#T##String#>)
// print(Bundle.main.url(forResource: "blocker/blockerList", withExtension: "json"))
// Bundle.init(for: ContentBlockerRequestHandler)
// print(Bundle.main.paths(forResourcesOfType: "blockerList.json", inDirectory: "blocker"))
tableView.register(MyTableViewCell.self, forCellReuseIdentifier: "cell")
if let path = Bundle.main.path(forResource: "blockerList", ofType: "json"){
guard let data = NSData(contentsOf: URL(fileURLWithPath: path)) else{
return
}
let jsonObj = JSON(data: data as Data)
print(jsonObj)
if jsonObj != JSON.null {
// print("Hello I do work here \(jsonObj["trigger"])")
guard let arr1 = jsonObj.array else{
return;
}
var count = arr1.count;
for index in 0...count-1{
//print("-------")
// print(jsonObj[index]["trigger"]["url-filter"].stringValue)
arr.append(jsonObj[index]["trigger"]["url-filter"].stringValue);
}
//for
} else {
print("Could not get json from file, make sure that file contains valid json.")
}
//
}
// arr.append("Hello")
// arr.append("my name is ")
let button = UIButton();
button.setTitle("+", for: .normal)
button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
// button.titleLabel?.text = "+"
self.view.addSubview(tableView)
self.view.addSubview(button)
tableView.delegate = self
tableView.dataSource = self
constrain(tableView, view, button){
tableView, view, button in
tableView.width == view.width
tableView.height == view.height - 50
tableView.top == view.top
tableView.right == view.right
button.height == 50
button.width == view.width
button.top == view.bottom - 50
button.right == view.right
}
//arr = Array()
// Do any additional setup after loading the view, typically from a nib.
// self.view.backgroundColor = UIColor.redColor();
}
func buttonPressed(){
// print("I was pressed")
//var alert = UIAlertView();
//alert.title = "Enter a website";
// alert.alertViewStyle = UIAlertViewStyle.plainTextInput
// alert.addB
//alert.addButton(withTitle: "Done")
//alert.addButton(withTitle: "Cancel")
var s:String?
var alert = UIAlertController(title: "Alert", message: "Enter website that you would like to block", preferredStyle: UIAlertControllerStyle.alert)
alert.addTextField { (text) in
text.placeholder = "http://";
s=text.text
}
let action = UIAlertAction(title: "Done", style: UIAlertActionStyle.default) { (action: UIAlertAction) in
guard let s = alert.textFields?[0].text else{
return
}
//var c = ["action":["type": "block"], "trigger":["url-filter":s]];
//print(c)
let path = Bundle.main.path(forResource: "blockerList", ofType: "json")!
var readString = "" // Used to store the file contents
do {
// Read the file contents
readString = try String.init(contentsOf: URL(fileURLWithPath: path))
//readString = fileURL.absoluteString
// readString = try String(contentsOfURL: fileURL)
} catch let error as NSError {
print("Failed reading from URL: \(URL(fileURLWithPath: path)), Error: " + error.localizedDescription)
}
// var size = (readString.characters.count - 1)
//print("The end index is \(readString.endIndex)")
print("------------------------")
readString = readString.replacingOccurrences(of: "]", with: "")
// print(readString.endIndex)
// readString = String(readString.characters.dropLast())
print(readString)
print("--------------------------")
// readString.remove(at: readString.endIndex)
// readString = readString.substring(to: readString.index(before: readString.endIndex))
readString += ",{\"action\":{\"type\":\"block\"},\"trigger\":{\"url-filter\":\"" + s+"\"}}]"
print("File Text: \(readString)")
// let fileName = "blockerList"
// let DocumentDirURL = try! FileManager.default.url(for: ., in: .userDomainMask, appropriateFor: nil, create: true)
// let fileURL = DocumentDirURL.appendingPathComponent(fileName).appendingPathExtension("json")
print("FilePath: \(path)")
let fileHandler = try! FileHandle(forWritingTo: URL(fileURLWithPath: path))
//fileHandler.
//fileHandler.seekToEndOfFile()
fileHandler.write(readString.data(using: String.Encoding.utf8, allowLossyConversion: false)!)
// fileHandler.write("Hello".data(using: String.Encoding.utf8, allowLossyConversion: false)!)
// fileHandler.write(c.description.data(using: String.Encoding.utf8, allowLossyConversion: false)!)
fileHandler.closeFile()
var readString1 = "" // Used to store the file contents
do {
// Read the file contents
readString1 = try String.init(contentsOf: URL(fileURLWithPath: path))
//readString = fileURL.absoluteString
// readString = try String(contentsOfURL: fileURL)
} catch let error as NSError {
print("Failed reading from URL: \(URL(fileURLWithPath: path)), Error: " + error.localizedDescription)
}
print("File Text: \(readString1)")
let blockerIdentifier = "saltaim.SelfControl2.blocker"
SFContentBlockerManager.reloadContentBlocker(withIdentifier: blockerIdentifier) {error in
if error == nil {
print("Success")
} else {
print("----------------------------------------------")
print(error)
print("----------------------------------------------")
}
}
}
let action2 = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) { (UIAlertAction) in
self.dismiss(animated: true, completion: nil)
}
alert.addAction(action)
alert.addAction(action2)
self.present(alert, animated: true, completion: nil)
//self.viewC
//presentedViewController(alert)
//alert.addA
// alert.show()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return arr.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 50
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
// Code here
// let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
var site = arr[(indexPath as NSIndexPath).item]
let cell = MyTableViewCell(num: (indexPath as NSIndexPath).item,site: site, style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.delegate = self;
// let cell = MyTableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
// cell.site = arr[(indexPath as NSIndexPath).item]
// let cell1 = MyTableViewCell();
// let cell = MyTableV
//cell.t
//let cell1 = tableView.dequeueReusableCell(withIdentifier: "cell")
//cell.textLabel?.text = "Hello"
//cell.textLabel?.text = arr[(indexPath as NSIndexPath).item]
return cell;
}
}
I ran into a similar issue when I wrote my own content blocker. When you create the content-blocker extension you also create a json file that the extension reads from. Now, the important part to that is that the extension ONLY reads from that file located in the extension's bundle directory.
From what I can see you are writing to a json file in your main app bundle and then reloading the content blocker. So the content blocker just simply looks at the file in it's own directory (again, seperate from the main bundle directory) and loads that json file.
To resolve this, you need to actually write your file changes to the json file located in the extensions bundle directory.
Here's an example:
let groupUrl: NSURL = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.com.mygroup")!
if let path = NSURL(string: "blockerList.json", relativeToURL: groupUrl) {
// write your json data to the path here
SFContentBlockerManager.reloadContentBlockerWithIdentifier("com.my.extension.identifier", completionHandler: nil)
}
Another important thing to note is you'll have to request special permissons to read and write from the extension's bundle.