如何为iPhone创建消息应用过滤器扩展?

时间:2017-12-21 00:13:21

标签: ios swift

我正在开发一个消息过滤器应用扩展程序。我搜索了它并了解了身份查找,这是ios 11.0中新引入的概念。我开始知道我必须在info.plist中插入密钥

<key>NSExtension</key>
    <dict>
        <key>NSExtensionPrincipalClass</key>
            <string>MessageFilterExtension</string>
        <key>NSExtensionAttributes</key>
            <dict>
                <key>ILMessageFilterExtensionNetworkURL</key>
                <string>https://www.example-sms-filter-application.com/api</string>
            </dict>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.identitylookup.message-filter</string>
     </dict>

但插入这些后,在构建应用程序时,我得到黑屏。我刚刚插入此代码。在视图controller.swift文件中没有其他内容,并创建了一个具有相同类名的MessageFilterExtension.swift文件。

这是文档:https://developer.apple.com/documentation/identitylookup/creating_a_message_filter_app_extension

1 个答案:

答案 0 :(得分:0)

如上所述here,要创建扩展程序,您只需创建一个新的iOS应用程序,然后从Xcode菜单中选择File / New / Target并选择Message Filter Extension。

在您的扩展程序中,会自动为您创建一个继承自ILMessageFilterExtension的类。它也符合具有单一要求的ILMessageFilterQueryHandling协议handle(_ queryRequest:context:completion:)方法。

在此方法中,将ILMessageFilterQueryRequest类型的查询请求对象传递给您,您将可以访问邮件的发件人和messageBody

应用过滤规则后,需要调用完成闭包,它将采用您需要创建的ILMessageFilterQueryResponse类型的单个参数并设置其动作属性。

如果要阻止显示该消息,则需要将操作类型设置为.filter。其他两个选项.none.allow将无效,消息将正常显示。

这就是创建消息过滤扩展所需要做的全部工作。

以下是Filter Spam SMS应用中的示例,该应用使用CoreData共享容器加载用户创建的关键字列表,用于过滤邮件正文:

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
  }
}