Blue Triangle iOS SDK 帮助应用程序所有者跟踪其用户体验,以便他们能够专注于影响其业务成果的用户体验问题。
要将 BlueTriangle 通过 Swift Packages Manager 集成到您的 iOS 项目中,您需要按照以下步骤操作
转到 File > Add Packages…,输入包存储库 URL https://github.com/blue-triangle-tech/btt-swift-sdk.git
,然后点击 Add Package。
Xcode 11 - 12: 转到 File > Swift Packages > Add Package Dependency…,然后输入包存储库 URL https://github.com/blue-triangle-tech/btt-swift-sdk.git
,然后按照说明操作。
要将 BlueTriangle 通过 CocoaPods 集成到您的 iOS 项目中,您需要按照以下步骤操作
pod 'BlueTriangleSDK-Swift'
pod install
要使用 BlueTriangle
,您需要首先配置 BlueTriangle
SDK。要配置它,请导入 BlueTriangle
并使用您的 siteID 调用配置函数。建议在您的 AppDelegate.application(_:didFinishLaunchingWithOptions:)
或 SceneDelegate.scene(_ scene:, willConnectTo session:, options,connectionOptions:)
方法中执行此操作
BlueTriangle.configure { config in
config.siteID = "<MY_SITE_ID>"
}
如果您使用的是 SwiftUI,建议在您的 App struct 中添加一个 init() 构造函数,并在其中添加配置代码,如下所示。
import BlueTriangle
import SwiftUI
@main
struct YourApp: App {
init() {
//Configure BlueTriagle with your siteID
BlueTriangle.configure { config in
config.siteID = "<MY_SITE_ID>"
}
//...
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
将 <BTT_SITE_ID>
替换为您的 site ID。 您可以在 这里 找到有关如何查找您的 site ID 的说明。
应用程序开发人员有责任确保隐私营养标签符合您应用中 BlueTriangle SDK 的使用情况。例如,如果您的应用使用收入跟踪(Timers cartValue),则其应用程序开发人员有责任在其中应用程序的隐私清单数据使用情况中提及购买历史记录。 更多详情请参见 隐私清单章节
所有 UIKit UIViewControllers 视图计数将自动跟踪。您可以在我们的仪表板上看到每个视图控制器的名称及其计数。如果您想忽略特定的视图控制器(即,不想跟踪该屏幕),您可以按照以下方式使用“ignoreViewControllers”配置属性将其排除在外。
确保视图控制器名称完全匹配,因为它区分大小写。
BlueTriangle.configure { config in
...
config.ignoreViewControllers = ["UIViewController"]
}
SwiftUI 视图不会自动捕获。您需要在要跟踪的每个视图上调用 bttTrackScreen() 修饰符。以下示例显示了使用“bttTrackScreen(_ screenName: String)”跟踪“关于我们”屏幕的示例。
struct ContentView: View {
var body: some View {
VStack{
Text("Hello, world!")
}
.bttTrackScreen("Demo_Screen")
}
}
要禁用屏幕跟踪,您需要在配置期间将 enableScreenTracking 配置设置为 false,如下所示,这将忽略 UIViewControllers 活动和 bttTrackScreen() 修饰符调用。
BlueTriangle.configure { config in
...
config.enableScreenTracking = false
}
在 webview 中显示的由 BlueTriangle 跟踪的网站可以在与原生应用相同的会话中进行跟踪。要实现此目的,请按照以下步骤配置 WebView
实现 WKNavigationDelegate 协议并在 'webView(_:didCommit:)' 委托方法中调用 BTTWebViewTracker.webView(webView, didCommit: navigation),如下所示。
import BlueTriangle
//....
extension YourWebViewController: WKNavigationDelegate{
//....
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
//....
//Call BlueTringles 'webView(_:didCommit:)' method
BTTWebViewTracker.webView(webView, didCommit: navigation)
}
}
为了更清晰起见,这是一个带有 UIViewController 的 Webview 的完整示例
import UIKit
import WebKit
//Need to import BlueTriangle
import BlueTriangle
class YourWebViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
//Set navigationDelegate
webView.navigationDelegate = self
//Load Url
if let htmlURL = URL(string: "https://example.com"){
webView.load(URLRequest(url: htmlURL))
}
}
}
//Implement Navigation Delagate
extension YourWebViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
//...
//Call BlueTringles 'webView(_:didCommit:)' method
BTTWebViewTracker.webView(webView, didCommit: navigation)
}
}
带有 SwiftUI 的 Webview 的完整示例
import SwiftUI
import WebKit
//Need to import BlueTriangle
import BlueTriangle
struct YourWebView: UIViewRepresentable {
private let webView = WKWebView()
func makeCoordinator() -> YourWebView.Coordinator {
Coordinator()
}
func makeUIView(context: Context) -> some UIView {
//Set navigationDelegate
webView.navigationDelegate = context.coordinator
//Load Url
if let htmlURL = URL(string: "https://example.com"){
webView.load(URLRequest(url: htmlURL))
}
return webView
}
}
extension YourWebView {
//Implement Navigation Delegate Coordinator
class Coordinator: NSObject, WKNavigationDelegate {
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
//...
//Call BlueTringles 'webView(_:didCommit:)' method
BTTWebViewTracker.webView(webView, didCommit: navigation)
}
}
}
** 会话拼接问题排查 **
为了验证会话拼接是否正确完成,我们有函数 verifySessionStitchingOnWebView(_:completion:) 来进行验证。此功能仅用于调试目的
在 WKNavigationDelegate 协议的 webView(_:didFinish:) 委托方法中,调用 BTTWebViewTracker.verifySessionStitchingOnWebView(_:completion:),如下所示。
import BlueTriangle
//....
extension YourWebViewController: WKNavigationDelegate{
//....
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//....
//Call BlueTringles 'verifySessionStitchingOnWebView(_:completion:)' method
BTTWebViewTracker.verifySessionStitchingOnWebView(webView) { sessionId, error in
if let error = error{
NSLog("BlueTriangle: \(error)")
}else{
NSLog("BlueTriangle: Session stitching was successfull for session \(sessionId)")
}
}
}
}
Blue Triangle SDK 支持使用 bt-prefixed URLSession 方法或 NetworkCaptureSessionDelegate 捕获网络请求。
使用带有 NetworkCaptureSessionDelegate 的 URLSession 或使用一个 bt-prefixed URLSession 方法发出的网络请求将与在请求完成时启动的最后一个主要计时器相关联。请注意,仅在启动至少一个主要计时器之后才捕获请求,并且在请求结束之前它们不会与计时器相关联。
您可以将 NetworkCaptureSessionDelegate 或子类用作您的 URLSession 委托,以便在启用网络捕获时收集有关网络请求的信息
let session = URLSession(
configuration: .default,
delegate: NetworkCaptureSessionDelegate(),
delegateQueue: nil)
let timer = BlueTriangle.startTimer(page: Page(pageName: "MY_PAGE"))
...
let (data, response) = try await session.data(from: URL(string: "https://example.com")!)
如果您已经实现并将 URLSessionDelegate 设置为 URLSession,您可以调用 NetworkCaptureSessionDelegate 对象的 urlSession(session: task: didFinishCollecting:) 方法
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
//Your code ...
let sessionDelegate = NetworkCaptureSessionDelegate()
sessionDelegate.urlSession(session, task: task, didFinishCollecting: metrics)
}
或者,使用 bt-prefixed URLSession 方法来捕获网络请求
标准 | 网络捕获 |
---|---|
URLSession.dataTask(with:completionHandler:) | URLSession.btDataTask(with:completionHandler:) |
URLSession.data(for:delegate:) | URLSession.btData(for:delegate:) |
URLSession.dataTaskPublisher(for:) | URLSession.btDataTaskPublisher(for:) |
像使用标准对应项一样使用这些方法
let timer = BlueTriangle.startTimer(page: Page(pageName: "MY_PAGE"))
...
URLSession.shared.btDataTask(with: URL(string: "https://example.com")!) { data, response, error in
// ...
}.resume()
对于其他网络捕获要求,可以手动创建捕获的请求并将其提交到跟踪器。
如果您在请求中具有 URL、方法和 requestBodyLength,并且在响应中具有 httpStatusCode、responseBodyLength 和 contentType
let tracker = NetworkCaptureTracker.init(url: "https://example.com", method: "post", requestBodylength: 9130)
tracker.submit(200, responseBodyLength: 11120, contentType: "json")
如果您在请求中具有 urlRequest,在响应中具有 urlResponse
let tracker = NetworkCaptureTracker.init(request: urlRequest)
tracker.submit(urlResponse)
其中 urlRequest 和 urlResponse 分别是 URLRequest 和 URLResponse 类型。
如果在网络调用期间遇到错误
let tracker = NetworkCaptureTracker.init(url: "https://example.com", method: "post", requestBodylength: 9130)
tracker.failed(error)
OR
let tracker = NetworkCaptureTracker.init(request: urlRequest)
tracker.failed(error)
网络采样率表示捕获的会话网络请求的百分比。例如,值 0.05 表示将随机为 5% 的用户会话启用网络捕获。网络采样率值应介于 0.0 到 1.0 之间,表示百分比 0 到 100 的小数。默认的 networkSampleRate 值为 0.05,即仅捕获 5% 的会话网络请求。
要更改网络捕获采样率,请将“config.networkSampleRate”的值设置为 0.5,将其设置为 50%。
BlueTriangle.configure { config in
config.siteID = "<MY_SITE_ID>"
config.networkSampleRate = 0.5
...
}
要在配置期间禁用网络捕获,请将 0.0 设置为“config.networkSampleRate”。
建议在开发/调试时使用 100% 的采样率。通过在配置期间将“config.networkSampleRate”设置为 1.0。
以下字段可用于识别和细分用户,以进行优化的分析上下文。 它们可以在 SDK 中配置,并在应用程序中实时修改,并且它们在 Blue Triangle 门户中显示为报告的参数。
字段 | 含义 |
---|---|
abTestID="MY_AB_TEST_ID" | 捕获一个变量,使我们能够了解应用程序中两个变体的实时 AB 测试。 |
campaignMedium="MY_CAMPAIGN_MEDIUM" | 了解旅程开始的一般原因(电子邮件、付费搜索、自然搜索等) |
campaignName="MY_CAMPAIGN_NAME" | 了解启动旅程的营销活动名称。 |
campaignSource="MY_CAMPAIGN_SOURCE" | 了解营销活动的类型。 |
dataCenter="MY_DATA_CENTER" | 了解如果您有多个为客户提供服务的数据中心,您可以按数据中心对数据进行分组。 |
trafficSegmentName="MY_SEGMENT_NAME" | 这可用于细分环境类型。 例如,我们可以使用它来了解您是否具有 beta 版与生产版,但两者都是该应用程序的活动版本。 |
BlueTriangle.configure { config in
config.abTestID = "MY_AB_TEST_ID"
config.campaignMedium = "MY_CAMPAIGN_MEDIUM"
config.campaignName = "MY_CAMPAIGN_NAME"
config.campaignSource = "MY_CAMPAIGN_SOURCE"
config.dataCenter = "MY_DATA_CANTER "
config.trafficSegmentName = "MY_TRAFFIC_SEGEMENT_NAME"
}
虽然屏幕视图在安装后自动跟踪,但也可以根据需要配置自定义计时器。 自动计时器捕获遵循以下事件
要测量用户交互的持续时间,请初始化一个描述该交互的 Page
对象,并将其传递给 BlueTriangle.startTimer(page:timerType)
以接收正在运行的计时器实例。
let page = Page(pageName: "MY_PAGE")
let timer = BlueTriangle.startTimer(page: page)
如果您需要推迟计时器的启动,请将您的 Page
实例传递给 BlueTriangle.makeTimer(page:timerType)
,并在您准备好开始计时时调用计时器的 start()
方法
let page = Page(pageName: "MY_PAGE")
let timer = BlueTriangle.makeTimer(page: page)
...
timer.start()
在这两种情况下,请将您的计时器传递给 BlueTriangle.endTimer(_:purchaseConfirmation:)
以将其发送到 Blue Triangle 服务器。
BlueTriangle.endTimer(timer)
正在运行的计时器在传递给 BlueTriangle.endTimer(_:purchaseConfirmation:)
时会自动停止,但您可以通过调用计时器的 end()
方法提前结束计时。
timer.end()
...
// You must still pass the timer to `BlueTriangle.endTimer(_:)` to send it to the Blue Triangle server
BlueTriangle.endTimer(timer)
对于与结账相关的计时器,请创建一个 PurchaseConfirmation
对象,并将其与计时器一起传递给 BlueTriangle.endTimer(_:purchaseConfirmation:)
timer.end()
let purchaseConfirmation = PurchaseConfirmation(cartValue: 99.00)
BlueTriangle.endTimer(timer, purchaseConfirmation: purchaseConfirmation)
在客户结账时,可以为该事件配置以下数据参数。
品牌价值
let timer = BlueTriangle.startTimer( page: Page( pageName: "SignUp", brandValue: 100.0))
BlueTriangle.endTimer(timer)
购物车价值、购物车数量、购物车结账数量、订单号
let timer = BlueTriangle.startTimer(
page: Page(
pageName: "Confirmation"))
BlueTriangle.endTimer(
timer,
purchaseConfirmation: PurchaseConfirmation(
cartValue:99.0,
cartCount: 2,
cartCountCheckout : 2,
orderNumber: "ORD-123345"))
订单时间
PurchaseConfirmation 包括订单时间,该订单时间会自动设置为时间的结束时间。
BlueTriangle 通过监控主线程的使用情况来跟踪应用程序的响应能力。 如果任何任务长时间阻塞主线程导致应用程序无响应,则将被跟踪为 ANR 警告。 默认情况下,此时间间隔为 5 秒,即,如果任何任务阻塞主线程超过 5 秒,将触发 ANRWorning。可以使用下面的 "ANRWarningTimeInterval" 属性更改此时间间隔。
BlueTriangle.configure { config in
...
config.ANRWarningTimeInterval = 3
}
您可以在配置期间将 "ANRMonitoring" 配置属性设置为 "false" 来禁用它。
BlueTriangle.configure { config in
...
config.ANRMonitoring = false
}
Blue Triangle 跟踪 ios 报告的低内存警告。 通过监控 UIApplication.didReceiveMemoryWarningNotification 通知。
您可以在配置期间将 "enableMemoryWarning" 配置属性设置为 "false" 来禁用它。
BlueTriangle.configure { config in
...
config.enableMemoryWarning = false
}
内存使用情况是计时器间隔期间代码使用的内存量。 这是以字节为单位测量的。
针对每个计时器,都会发送 3 个内存测量值,最小值、最大值和平均值。
内存使用情况是指应用程序当前用于存储和管理数据的内存 (RAM) 量。 在 analytics.rcv 有效负载数据 json 中,使用 'minMemory'、'maxMemory' 和 'avgMemory' 来发送相应的内存使用情况。
要设置捕获内存使用情况的间隔(以秒为单位),请设置以下字段
BlueTriangle.configure { config in
...
config.performanceMonitorSampleRate = 1
}
要禁用内存使用情况,请设置以下字段
BlueTriangle.configure { config in
...
config.isPerformanceMonitorEnabled = false
}
CPU 使用率是计时器间隔期间代码使用的 CPU 量。 这是以 0-100% 的形式测量的。
针对每个计时器,都会发送 3 个 CPU 测量值,最小值、最大值和平均值。
CPU 使用率由 xcode 报告为 X.100% 格式 [其中 X 是内核数],通常意味着系统正在大量利用 CPU 资源。为了以 0% 到 100% 格式表示这一点,Blue Triangle 通过划分 CPU 内核数来计算 CPU 使用率。这将为您提供一个介于 0% 和 100% 之间的百分比值。
0% 到 100% 格式 = Instruments 上的总当前 CPU 使用率 / CPU 内核数。
例如,如果您有 4 个 CPU 内核,并且您当前的用量是 300%。 那么实际的 BTT CPU 使用率为 300% / 4 = 75%。 这表明 CPU 的使用率达到其总容量的 75%。
要设置捕获 CPU 使用率的间隔(以秒为单位),请在 BlueTriangleConfiguration 中设置以下字段
BlueTriangle.configure { config in
...
config.performanceMonitorSampleRate = 1
}
要禁用 CPU 使用率,请在 BlueTriangleConfiguration 中设置以下字段
BlueTriangle.configure { config in
...
config.isPerformanceMonitorEnabled = false
}
离线缓存是一项功能,允许 BTT SDK 在应用程序处于离线模式时跟踪计时器和其他分析数据。 即,BTT SDK 无法将数据发送回 Blue Triangle。
缓存的数据存在内存限制和过期时间。如果缓存超过内存限制,则只有在删除一些较旧的缓存数据(先进先出)后才会添加额外的追踪器数据。 同样,存储时间超过过期时间的缓存数据将被丢弃,并且不会发送到追踪器服务器。
可以使用配置属性 cacheMemoryLimit 和 cacheExpiryDuration 设置内存限制和过期时间,如下所示:
BlueTriangle.configure { config in
...
config.cacheMemoryLimit = 50 * 1024 (Bytes)
config.cacheExpiryDuration = 50 * 60 * 1000 (Millisecond)
}
默认情况下,cacheMemoryLimit 设置为 48 小时,cacheExpiryDuration 设置为 30 MB。
BlueTriangle SDK 允许捕获网络状态数据。网络状态是指设备上任何网络接口的可用性。网络接口包括 Wi-Fi、以太网、蜂窝网络等。一旦启用网络状态捕获,网络状态将与 SDK 捕获的所有计时器、错误和网络请求相关联。 此功能默认启用。
您可以通过在配置期间将 enableTrackingNetworkState 属性设置为“false”来禁用它。
BlueTriangle.configure { config in
...
config.enableTrackingNetworkState = false
}
BlueTriangle 追踪应用启动性能。启动时间是指应用启动后准备好进行用户交互所需的时间。 BlueTriangle 自动追踪热启动和冷启动。
冷启动是指应用进程未在主内存中的启动。 这可能是因为 iOS 或用户终止了您的应用进程,或者这是安装/更新/重启后的首次启动。
BlueTriangle SDK 测量冷启动延迟,即进程启动时间和“applicationDidBecomeActive(:)”结束之间的时间。 因此,冷启动时间是加载进程的累积时间以及“application(:didFinishLaunchingWithOptions:)”、“applicationWillEnterForeground(:)”和“applicationDidBecomeActive(:)”所花费的时间。
热启动是指应用进程已在主内存中的启动。 当用户从后台启动应用时,可能会发生这种情况。
BlueTriangle SDK 测量热启动延迟,即“applicationWillEnterForeground(:)”结束和“applicationDidBecomeActive(:)”结束之间的时间。 因此,热启动时间由“applicationDidBecomeActive(:)”所花费的时间决定。
当用户在应用在屏幕上时锁定设备并解锁设备时,iOS 会发出后台和前台通知。 因此,在应用处于活动状态时解锁后立即锁定会被追踪为热启动。
您可以通过在配置期间将“enableLaunchTime”配置属性设置为“false”来禁用它。 像这样:
BlueTriangle.configure { config in
...
config.enableLaunchTime = false
}
BlueTriangle 追踪应用崩溃,以报告崩溃收入相关性。 默认情况下,崩溃追踪已启用。
建议在任何其他崩溃追踪工具之前配置 BlueTriangle SDK,以避免与其他崩溃报告工具发生冲突。 我们建议在生产前测试您的崩溃报告,以确保崩溃同时报告给 BlueTriangle 和您的其他崩溃追踪工具。 崩溃追踪工具可能会相互冲突,不在其他崩溃追踪工具之前配置 BlueTriangle SDK 可能会导致冲突,从而导致 BlueTriangle 无法追踪崩溃。 尝试更改配置顺序并禁用另一个工具。
要禁用 BlueTriangle 崩溃追踪,请使用以下配置:
BlueTriangle.configure { config in
config.siteID = "<MY_SITE_ID>"
//Disable crash tracking
config.crashTracking = .none
}
如果由于任何原因您无法在崩溃追踪工具配置之前配置 BlueTriangle,您可以使用 BlueTriangle.startCrashTracking(),此函数允许 BlueTriangle 在配置 BlueTriangle SDK 之前启动崩溃追踪。 这有助于您希望在配置另一个崩溃追踪工具之后再配置 BlueTriangle SDK 的情况。
它是由开发人员定义的属性,引入到 BTT SDK 有效负载中,开发人员可以包含它来收集和追踪特定于其应用程序需求的额外信息。
要引入自定义变量,开发人员首先需要在 BlueTriangle 门户上创建它,方法是按照 自定义变量页面 上的说明进行操作。
然后,开发人员需要使用以下函数设置自定义变量:
BlueTriangle.setCustomVariable(<VARIABLE NAME>, value: <VALUE>)
为了获取自定义变量值,请使用变量名称调用以下内容:
let value = BlueTriangle.getCustomVariable(<VARIABLE NAME>)
要删除自定义变量值,请使用变量名称调用以下函数:
BlueTriangle.clearCustomVariable(<VARIABLE NAME>)
要删除所有自定义变量值,请调用以下函数:
BlueTriangle.clearAllCustomVariables()
其中 <VARIABLE NAME> 是用户在创建自定义变量时添加到门户的自定义变量的变量名称,例如 CV1、CV2 等,并且是开发人员想要在这些字段中设置的任何内容。
一旦设置了该值,它将与每个页面视图一起发送,直到通过调用上述任何清除方法来清除它。
要在门户上查看其中一个值,请导航到路径“菜单 > Native App Monitoring > Native App Performance Detail”,或转到 Session Lookup 页面。 然后,按会话 ID 搜索,并查看特定页面的性能测量详细信息。 了解更多详情
登录到您在 Blue Triangle 门户上的帐户,转到“Native App -> Performance overview”,并查看您是否可以观察到一些数据。
要测试内存警告,您可以使用以下步骤在 iOS 模拟器中生成内存警告:
要测试 ANR 追踪,您可以在主线程上声明和调用以下函数:
func testANRTracking(){ let startTime = Date() while true { if (Date().timeIntervalSince1970 - startTime.timeIntervalSince1970) > 30 { break } } }
要测试崩溃追踪,您可以声明和调用以下函数:
func testCrashTracking() { let array = NSArray() array.object(at: 99) }
为了方便测试和调试,SDK 包含可选的启动参数,允许开发人员在从 Xcode 运行应用程序时模拟特定场景。
此参数使 SDK 能够以 100% 的网络采样率运行,这对于测试所有网络都被捕获和处理的场景非常有用。
-FullSampleRate
此参数强制每次应用程序启动时都启动一个新会话。 它对于测试基于会话的功能很有帮助,确保每次运行都以干净的会话状态开始。
-NewSessionOnLaunch
这些参数仅在通过使用 Xcode 播放按钮启动应用程序时适用。 它们不适用于通过点击应用程序图标直接在设备上启动应用程序的情况。
您可以通过编辑项目的方案并将新条目添加到“Arguments Passed On Launch”来添加这些参数。