swift 如何使用subAction为iOS制作消息过滤器

3lxsmp7m  于 2023-05-05  发布在  Swift
关注(0)|答案(1)|浏览(151)

我正在为iOS做一个短信过滤器,我想用subAction对一些消息进行分类我返回了subAction,但在我的iPhone中没有分类(iOS 16),我的应用程序会将它们分类为促销或交易这是我的代码:

import IdentityLookup
final class MessageFilterExtension: ILMessageFilterExtension {}

extension MessageFilterExtension: ILMessageFilterQueryHandling, ILMessageFilterCapabilitiesQueryHandling {
    func handle(_ capabilitiesQueryRequest: ILMessageFilterCapabilitiesQueryRequest, context: ILMessageFilterExtensionContext, completion: @escaping (ILMessageFilterCapabilitiesQueryResponse) -> Void) {
        let response = ILMessageFilterCapabilitiesQueryResponse()

        // TODO: Update subActions from ILMessageFilterSubAction enum
        completion(response)
    }

    func handle(_ queryRequest: ILMessageFilterQueryRequest, context: ILMessageFilterExtensionContext, completion: @escaping (ILMessageFilterQueryResponse) -> Void) {
        let (offlineAction, offlineSubAction) = self.offlineAction(for: queryRequest)
        print("====== STARTED ======")
        switch offlineAction {
        case .allow, .junk, .promotion, .transaction:
            // Based on offline data, we know this message should either be Allowed, Filtered as Junk, Promotional or Transactional. Send response immediately.
            let response = ILMessageFilterQueryResponse()
            response.action = offlineAction
            response.subAction = offlineSubAction

            completion(response)

        case .none:
            // Based on offline data, we do not know whether this message should be Allowed or Filtered. Defer to network.
            // Note: Deferring requests to network requires the extension target's Info.plist to contain a key with a URL to use. See documentation for details.
            context.deferQueryRequestToNetwork() { (networkResponse, error) in
                let response = ILMessageFilterQueryResponse()
                response.action = .none
                response.subAction = .none

                if let networkResponse = networkResponse {
                    // If we received a network response, parse it to determine an action to return in our response.
                    (response.action, response.subAction) = self.networkAction(for: networkResponse)
                } else {
                    NSLog("Error deferring query request to network: \(String(describing: error))")
                }

                completion(response)
            }

        @unknown default:
            break
        }
    }

    private func offlineAction(for queryRequest: ILMessageFilterQueryRequest) -> (ILMessageFilterAction, ILMessageFilterSubAction) {
        // TODO: Replace with logic to perform offline check whether to filter first (if possible).
        NSLog("recived msg: " + queryRequest.messageBody! + " sender: " + queryRequest.sender!)
        
        // reload setting
        SettingManager.getInstance().load()
        
        let whitelistResult = whitelistHandler(sender: queryRequest.sender!)
        if whitelistResult == .allow {
            return (.allow, .none)
        }
        let callingCodeResult = callingCodeHandler(sender: queryRequest.sender!)
        if  callingCodeResult != .none {
            return (callingCodeResult, .none)
        }
        if bombingHandler(msg: queryRequest.messageBody!) {
            return (.junk, .none)
        }
        let keywordResult = keywordHandler(msg: queryRequest.messageBody!)
        if  keywordResult != .none {
            return (keywordResult, .none)
        }
        
        let classificationResult = classifyHandler(msg: queryRequest.messageBody!)
        if classificationResult.0 != .none {
            return (classificationResult.0, classificationResult.1)
        }
        return (.none, .none)

    }

    func classifyHandler(msg: String) -> (ILMessageFilterAction, ILMessageFilterSubAction) {
        NSLog("checking msg's classification")
        let classificationFilters = DataManager.getInstance().getClassificationData()
        for filter in classificationFilters {
            NSLog("checking keyword: \(filter.keyword)")
            if (msg.contains(filter.keyword)) {
                NSLog("msg is in classification list, marked to \(filter.type)")
                return (filter.type.getAction(), filter.type.getSubAction())
            }
        }
        NSLog("msg is not in classification")
        return (.none, .none)
    }

    
    func whitelistHandler(sender: String) -> ILMessageFilterAction {
        ...
        return .none
    }
    
    func callingCodeHandler(sender: String) -> ILMessageFilterAction {
        ...
        return .none
    }
    
    // false: not need to filter
    // true: need filter
    func bombingHandler(msg: String) -> Bool {
        ...
        return false
    }
    
    func keywordHandler(msg: String) -> ILMessageFilterAction {
        ...
        return .none
    }
}

我尝试在第一个句柄函数中设置response的promotionalSubActions和transactionSubActions,但它不起作用

mlnl4t2r

mlnl4t2r1#

回答这个问题可能有点晚了,或者你可能已经想明白了,但这是给那些想知道为什么这段代码不起作用的人的。
这里的问题出在您的offlineAction方法中,您返回

ILMessageFilterAction and ILMessageFilterSubAction

在这里,每隔一个参数返回.none
从你的代码:-

  • return (.allow, .none)
  • return (callingCodeResult, .none)
  • return (.junk, .none)
  • return (keywordResult, .none)等...

这里返回的第二个参数的类型是ILMessageFilterSubAction,这里返回.none意味着你不想对你收到的短信应用任何基于子类的过滤,所以不是返回.none,而是根据你的逻辑,你可以具体返回.transactionalFinancepromotionalCoupons
下面是我的offlineAction方法代码片段

private func offlineAction(for queryRequest: ILMessageFilterQueryRequest) -> (ILMessageFilterAction, ILMessageFilterSubAction) {
    
    // TODO: Replace with logic to perform offline check whether to filter first (if possible).
    /// Offline logic goes here
    
    guard let messageBody = queryRequest.messageBody else { return (.none, .none) }
    switch messageBody {
    case _ where messageBody.lowercased().contains("code"):
        return (.transaction, .transactionalFinance)
    case _ where messageBody.lowercased().contains("discount"):
        return (.promotion, .promotionalCoupons)
    case _ where messageBody.lowercased().contains("earn"):
        return (.junk, .none)
    default:
        return (.none, .none)
    }  
}

希望这对你有帮助…

相关问题