As mentioned here, to create an extension all you have to do is create a new iOS app and from the Xcode menu select File/New/Target and select Message Filter Extension.
In your extension a class that inherits from ILMessageFilterExtension
is automatically created for you. It also conforms to the ILMessageFilterQueryHandling
protocol which has a single requirement, the handle(_ queryRequest:context:completion:)
method.
In this method a query request object of type ILMessageFilterQueryRequest
is passed to you and you will have access to the sender and messageBody
of the message.
After you apply your filter rules, you need to call the completion closure which will take a single parameter of type ILMessageFilterQueryResponse
that you need to create and set it’s action property.
If you want to prevent the message from being shown you need to set the action type to .filter
. The other 2 options .none
and .allow
will have no effect, the message will be shown normally.
That’s all you have to do to create a Message Filter Extension.
Below is an example from the Filter Spam SMS app that uses a CoreData shared container to load the list of keywords created by the user, which are used to filter the message body:
import IdentityLookup
final class MessageFilterExtension: ILMessageFilterExtension {
var words:[Item] = []
let stack = CoreDataStack()
func loadItems() {
let context = stack.persistentContainer.viewContext
let itemDAO = ItemDAO(managedObjectContext: context)
let allItems = itemDAO.fetchItmes()
self.words = allItems.flatMap({ item in
return item.value != nil ? item : nil
})
}
}
extension MessageFilterExtension: ILMessageFilterQueryHandling {
func handle(_ queryRequest: ILMessageFilterQueryRequest, context: ILMessageFilterExtensionContext, completion: @escaping (ILMessageFilterQueryResponse) -> Void) {
let action = self.offlineAction(for: queryRequest)
let response = ILMessageFilterQueryResponse()
response.action = action
completion(response)
}
private func offlineAction(for queryRequest: ILMessageFilterQueryRequest) -> ILMessageFilterAction {
guard let messageBody = queryRequest.messageBody?.lowercased() else { return .none }
self.loadItems()
for word in self.words {
if let value = word.value,
messageBody.contains(value.lowercased()) {
return .filter
}
}
return .allow
}
}