Bỏ qua, đến nội dung

Gửi event của bản QA về Astra Scout ​

Cấu hình bản QA của app iOS và Android để Astra Scout nhận và kiểm tra event Amplitude khi tester chạy flow.

Astra Scout kiểm tra event Amplitude mà app gửi trong lúc chạy flow. Để nhận được event, bản QA phải gửi chúng về Astra Scout trên máy Mac của tester thay vì lên Amplitude. Dev app cấu hình việc này trong bản QA; bản phát hành giữ nguyên.

Trước khi bắt đầu ​

  • App dùng Amplitude SDK: Swift SDK hoặc iOS SDK cũ, Kotlin SDK trên Android.
  • Project có cấu hình build và scheme riêng cho QA, ví dụ Dev hoặc QA.
  • Một máy Mac đã cài Astra Scout để kiểm tra kết quả.
Project chưa có cấu hình QA
  1. Trong Project navigator, chọn project. Trong cột bên trái của editor, chọn project ở mục PROJECT, rồi mở tab Info.

  2. Bấm + dưới danh sách Configurations, chọn Duplicate "Debug" Configuration và đặt tên QA.

    Menu + dưới danh sách Configurations, mục Duplicate "Debug" Configuration

  3. Chọn Product → Scheme → Edit Scheme…, bấm Duplicate Scheme và đặt tên, ví dụ MyApp QA.

  4. Trong scheme mới, chọn Run, tab Info, đặt Build Configuration là QA. Làm tương tự với Archive.

    Edit Scheme, mục Run, danh sách Build Configuration có QA

Cách hoạt động ​

Amplitude SDK gửi event tới địa chỉ trong tuỳ chọn serverUrl. Astra Scout nhận event theo đúng API của Amplitude, nên bản QA chỉ cần đổi serverUrl.

Địa chỉ của Astra Scout khác nhau trên mỗi máy Mac và giữa simulator với iOS device. Vì vậy app không ghi cứng địa chỉ. Mỗi khi flow mở app bằng launchApp, Astra Scout truyền địa chỉ vào app qua launch argument scoutServerUrl, iOS lưu nó vào UserDefaults, và code QA đọc ra để dùng làm serverUrl.

Một bản QA dùng được cho mọi tester và mọi máy Mac. Dạng đầy đủ của địa chỉ ở mục Chi tiết.

1. Đánh dấu bản QA bằng AMPLITUDE_SERVER_URL ​

Tạo setting AMPLITUDE_SERVER_URL: có giá trị ở cấu hình QA, để trống ở Staging và Production. Code ở bước 2 chỉ đọc scoutServerUrl khi setting này có giá trị, nên bản phát hành không bao giờ gửi event về Astra Scout.

  1. Trong Project navigator, chọn project, rồi chọn target của app ở mục TARGETS.

  2. Mở tab Build Settings, chọn All.

  3. Bấm + bên trái nút Basic, chọn Add User-Defined Setting, đặt tên AMPLITUDE_SERVER_URL.

    Menu + của Build Settings, mục Add User-Defined Setting

  4. Setting mới nằm trong nhóm User-Defined. Bấm tam giác bên trái tên setting để hiện từng cấu hình. Bấm đúp vào cột giá trị ở dòng QA và nhập http://127.0.0.1:5051/2/httpapi. Để trống các dòng còn lại.

    AMPLITUDE_SERVER_URL có giá trị ở dòng QA, trống ở Debug và Release

  5. Mở tab Info. Trong Custom iOS Target Properties, rê chuột lên một dòng, bấm + và thêm:

    KeyTypeValue
    AMPLITUDE_SERVER_URLString$(AMPLITUDE_SERVER_URL)

Giá trị http://127.0.0.1:5051/2/httpapi còn là địa chỉ dự phòng: app dùng nó khi được mở bằng tay trên simulator. Khi Astra Scout mở app, scoutServerUrl thay thế nó.

Project quản lý build setting bằng file xcconfig

Thay cho bước 3 và 4, thêm dòng sau vào file xcconfig của cấu hình QA:

AMPLITUDE_SERVER_URL = http:/$()/127.0.0.1:5051/2/httpapi

và AMPLITUDE_SERVER_URL = vào file của Staging và Production. Trong xcconfig, // mở đầu chú thích. $() rỗng đặt giữa hai dấu / để tách chúng ra, và Xcode ra giá trị http://127.0.0.1:5051/2/httpapi. Bước 5 vẫn làm như trên.

2. Đọc scoutServerUrl khi khởi tạo Amplitude ​

Với Amplitude Swift SDK:

swift
var serverUrl = Bundle.main.object(forInfoDictionaryKey: "AMPLITUDE_SERVER_URL") as? String ?? ""
if !serverUrl.isEmpty,
   let scout = UserDefaults.standard.string(forKey: "scoutServerUrl"), !scout.isEmpty {
    serverUrl = scout
}

let configuration = serverUrl.isEmpty
    ? Configuration(apiKey: apiKey)
    : Configuration(apiKey: apiKey, flushQueueSize: 1, flushIntervalMillis: 1000, serverUrl: serverUrl)
let amplitude = Amplitude(configuration: configuration)
NSLog("[Amplitude] serverUrl = %@", serverUrl.isEmpty ? "Amplitude" : serverUrl)
  • Staging và Production có AMPLITUDE_SERVER_URL rỗng nên dùng cấu hình Amplitude như trước.
  • flushQueueSize: 1 và flushIntervalMillis: 1000 gửi từng event ngay khi phát sinh. Với cấu hình mặc định, SDK gom event lại, và event tới Astra Scout trễ so với bước đã tạo ra nó.
  • Dòng NSLog ghi địa chỉ đang dùng vào log hệ thống, dùng ở bước kiểm tra. Không dùng print: khi Astra Scout mở app, print không hiện ở đâu cả.

Với Amplitude iOS SDK cũ: Amplitude.instance().setServerUrl(serverUrl) và eventUploadThreshold = 1.

3. Cho phép gửi HTTP trong mạng nội bộ ​

Astra Scout nhận event qua http://. Bản QA cần hai khoá trong Info.plist:

Key (tên hiện trong Xcode)TypeValue
App Transport Security Settings → Allows Local Networking (NSAllowsLocalNetworking)BooleanYES
Privacy - Local Network Usage Description (NSLocalNetworkUsageDescription)StringBản QA gửi event analytics tới Astra Scout trong mạng nội bộ.
  • Allows Local Networking cho phép kết nối http:// tới 127.0.0.1 và các địa chỉ .local.
  • Privacy - Local Network Usage Description là nội dung hộp thoại xin quyền Local Network trên iOS device. Khi tester chọn Don't Allow, app giữ event lại và không gửi đi.

Trong tab Info, mục Custom iOS Target Properties:

  1. Thêm khoá App Transport Security Settings (kiểu Dictionary), nếu chưa có.
  2. Bấm tam giác bên trái để mở nó, bấm + trên dòng đó và thêm khoá con Allows Local Networking = YES.
  3. Thêm khoá Privacy - Local Network Usage Description với câu ở bảng trên.

Kết quả sau bước 1 và bước 3:

Custom iOS Target Properties có AMPLITUDE_SERVER_URL, App Transport Security Settings → Allows Local Networking và Privacy - Local Network Usage Description

Tab Info áp dụng cho mọi cấu hình, kể cả bản App Store. Nếu app không dùng mạng nội bộ cho việc gì khác, bản App Store không bao giờ kết nối tới mạng nội bộ, iOS không hỏi quyền, và hai khoá không có tác dụng ở bản đó.

Muốn hai khoá chỉ có trong bản QA

Thay vì thêm ở tab Info:

  1. Tạo file Info-QA.plist trong thư mục của target: File → New → File from Template… → Property List.
  2. Mở file, thêm hai khoá trên.
  3. Trong Build Settings, tìm Info.plist File, bấm tam giác để hiện từng cấu hình, đặt dòng cấu hình QA thành đường dẫn tới Info-QA.plist. Dòng Staging và Production giữ nguyên.

Nếu project tự sinh Info.plist (Generate Info.plist File = Yes), Xcode gộp các khoá trong Info-QA.plist vào Info.plist của cấu hình QA.

4. Build bản cho simulator và cho iOS device ​

Simulator và iOS device cần hai file build riêng, từ cùng một code.

SimulatoriOS device
File.app, nén .zip để gửi.ipa
KýKhôngDevelopment hoặc Ad Hoc
Yêu cầuUDID iOS device của tester có trong provisioning profile

Bản simulator:

bash
xcodebuild -scheme <Scheme QA> -configuration <Cấu hình QA> -sdk iphonesimulator \
  -derivedDataPath build build

File nằm ở build/Build/Products/<Cấu hình QA>-iphonesimulator/<App>.app.

Bản iOS device: Product → Archive với scheme QA, rồi Distribute App → Custom → Release Testing (Ad Hoc) hoặc Debugging (Development). Bản TestFlight và App Store không dùng được, vì clearState cần cài lại app từ bản build.

Tester gửi UDID iOS device của họ (xem trong Xcode → Window → Devices and Simulators); thêm UDID vào tài khoản Apple Developer trước khi build. Cách đưa build cho tester: Chia sẻ build cho tester.

5. Kiểm tra ​

  1. Trong Astra Scout, kết nối một simulator.

  2. Upload file .app theo Chia sẻ build cho tester. Chọn Window → Builds, chọn bản build và bấm Cài lên kèm tên simulator.

  3. Chạy một flow có launchApp:

    yaml
    appId: com.example.app
    ---
    - launchApp
  4. Mở Window → Tracking (Shift+Cmd+T). Cửa sổ liệt kê các event app vừa gửi.

Nếu cửa sổ ghi "Chưa ghi nhận event Amplitude nào.", xem địa chỉ app đang dùng. Chạy lệnh sau trong Terminal rồi chạy lại flow:

bash
xcrun simctl spawn booted log stream --predicate 'eventMessage CONTAINS "[Amplitude]"'

Dòng [Amplitude] serverUrl = http://127.0.0.1:5051/d/… nghĩa là app đã nhận địa chỉ của Astra Scout. Các trường hợp khác ở Xử lý sự cố.

Làm lại với bản build .ipa trên iOS device, chọn Allow khi app hỏi quyền Local Network.

Android ​

Astra Scout chưa truyền scoutServerUrl cho app Android. Bản QA Android dùng địa chỉ cố định:

Nơi app chạyserverUrl
Emulatorhttp://10.0.2.2:5051/2/httpapi
Android device qua USBhttp://127.0.0.1:5051/2/httpapi, sau khi chạy adb reverse tcp:5051 tcp:5051 trên Mac
Device qua Wi-Fihttp://<IP của Mac>:5051/2/httpapi, máy và Mac cùng mạng Wi-Fi. Địa chỉ <tên máy Mac>.local chỉ dùng được trên máy Android hiểu tên .local

Trong build.gradle.kts của module app, khai báo địa chỉ cho build type QA và để trống ở các build type khác:

kotlin
android {
    buildFeatures { buildConfig = true }
    buildTypes {
        getByName("debug") {   // build type dùng cho QA
            buildConfigField("String", "AMPLITUDE_SERVER_URL", "\"http://10.0.2.2:5051/2/httpapi\"")
        }
        getByName("release") {
            buildConfigField("String", "AMPLITUDE_SERVER_URL", "\"\"")
        }
    }
}

Khi khởi tạo Amplitude:

kotlin
val scoutUrl = BuildConfig.AMPLITUDE_SERVER_URL.ifEmpty { null }
val amplitude = Amplitude(Configuration(
    apiKey = apiKey,
    context = applicationContext,
    serverUrl = scoutUrl,                              // null: gửi lên Amplitude như bình thường
    flushQueueSize = if (scoutUrl != null) 1 else 30,
    flushIntervalMillis = if (scoutUrl != null) 1000 else 30000,
))

Không truyền chuỗi rỗng cho serverUrl: SDK coi đó là một địa chỉ và bản phát hành sẽ không gửi được event.

Android 9 trở lên chặn http://. Trong build type QA, bật android:usesCleartextTraffic="true" trong manifest, hoặc dùng network_security_config cho các địa chỉ trên.

IP của Mac lấy bằng ipconfig getifaddr en0. Menu Hành động của cửa sổ Tracking cũng liệt kê các địa chỉ này để copy.

Xử lý sự cố ​

Triệu chứngNguyên nhânCách sửa
Log ghi serverUrl = AmplitudeKhông phải bản QA, hoặc Info.plist thiếu AMPLITUDE_SERVER_URLKiểm tra scheme đang build và bước 1
Log ghi 127.0.0.1:5051/2/httpapi thay vì địa chỉ có /d/App không được mở bằng launchApp, hoặc launchApp có stopApp: falseChạy app qua flow, bỏ stopApp: false
Không thấy dòng log nàoCode ở bước 2 chưa chạy, hoặc dùng print thay vì NSLogKiểm tra code khởi tạo Amplitude
Simulator nhận được, iOS device thì khôngChưa cho quyền Local Network, khác mạng Wi-Fi, hoặc tắt Nhận event từ device trong mạngCho quyền trong Settings → Privacy & Security → Local Network; dùng chung Wi-Fi; bật lại công tắc trong Cài đặt → Amplitude
Xuất hiện event của lần chạy trướcHàng đợi của SDK còn event cũXoá app rồi cài lại

Bản App Store luôn gửi lên Amplitude. Kiểm tra tracking của bản đã phát hành bằng Tra cứu người dùng…, xem Kết quả từ Amplitude.

Chi tiết ​

DevicescoutServerUrl
Simulatorhttp://127.0.0.1:5051/d/<mã>/2/httpapi
iOS devicehttp://<tên máy Mac>.local:5051/d/<mã>/2/httpapi
  • Astra Scout nhận event ở cổng 5051. Đường dẫn /2/httpapi trùng với API của Amplitude.
  • Simulator chạy trong máy Mac nên gọi được 127.0.0.1. iOS device gọi máy Mac qua Wi-Fi bằng tên .local.
  • <mã> là 12 ký tự đầu của SHA-256 của scout-device:<UDID>. Astra Scout chỉ gắn event có mã này vào run của đúng device đó.
  • Event gửi tới địa chỉ không có /d/<mã> vẫn được nhận và gắn vào run đang chạy, nhưng không phân biệt được device.
  • Flow đã đặt scoutServerUrl trong launchApp: arguments: thì Astra Scout dùng giá trị của flow.