> >

概述及资源

本文是 GeeGlance iOS SDK 的部署文档,用于指导 GeeGlance iOS SDK 的集成,读者需具有一定 iOS 编程知识基础。

1、环境需求

条目 资源
开发目标 iOS 9+
开发环境 Xcode 11+
系统依赖 libiconv.2.4.0.tbd
SDK 体积 4.6M(支持 bitcode)
包增量 0.5M

2、相关开发资料

条目 资源
SDK 当前版本 1.2.0

准备工作

1、创建应用

登录极验后台创建应用获取商户 ID (merchantId),并在后台配置 bundleId。

2、快速体验 Demo

iOS 压缩包附带的 GeeGlanceDemo 文件夹中是极验的示例工程,使用 Xcode 打开示例工程,修改 BundleID 和 merchantId 为创建应用时绑定的 BundleID 和 merchantId。

  1. 修改 bundleId
  2. 修改 AppDelegate.m 文件中的 registerWithMerchantId: 方法的参数 merchantId

    // 修改 merchantId
    [GeeGlanceManager registerWithMerchantId:@"4c73730ddc83ebc6f9b0af0d0e350590"];

3、开发环境搭建

3.1、手动集成

将下载获取的 GeeGlanceSDK.framework 以及 GeeGlanceResource.bundle 共 2 个文件添加到工程中, 确保 Copy items if needed 已被勾选。

添加完后, 以 Linked Frameworks and Libraries 方式导入 framework。

在拖入 GeeGlanceSDK.framework 到工程后, 请检查其是否被添加到 PROJECT -> Build Phases -> Linked Frameworks and Libraries, 以确保正常编译。

添加系统依赖库 libiconv.2.4.0.tbd

linkedlibraries

3.2、工程配置

  1. 针对静态库中的 Category, 需要在对应 target 的 Build Settings->Other Linker Flags 添加 -ObjC 编译选项。

    linkerflags

SDK 接入

1、调用逻辑

  1. registerWithMerchantId: 初始化 SDK 并配置 merchantId (建议在应用启动时调用该方法)
  2. 构造 GeeGlanceConfig 的实例,配置 sceneKeysceneType
  3. matchesInContent:withConfig:completionHandler: 开始内容识别

2、接口介绍

2.1、初始化

方法原型

/**
@abstract 将 merchantId 传入给 SDK,该参数为可选参数

@param merchantId 商户 ID,merchantId 通过后台注册获得,从极验后台获取该 merchantId,merchantId 需与 bundleId 配套
*/
+ (void)registerWithMerchantId:(NSString * _Nonnull)merchantId;

参数描述

参数 是否必填 类型 说明
merchantId NSString merchantId

接口作用

传入 merchantId,并开始初始化,预加载内容识别需要的资源

示例代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// GeeGlance
[GeeGlanceManager enableLog:YES];
[GeeGlanceManager registerWithMerchantId:@"4c73730ddc83ebc6f9b0af0d0e350590"];

return YES;
}

2.2、匹配敏感词

方法原型

/**
@abstract 匹配字符串中的敏感词

@param content 待匹配的字符串
@param config 匹配场景配置,包括配置场景 key 和场景 type
@param completionHandler 匹配结果

@discussion 匹配结果中包含三个字段
results - 匹配结果,包括匹配到的敏感词,敏感词在整段文本中的起始位置,敏感词类别、违规等级
originContent - 匹配的原文
extraInfo - 额外信息,包括传入的 merchantId、匹配任务的 taskId、sdk、应用、系统等版本号、机型,匹配出错时,error 中有具体错误描述信息
*/
+ (void)matchesInContent:(NSString * _Nullable)content
withConfig:(GeeGlanceConfig * _Nullable)config
completionHandler:(void(^)(GeeGlanceMatchingResult * _Nonnull result))completionHandler;

参数描述

参数 是否必填 类型 说明
content NSString 需匹配敏感词的内容
config GeeGlanceConfig 场景配置
completionHandler block 匹配结果回调

GeeGlanceMatchingResult

参数 说明
status 200 - 匹配正常,500 - 匹配出错,请根据 extraInfo 中的 error 查看具体出错信息
originContent 被匹配的原文
results 匹配到的敏感字符,若为空,说明无敏感字符
extraInfo 额外信息,包括 merchantId、 SDK 版本号等辅助定位问题的字段

GeeGlanceMatchResult

参数 说明
startLocation 敏感词在原文中的起始位置
endLocation 敏感词在原文中的结束位置
range 敏感词在原文中的 NSRange
resultCategory 敏感词类别
riskLevel 敏感词等级
sensitiveWord 敏感词

originContent

参数 说明
originContent 被匹配的原文

GeeGlanceExtraInfo

参数 说明
taskId 此次匹配的任务号
merchantId 商户号
clientType 客户端类型
sdkVersion SDK 版本号
systemVersion iOS 系统版本号
bundleShortVersion bundleShortVersion
bundleVersion bundleVersion
deviceModel 机型
error 匹配出错时返回,正常匹配时为 nil

匹配结果具体示例如下所示:

  1. 匹配结果数组:

    linkerflags

  2. 匹配原文:

    linkerflags

  3. 匹配的额外信息:

    linkerflags

接口作用

匹配输入内容中的敏感词

使用场景

匹配前,先构造 GeeGlanceConfig 的实例,传入 sceneKeysceneType,比如,若当前为评论场景,可将 sceneKey 设置为 commentsceneType 设置为 GeeGlanceSceneTypeMedium,若当前为创建昵称场景,可将 sceneKey 设置为 nicknamesceneType 设置为 GeeGlanceSceneTypeSuperShort,在用户即将提交输入内容时,调用该接口进行识别

示例代码

GeeGlanceConfig *config = [[GeeGlanceConfig alloc] initWithSceneKey:@"comment" sceneType:GeeGlanceSceneTypeMedium];
[GeeGlanceManager matchesInContent:self.text withConfig:config completionHandler:^(NSMutableArray<GeeGlanceMatchResult *> * _Nonnull results, NSString * _Nonnull originContent, GeeGlanceExtraInfo * _Nonnull extraInfo) {
dispatch_async(dispatch_get_main_queue(), ^{
[self handleMatchResults:results textView:self.textView];
if (completionHandler) {
completionHandler(self.text, results);
}
});
}];

集成 SDK 提供的输入控件

SDK 提供输入控件 GeeGlanceTextView,该控件可以在输入过程中实时识别敏感字符并进行标记,使用方法与系统控件 UITextView 一样。

集成步骤:

  1. 属性定义

    @property (nonatomic, strong) GeeGlanceTextView *editTextView;
  2. 属性初始化,并将视图添加到 UIViewController

    [self.editBackgroundView addSubview:self.editTextView];
    [self.editTextView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.leading.equalTo(self.editBackgroundView).offset(10);
    make.centerY.equalTo(self.editBackgroundView);
    make.trailing.equalTo(self.hintImageView.mas_leading).offset(-5);
    make.height.mas_equalTo(EditHeight - 2*EditTopMargin);
    }];

    - (GeeGlanceTextView *)editTextView {
    if (!_editTextView) {
    _editTextView = [[GeeGlanceTextView alloc] init];
    _editTextView.backgroundColor = [UIColor clearColor];
    _editTextView.delegate = self;
    _editTextView.maxLength = MAXInputCharactors;
    _editTextView.textContainerInset = UIEdgeInsetsMake(-2, 0, 0, 0);
    _editTextView.sceneKey = @"Bilibili";
    _editTextView.sceneType = GeeGlanceSceneTypeShort;
    // 自定义敏感字符标记颜色
    _editTextView.markBackgroundColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.16];
    _editTextView.markUnderlineColor = [UIColor colorWithRed:0 green:1 blue:0 alpha:0.64];
    }
    return _editTextView;
    }
  3. 输入过程监控,当输入文字较多产生换行时,需要实时修改控件高度

    // MARK: Layout EditView

    - (void)layoutEditView:(CGFloat)newHeight {
    if (newHeight > self.editTextView.bounds.size.height) {
    [self.editTextView mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.mas_equalTo(newHeight);
    }];
    [self.editView mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.mas_equalTo(MIN(EditHeight + newHeight - self.editTextView.bounds.size.height, MAXEditHeight));
    }];
    [self.view layoutIfNeeded];
    } else {
    [self.editTextView mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.mas_equalTo(newHeight);
    }];
    [self.editView mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.mas_equalTo(MIN(newHeight < self.originEditTextViewSize.height ? EditHeight : EditHeight + (newHeight - self.originEditTextViewSize.height), MAXEditHeight));
    }];
    [self.view layoutIfNeeded];
    }
    }

    // MARK: GeeGlanceTextViewDelegate

    - (void)textView:(GeeGlanceTextView *)textView didTextHeightChanged:(CGFloat)textHeight {
    [self layoutEditView:textHeight];
    }
  1. 输入状态监控,当出现敏感字符或者敏感字符消失时,可根据相关状态进行相关提示

    // MARK: GeeGlanceTextViewDelegate

    - (void)textView:(GeeGlanceTextView *)textView didGlanceStatusChanged:(GeeGlanceTextViewStatus)glanceStatus {
    [self setGlanceStatus:glanceStatus];
    }

    // MARK: Glance Status

    - (void)setGlanceStatus:(GeeGlanceTextViewStatus)status {
    switch (status) {
    case GeeGlanceTextViewStatusEmpty:
    {
    self.hintImageView.hidden = YES;
    [self hideErrorHintView];
    }
    break;

    case GeeGlanceTextViewStatusEditing:
    {
    self.hintImageView.hidden = NO;
    self.hintImageView.image = [UIImage imageNamed:@"Group 722"];
    [self hideErrorHintView];
    }
    break;

    case GeeGlanceTextViewStatusNormal:
    {
    self.hintImageView.hidden = NO;
    self.hintImageView.image = [UIImage imageNamed:@"Group 723"];
    [self hideErrorHintView];
    }
    break;

    case GeeGlanceTextViewStatusError:
    {
    self.hintImageView.hidden = NO;
    self.hintImageView.image = [UIImage imageNamed:@"Group 721"];
    [self showErrorHintView];
    }
    break;

    default:
    break;
    }
    }
  2. 输入完成后,提交,根据匹配结果决定提交策略

    // MARK: Send Action

    - (void)sendAction:(UIButton *)button {
    [self endEditing];
    __weak typeof(self) wself = self;
    [GTProgressHUD showLoadingHUDWithMessage:@"智能匹配中…"];
    [self.editTextView submitWithCompletionHandler:^(NSString * _Nonnull text, NSMutableArray<GeeGlanceMatchResult *> * _Nonnull results) {
    [GTProgressHUD hideAllHUD];
    [wself confirmSendContent:text matchResults:results];
    }];
    }

注:更详细的集成方法,请参考 Demo 中的 BilibiliSceneController.m 文件。

其他接口说明

1、设置使用场景 key

方法原型

/**
@abstract 设置使用场景 key,该参数为可选参数

@param sceneKey 使用场景 key

@discussion 推荐在只有单个识别场景时使用该方法设置场景 key,后续通过 `matchesInContent:completionHandler:` 方法进行内容识别
*/
+ (void)setSceneKey:(NSString * _Nullable)sceneKey;

参数描述

参数 是否必填 类型 说明
sceneKey NSString sceneKey

接口作用

设置使用场景 key

使用场景

推荐在只有单个识别场景时使用该方法设置场景 key,后续通过 matchesInContent:completionHandler: 方法进行内容识别,对于有多个识别场景的情况,可不用调用此方法,直接使用 matchesInContent:withConfig:completionHandler: 方法通过 config 传入场景 key 即可

示例代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// GeeGlance
[GeeGlanceManager enableLog:YES];
[GeeGlanceManager registerWithMerchantId:@"53224D4D49A298554E228466C25DC7C8"];
// 内容识别场景,比如,如果在发表评论时需要进行内容识别,可将 sceneKey 设置为 comment
[GeeGlanceManager setSceneKey:@"comment"];

return YES;
}

2、设置使用场景类型

方法原型

/**
@abstract 设置使用场景类型,该参数为必传参数

@param sceneType 使用场景类型

@discussion 当前场景类型有 4 种:
GeeGlanceSceneTypeSuperShort - 超短文本(昵称、群名称等)
GeeGlanceSceneTypeShort - 短文本(弹幕等)
GeeGlanceSceneTypeMedium - 中等文本(评论等)
GeeGlanceSceneTypeLong - 长文本(文章发布等)

推荐在只有单个识别场景时使用该方法设置场景 type,后续通过 `matchesInContent:completionHandler:` 方法进行内容识别
*/
+ (void)setSceneType:(GeeGlanceSceneType)sceneType;

参数描述

参数 是否必填 类型 说明
sceneKey GeeGlanceSceneType sceneType

接口作用

设置使用场景类型

使用场景

推荐在只有单个识别场景时使用该方法设置场景 type,后续通过 matchesInContent:completionHandler: 方法进行内容识别,对于有多个识别场景的情况,可不用调用此方法,直接使用 matchesInContent:withConfig:completionHandler: 方法通过 config 传入场景 type 即可

示例代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// GeeGlance
[GeeGlanceManager enableLog:YES];
[GeeGlanceManager registerWithMerchantId:@"4c73730ddc83ebc6f9b0af0d0e350590"];
// 内容识别场景,比如,如果在发表评论时需要进行内容识别,可将 sceneKey 设置为 comment
[GeeGlanceManager setSceneKey:@"comment"];
// 评论场景,文本长度一般中等,故可将 sceneType 设置为 GeeGlanceSceneTypeMedium
[GeeGlanceManager setSceneType:GeeGlanceSceneTypeMedium];

return YES;
}

3、匹配敏感词

方法原型

/**
@abstract 匹配字符串中的敏感词

@param content 待匹配的字符串
@param completionHandler 匹配结果

@discussion 匹配结果中包含三个字段
results - 匹配结果,包括匹配到的敏感词,敏感词在整段文本中的起始位置,敏感词类别、违规等级
originContent - 匹配的原文
extraInfo - 额外信息,包括传入的 merchantId、匹配任务的 taskId、sdk、应用、系统等版本号、机型,匹配出错时,error 中有具体错误描述信息
*/
+ (void)matchesInContent:(NSString * _Nullable)content
completionHandler:(void(^)(GeeGlanceMatchingResult * _Nonnull result))completionHandler;

参数描述

参数 是否必填 类型 说明
content NSString 需匹配敏感词的内容
completionHandler block 匹配结果回调

接口作用

用于单识别场景匹配输入内容中的敏感词

使用场景

对于单识别场景,并已通过 setSceneKey:setSceneType: 方法设置过 key 和 type,建议使用该方法进行内容识别,在用户即将提交输入内容时,调用该接口进行识别

示例代码

[GeeGlanceManager matchesInContent:self.editTextView.text withConfig:config completionHandler:^(GeeGlanceMatchingResult * _Nonnull result) {
[wself finishMatching:result.results originContent:result.originContent extraInfo:result.extraInfo];
}];

4、设置日志开关

设置日志开关,建议开发调试时打开日志,上线时关闭日志

/**
@abstract 设置日志开关,默认关闭,不打印日志

@param enableLog YES - 打印日志,NO - 不打印日志
*/
+ (void)enableLog:(BOOL)enableLog;

5、设置用户 id

设置用户 id

/**
@abstract 设置 uid,该参数为可选参数

@param uid 用户 id
*/
+ (void)setUid:(NSString * _Nullable)uid;

6、获取 SDK 版本号

获取 SDK 版本号

/**
@abstract 获取 SDK 版本号

@return SDK 版本号
*/
+ (NSString * _Nonnull)sdkVersion;