首页 iOS 实现垃圾短信客户端过滤 (Message Filter Extension)
文章
取消

iOS 实现垃圾短信客户端过滤 (Message Filter Extension)

Message Filter Extension 是 Apple 为开发者提供的短信过滤 App 扩展.

概述

当我们的设备收到 未知联系人 的短信的时候,短信App 就会调用我们创建的 Message Filter Extension 来帮我们过滤垃圾短信. Message Filter Extension 可以让我们定义自己的 过滤规则 来过滤垃圾短信.

提示 扩展作用的对象仅仅限于来自 未知发件人 的 SMS 和 MMS 消息. 来自 用户通讯录 内联系人的信息不会被过滤.

App 扩展本地过滤短信的工作流程

短信App 通过一个 ILMessageFilterQueryRequest 实例对象来传递短息信息到 App扩展. 然后 App扩展 使用自定义的 过滤规则 判断短信是否是垃圾信息. 然后通过一个 ILMessageFilterQueryResponse 实例对象, 把判断结果返回给 短信App.

通过服务器过滤短信的工作流程

如果你的本地 App扩展 不能直接判断出结果, 则 App扩展 会通知 短信App 发送短信数据到与 App扩展 关联的服务器, 由服务器处理并返回处理结果. 短信App 得到服务器的响应后, 把服务器的响应数据传递给 App扩展, 由 App扩展 处理服务器返回的数据, 并把判断结果返回给 短信App.

提示 出于安全的考虑, 与服务器的数据通信将会由 iOS 系统来完成. App扩展 无法直接访问网络. 并且 App扩展 也无法通过写入数据到 App Group 的公共存储空间到来共享数据给 宿主App.

实现

创建 Message Filter Extension

选择 File -> New -> Target... -> Message Filter Extension, 创建新的 target.

代码

在新创建的 Target 中只有 MessageFilterExtension 一个类. 我们所有的逻辑都会在这里来完成.

处理 短信App 的请求

在接收到 未知联系人 的短信时候此方法会被调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- (void)handleQueryRequest:(ILMessageFilterQueryRequest *)queryRequest context:(ILMessageFilterExtensionContext *)context completion:(void (^)(ILMessageFilterQueryResponse *))completion {
    // 使用本地规则过滤短信
    ILMessageFilterAction offlineAction = [self offlineActionForQueryRequest:queryRequest];
    switch (offlineAction) {
        case ILMessageFilterActionAllow:
        case ILMessageFilterActionFilter: {
            // 返回本地规则过滤结果
            ILMessageFilterQueryResponse *response = [[ILMessageFilterQueryResponse alloc] init];
            response.action = offlineAction;
            completion(response);
            break;
        }
        case ILMessageFilterActionNone: {
            // 根据本地规则无法判断是否是垃圾短信
            // 通过服务器来处理
            [context deferQueryRequestToNetworkWithCompletion:^(ILNetworkResponse *_Nullable networkResponse, NSError *_Nullable error) {
                ILMessageFilterQueryResponse *response = [[ILMessageFilterQueryResponse alloc] init];
                response.action = ILMessageFilterActionNone; 
                if (networkResponse) {
                    // 如果从服务器获取到了服务器的处理结果, 则解析服务器返回的数据, 并返回给 短信App.
                    response.action = [self actionForNetworkResponse:networkResponse];
                } else {
                    NSLog(@"Error deferring query request to network: %@", error);
                }           
                completion(response);
            }];
            break;
        }
    }
}

自定义方法, 通过本地规则过滤垃圾短信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 处理短信过滤内容

 @param queryRequest 短信数据
 @return 处理结果
 */
- (ILMessageFilterAction)offlineActionForQueryRequest:(ILMessageFilterQueryRequest *)queryRequest {
    // 1. 可以根据 发送者 过滤 指定 发送者
    if ([queryRequest.sender containsString:@"xxxxx"]) {
        return ILMessageFilterActionFilter;
    }
    // 2. 根据短息内容过滤特定 关键词
    if ([queryRequest.messageBody containsString:@"俱乐部"] ||
        [queryRequest.messageBody containsString:@"澳门"]) {
        return ILMessageFilterActionFilter;
    }
    // 根据具体逻辑返回结果
    // 1. 无法处理: ILMessageFilterActionNone (请求服务器处理)
    // 2. 通过规则: ILMessageFilterActionAllow (判定为非垃圾短信)
    return ILMessageFilterActionNone;
}

处理关联服务器响应结果

1
2
3
4
5
6
7
8
9
10
11
/**
 解析服务器返回的数据

 @param networkResponse 服务器返回的数据
 @return 过滤判断结果
 */
- (ILMessageFilterAction)actionForNetworkResponse:(ILNetworkResponse *)networkResponse {
    // 解析服务器返回的数据, 返回过滤判断结果
    // 解析数据代码
    return ILMessageFilterActionAllow;
}

至此客户端的功能基本已经实现完成, 可以装上 App 实际测试一下了.

本文由作者按照 CC BY 4.0 进行授权