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

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

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

概述

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

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

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 进行授权