代码之家  ›  专栏  ›  技术社区  ›  Kevin Sylvestre

iOS内容阻止扩展加载多个JSON文件

  •  8
  • Kevin Sylvestre  · 技术社区  · 10 年前

    是否可以从 内容阻止程序扩展 ? 在我的UI中,用户启用/禁用不同的过滤器,每个过滤器由一个单独的文件表示。我目前有(尽管迭代多次,但只加载一个):

    func beginRequestWithExtensionContext(context: NSExtensionContext) {
        var items = Array <NSExtensionItem>()
    
        let resources = ["a", "b", "c"]
        for resource in resources {
            let url = NSBundle.mainBundle().URLForResource(resource, withExtension: "json")
    
            if let attachment = NSItemProvider(contentsOfURL: url) {
                let item = NSExtensionItem()
                item.attachments = [attachment]
                items.append(item)
            }
        }
        context.completeRequestReturningItems(items, completionHandler: nil)
    }
    

    我试过做多个项目和一个带有多个附件的项目。如果不可能有单独的文件,有什么方法可以组合多个(或以编程方式生成)?

    3 回复  |  直到 10 年前
        1
  •  4
  •   bad_coder Singh    6 年前

    可以有多个JSON文件,并将其用于Content Blocker扩展。

    1) 投掷 SFContentBlockerErrorDomain 将多个扩展项传递给 completeRequestReturningItems 方法

    2) 无法将多个附件附加到 NSExtension 。源代码上的注释说,附件不是指一系列替代数据格式/类型,而是一个集合,例如,可以包含在社交媒体帖子中。始终键入这些项目 NSItemProvider 。我认为您无法添加多个JSON数据作为附件,因为它们不是创建消息的一系列附件。

    我的解决方案(已验证有效):

    NSITEM提供程序 可以用项目(NSData)初始化,并且 typeIdentifier .

    let aData = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("a", withExtension: "json")!)
    let bData = NSData(contentsOfURL: NSBundle.mainBundle().URLForResource("b", withExtension: "json")!)
    
    aJSON = `convert aData to JSON`
    bJSON = `convert bData to JSON`
    combinedJSON = `aJSON + bJSON`
    combinedData = 'convert combinedJSON to NSData'
    
    let attachment = NSItemProvider(item: combinedData, typeIdentifier: kUTTypeJSON as String)
    

    现在您可以使用附件创建扩展, combinedData 根据您的喜好。

        2
  •  3
  •   Kevin Sylvestre    10 年前

    对于那些好奇的人,我最终添加了代码来动态生成JSON文件(持久化到磁盘)。从其他答案来看,似乎可以通过返回 NSData 尽管我的尝试失败了。下面是我的代码片段:

    import UIKit
    import MobileCoreServices
    
    class ActionRequestHandler: NSObject, NSExtensionRequestHandling {
    
        func beginRequestWithExtensionContext(context: NSExtensionContext) {
            let item = NSExtensionItem()
            let items = [item]
    
            let url = buildJSONFileURL()
            if let attachment = NSItemProvider(contentsOfURL: url) { item.attachments = [attachment] }
    
            context.completeRequestReturningItems(items, completionHandler: nil)
        }
    
        func buildJSONFileURL() -> NSURL {
            let directories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
            let directory = directories[0]
    
            let path = directory.stringByAppendingFormat("/block.json")
    
            let selector = [...] // Dynamically Generated
            let dictionary = [[
                "action": [ "type": "css-display-none", "selector": selector ],
                "trigger": [ "url-filter": ".*" ]
                ]]
    
            let data = try! NSJSONSerialization.dataWithJSONObject(dictionary, options: NSJSONWritingOptions.PrettyPrinted)
            let text = NSString(data: data, encoding: NSASCIIStringEncoding)!
    
            try! text.writeToFile(path, atomically: true, encoding: NSASCIIStringEncoding)
    
            return NSURL(fileURLWithPath: path)
        }
    
    }
    
        3
  •  1
  •   Imran    6 年前

    您可以将两个JSON规则文件合并为一个文件并使用该文件。

        import UIKit
        import MobileCoreServices
        class ContentBlockerRequestHandler: NSObject, NSExtensionRequestHandling {
    
            func beginRequest(with context: NSExtensionContext) {
    
            let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "you app group identifier")
    
                    let sourceURLRules = sharedContainerURL?.appendingPathComponent("Rules1.json")
                    let sourceURLRules2 = sharedContainerURL?.appendingPathComponent("Rules2.json")
                    do {
                        let jsonDecoder = JSONDecoder()
    
                        let dataFormRules1 = try Data(contentsOf: sourceURLRules1!, options: .mappedIfSafe)// Rule is Decode able Swift class            
                       let  rulesArray1 = try? jsonDecoder.decode(Array<Rule>.self,from: dataFormRules1)
    
                        let dataFormRules2 = try Data(contentsOf: sourceURLRules2!, options: .mappedIfSafe)
                        let  rulesArray2 = try? jsonDecoder.decode(Array<Rule>.self,from: dataFormRules2)
    
                        saveCombinedRuleFile(ruleList: rulesArray1! + rulesArray2!)
    
                    } catch {
                        //handle error condition
                    }
    
                    let sourceURLCombinedRule = sharedContainerURL?.appendingPathComponent("CombinedRule.json")
                    let combinedRuleAttachment = NSItemProvider(contentsOf: sourceURLCombinedRule)
                    let item = NSExtensionItem()
                    item.attachments = [combinedRuleAttachment]
                    context.completeRequest(returningItems: [item], completionHandler: nil)
                }
    
                func saveCombinedRuleFile(ruleList:[Rule]) {
                    let encoder = JSONEncoder()
                    if let encoded = try? encoder.encode(ruleList) {
                        let sharedContainerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "you app group identifier")
                        if let json = String(data: encoded, encoding: .utf8) {
                            print(json)
                        }
                        if let destinationURL = sharedContainerURL?.appendingPathComponent("CombinedRule.json") {
                            do {
                                try  encoded.write(to: destinationURL)
                            } catch {
                                print ("catchtry")
                            }
                        }
                    }
                }
            }