I am making a sms message filter for iOS, I want to classify some message with subAction I returned subAction, But there is no classification in my iPhone(iOS 16), and my app will classify them to promotion or transaction this is my code:
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
}
}
I tried to set response's promotionalSubActions and transactionSubActions in first handle function, But it does not works
It might be late answering this question or you might have figured it out already but it's for someone who is wondering why this code haven't worked.
The problem here is in your offlineAction method where you are returning
Here you are returning
.none
in every second parameterFrom your code :-
return (.allow, .none)
return (callingCodeResult, .none)
return (.junk, .none)
return (keywordResult, .none)
etc...Here the second parameter your returning is of type
ILMessageFilterSubAction
and returning.none
here means you don't want to apply any subcategory based filteration to your incoming sms, so instead of returning.none
, based on your logic you can return specifically like.transactionalFinance
orpromotionalCoupons
etcHere's the code snippet from my code of offlineAction method
Hope this helps...