一、前提条件
·创建并获取云 API 密钥信息 SecretId 和 SecretKey,密钥信息获取请前往 API 密钥管理。
·已在 CLS 控制台获取移动端接入 Token,详见 获取密钥。
三、步骤1:集成插件
支持 CocoaPods 和 手动集成 两种方式添加依赖。
四、方式一:CocoaPods(推荐)
1. 修改 CocoaPods 的配置文件 Podfile。
·仅日志上报功能:
platform :ios, '12.0'use_frameworks!target 'YourApp' do pod 'TencentCloudLogProducer/Core', '~> 3.1.0'end
·需要日志上报和网络诊断功能(完整功能):
platform :ios, '12.0'use_frameworks!target 'YourApp' do pod 'TencentCloudLogProducer/NetWorkDiagnosis', '~> 3.1.0'end
2. 打开终端,执行安装命令。
pod install
五、方式二:手动集成
1. 从 GitHub Releases 下载最新版本。
2. 将 TencentCloudLogProducer 文件夹拖入 Xcode 工程。并勾选 Copy items if needed 和 Create groups。
3. 添加依赖。手动添加以下依赖库:
·Protobuf (~> 3.29.5)
·FMDB (~> 2.7.5)
·Reachability (~> 3.7)
4. 配置系统库。在 Build Phases → Link Binary With Libraries 中添加:
·Foundation.framework
·SystemConfiguration.framework
·UIKit.framework
·CoreTelephony.framework(网络诊断)
·Network.framework(网络诊断)
·libz.tbd
·libsqlite3.tbd
·libresolv.tbd(网络诊断)
六、步骤2:初始化配置
其中 NetToken 为移动端接入 Token,用于上报数据时鉴权,获取方式请参见 获取密钥。
// 1. 配置日志上报ClsLogSenderConfig *config = [ClsLogSenderConfig configWithEndpoint:@"ap-guangzhou-open.cls.tencentcs.com" accessKeyId:@"YOUR_ACCESS_KEY_ID" accessKey:@"YOUR_ACCESS_KEY"];// 2. 初始化网络诊断(使用 netToken)NSString *netToken = @"YOUR_NET_TOKEN"; // Base64 编码的 JSON,包含 networkAppId/appKey/topic_id[[ClsNetworkDiagnosis sharedInstance] setupLogSenderWithConfig:config netToken:netToken];// 3. 设置全局扩展字段(可选)[[ClsNetworkDiagnosis sharedInstance] setUserEx:@{ @"scene": @"homepage"}];
七、网络诊断
网络诊断模块提供5种探测方式,帮助分析应用的网络性能和质量问题。
八、HTTP Ping
测量 HTTP/HTTPS 请求的完整生命周期,包含15个时间点:DNS 解析、TCP 连接、SSL 握手、请求发送、响应接收等。
九、基本用法
// 创建请求CLSHttpRequest *request = [[CLSHttpRequest alloc] init];request.domain = @"https://cloud.tencent.com"; // 完整 URLrequest.appKey = @"YOUR_APP_KEY";request.maxTimes = 3; // 探测 3 次request.timeout = 10000; // 超时 10 秒// 执行探测[[ClsNetworkDiagnosis sharedInstance] httpingv2:request complate:^(CLSResponse *response) { if (response.success) { NSLog(@"HTTP Ping 成功"); NSLog(@"结果: %@", response.content); // JSON 格式 // 解析结果 NSDictionary *data = response.data; NSDictionary *netOrigin = data[@"netOrigin"]; NSNumber *dnsTime = netOrigin[@"dns_time"]; // DNS 耗时(毫秒) NSNumber *tcpConnectTime = netOrigin[@"tcp_connect_time"]; // TCP 连接耗时 NSNumber *sslHandshakeTime = netOrigin[@"ssl_handshake_time"]; // SSL 握手耗时 NSNumber *totalTime = netOrigin[@"total_time"]; // 总耗时 NSLog(@"DNS: %@ms, TCP: %@ms, SSL: %@ms, 总计: %@ms", dnsTime, tcpConnectTime, sslHandshakeTime, totalTime); } else { NSLog(@"HTTP Ping 失败: %@", response.errorMessage); }}];
十、高级配置
CLSHttpRequest *request = [[CLSHttpRequest alloc] init];request.domain = @"https://api.example.com/health";request.appKey = @"YOUR_APP_KEY";request.maxTimes = 5;request.timeout = 15000;// 多网卡探测(WiFi + 蜂窝网络并发)request.enableMultiplePortsDetect = YES;// 扩展字段(自定义业务标识)request.detectEx = @{ @"api_name": @"/health", @"request_id": @"req_12345"};// 页面名称(用于分组统计)request.pageName = @"HomePage";// 追踪 ID(关联多个探测)request.traceId = [[NSUUID UUID] UUIDString];// SSL 证书验证(默认开启)request.enableSSLVerification = YES;[[ClsNetworkDiagnosis sharedInstance] httpingv2:request complate:^(CLSResponse *response) { // 处理结果}];
十一、HTTP 生命周期时间点
| 时间点 | 字段名 | 说明 |
| 1 | callStart | 开始调用 |
| 2 | dnsStart | DNS 解析开始 |
| 3 | dnsEnd | DNS 解析结束 |
| 4 | connectStart | TCP 连接开始 |
| 5 | secureConnectStart | SSL 握手开始 |
| 6 | secureConnectEnd | SSL 握手结束 |
| 7 | connectionAcquired | TCP 连接建立 |
| 8 | requestHeaderStart | 请求头发送开始 |
| 9 | requestHeaderEnd | 请求头发送结束 |
| 10 | requestBodyStart | 请求体发送开始 |
| 11 | requestBodyEnd | 请求体发送结束 |
| 12 | responseHeadersStart | 响应头接收开始 |
| 13 | responseHeaderEnd | 响应头接收结束 |
| 14 | responseBodyStart | 响应体接收开始 |
| 15 | responseBodyEnd | 响应体接收结束 |
注意:说明:
注意:时间计算示例:
十二、TCP Ping
测量 TCP 三次握手的延迟,适合测试特定端口的连通性。
// 创建请求CLSTcpRequest *request = [[CLSTcpRequest alloc] init];request.domain = @"cloud.tencent.com";request.appKey = @"YOUR_APP_KEY";request.port = 443; // HTTPS 端口request.maxTimes = 10; // 探测 10 次request.timeout = 5000; // 超时 5 秒// 执行探测[[ClsNetworkDiagnosis sharedInstance] tcpPingv2:request complate:^(CLSResponse *response) { if (response.success) { NSDictionary *data = response.data; NSDictionary *netOrigin = data[@"netOrigin"]; NSNumber *latencyMin = netOrigin[@"latency_min"]; // 最小延迟(毫秒) NSNumber *latencyMax = netOrigin[@"latency_max"]; // 最大延迟 NSNumber *latencyAvg = netOrigin[@"latency_avg"]; // 平均延迟 NSNumber *successCount = netOrigin[@"success_count"]; // 成功次数 NSNumber *failureCount = netOrigin[@"failure_count"]; // 失败次数 NSLog(@"TCP Ping 统计: 最小=%@ms, 平均=%@ms, 最大=%@ms, 成功=%@, 失败=%@", latencyMin, latencyAvg, latencyMax, successCount, failureCount); } else { NSLog(@"TCP Ping 失败: %@", response.errorMessage); }}];
常用端口:
| 服务 | 端口 |
| HTTP | 80 |
| HTTPS | 443 |
| MySQL | 3306 |
| Redis | 6379 |
| MongoDB | 27017 |
| SSH | 22 |
| SMTP | 25 |
| DNS | 53 |
十三、ICMP Ping
使用 ICMP 协议测量网络延迟和丢包率,适合网络质量评估。
十四、基本用法
// 创建请求CLSPingRequest *request = [[CLSPingRequest alloc] init];request.domain = @"cloud.tencent.com";request.appKey = @"YOUR_APP_KEY";request.maxTimes = 10; // Ping 10 次request.size = 64; // 包大小 64 字节request.interval = 200; // 间隔 200msrequest.timeout = 10000; // 超时 10 秒// 执行探测[[ClsNetworkDiagnosis sharedInstance] pingv2:request complate:^(CLSResponse *response) { if (response.success) { NSDictionary *data = response.data; NSDictionary *netOrigin = data[@"netOrigin"]; NSNumber *latencyMin = netOrigin[@"latency_min"]; // 最小延迟(毫秒) NSNumber *latencyMax = netOrigin[@"latency_max"]; // 最大延迟 NSNumber *latencyAvg = netOrigin[@"latency_avg"]; // 平均延迟 NSNumber *latencyStddev = netOrigin[@"latency_stddev"]; // 标准差 NSNumber *lossRate = netOrigin[@"loss_rate"]; // 丢包率(百分比) NSLog(@"Ping 统计: 延迟=%@/%@/%@ms, 抖动=%@ms, 丢包率=%@%%", latencyMin, latencyAvg, latencyMax, latencyStddev, lossRate); } else { NSLog(@"Ping 失败: %@", response.errorMessage); }}];
十五、IP 协议偏好控制(v3.0.0新增)
CLSPingRequest *request = [[CLSPingRequest alloc] init];request.domain = @"www.qq.com";request.appKey = @"YOUR_APP_KEY";request.maxTimes = 5;// 设置 IP 协议偏好request.prefer = -1; // -1: 自动检测(默认) // 0: IPv4 优先 // 1: IPv6 优先 // 2: 仅 IPv4 // 3: 仅 IPv6[[ClsNetworkDiagnosis sharedInstance] pingv2:request complate:^(CLSResponse *response) { if (response.success) { NSDictionary *netOrigin = response.data[@"netOrigin"]; NSString *hostIp = netOrigin[@"host_ip"]; // 实际使用的 IP 地址 NSLog(@"使用 IP: %@", hostIp); }}];
十六、DNS 解析
查询域名的 DNS 记录(A 记录/AAAA 记录),支持自定义 DNS 服务器。
十七、基本用法
// 创建请求CLSDnsRequest *request = [[CLSDnsRequest alloc] init];request.domain = @"cloud.tencent.com";request.appKey = @"YOUR_APP_KEY";request.timeout = 5000; // 超时 5 秒// 执行解析[[ClsNetworkDiagnosis sharedInstance] dns:request complate:^(CLSResponse *response) { if (response.success) { NSDictionary *data = response.data; NSDictionary *netOrigin = data[@"netOrigin"]; // 解析结果(JSON 数组) NSString *answerSection = netOrigin[@"answer_section"]; NSLog(@"DNS 解析结果: %@", answerSection); /* 示例输出: [ {"name":"cloud.tencent.com","type":"A","ttl":300,"data":"203.205.158.53"}, {"name":"cloud.tencent.com","type":"AAAA","ttl":300,"data":"2408:871a:2100:15::53"} ] */ } else { NSLog(@"DNS 解析失败: %@", response.errorMessage); }}];
十八、自定义 DNS 服务器
CLSDnsRequest *request = [[CLSDnsRequest alloc] init];request.domain = @"cloud.tencent.com";request.appKey = @"YOUR_APP_KEY";// 使用公共 DNS 服务器request.nameServer = @"8.8.8.8"; // Google DNS// request.nameServer = @"1.1.1.1"; // Cloudflare DNS// request.nameServer = @"119.29.29.29"; // DNSPod DNS// IP 协议偏好request.prefer = 0; // 0: A 记录优先, 1: AAAA 记录优先[[ClsNetworkDiagnosis sharedInstance] dns:request complate:^(CLSResponse *response) { // 处理结果}];
十九、MTR 路由跟踪
追踪数据包到目标主机的完整路径,包含每一跳的延迟和丢包率。
// 创建请求CLSMtrRequest *request = [[CLSMtrRequest alloc] init];request.domain = @"cloud.tencent.com";request.appKey = @"YOUR_APP_KEY";request.maxTTL = 30; // 最大跳数 30request.protocol = @"icmp"; // 协议:icmp / udprequest.timeout = 60000; // 超时 60 秒(路由跟踪耗时长)// 执行探测[[ClsNetworkDiagnosis sharedInstance] mtr:request complate:^(CLSResponse *response) { if (response.success) { NSDictionary *data = response.data; NSDictionary *netOrigin = data[@"netOrigin"]; // 路径信息(JSON 数组) NSString *pathDetail = netOrigin[@"path_detail"]; NSLog(@"路由路径: %@", pathDetail); /* 示例输出: [ {"hop":1,"ip":"192.168.1.1","latency":2.5,"latency_min":2.0,"latency_max":3.0,"loss":0,"responseNum":3}, {"hop":2,"ip":"10.0.0.1","latency":10.2,"latency_min":8.5,"latency_max":12.0,"loss":0,"responseNum":3}, {"hop":3,"ip":"203.205.158.1","latency":25.8,"latency_min":24.0,"latency_max":28.0,"loss":10,"responseNum":2}, … ] */ } else { NSLog(@"❌ MTR 失败: %@", response.errorMessage); }}];
20、协议选择说明
| 协议 | 说明 | 适用场景 |
| ICMP | 使用 ICMP Echo Request 协议 | 测量结果更准确,但可能被防火墙拦截 |
| UDP | 使用 UDP 数据包 | 穿透性更好,适合被 ICMP 拦截的网络环境 |
21、IP 协议偏好控制
本 SDK 的 v3.0.0版本新增 prefer 参数,支持 IPv4/IPv6 协议偏好设置。
22、prefer 参数说明
| 值 | 说明 | 适用场景 |
| -1 | 自动检测(默认值) | 由系统决定,优先使用双栈网络支持的协议 |
| 0 | IPv4 优先 | 双栈环境下优先使用 IPv4,IPv4不可用时使用 IPv6 |
| 1 | IPv6 优先 | 双栈环境下优先使用 IPv6,IPv6不可用时使用 IPv4 |
| 2 | IPv4 only | 仅使用 IPv4,IPv6地址会被忽略 |
| 3 | IPv6 only | 仅使用 IPv6,IPv4地址会被忽略 |
23、使用示例
// 示例 1: 强制使用 IPv4(适用于纯 IPv4 环境)CLSPingRequest *request = [[CLSPingRequest alloc] init];request.domain = @"www.qq.com";request.appKey = @"YOUR_APP_KEY";request.prefer = 2; // IPv4 only[[ClsNetworkDiagnosis sharedInstance] pingv2:request complate:^(CLSResponse *response) { // 只会 Ping IPv4 地址:203.205.158.53}];// 示例 2: 仅查询 IPv6 DNS 记录CLSDnsRequest *request = [[CLSDnsRequest alloc] init];request.domain = @"www.qq.com";request.appKey = @"YOUR_APP_KEY";request.prefer = 3; // IPv6 only – 仅返回 AAAA 记录[[ClsNetworkDiagnosis sharedInstance] dns:request complate:^(CLSResponse *response) { // ANSWER-SECTION: [{"type": "AAAA", "data": "2408:871a:2100:15::53"}]}];// 示例 3: IPv6 优先(双栈环境)CLSMtrRequest *request = [[CLSMtrRequest alloc] init];request.domain = @"cloud.tencent.com";request.appKey = @"YOUR_APP_KEY";request.prefer = 1; // IPv6 优先request.protocol = @"icmp";[[ClsNetworkDiagnosis sharedInstance] mtr:request complate:^(CLSResponse *response) { // 优先追踪 IPv6 路径,失败时自动降级到 IPv4}];
24、支持 prefer 参数的探测类型
| 探测类型 | 支持 prefer | 说明 |
| HTTP Ping | 不支持 | URL 已指定协议 |
| TCP Ping | 不支持 | 直接指定 IP 或域名 |
| ICMP Ping | 支持 | 支持 IPv4/IPv6协议选择 |
| DNS 解析 | 支持 | 支持 A/AAAA 记录查询控制 |
| MTR 路由跟踪 | 支持 | 支持 IPv4/IPv6路径跟踪 |