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ụ
DevhoặcQA. - Một máy Mac đã cài Astra Scout để kiểm tra kết quả.
Project chưa có cấu hình QA
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.
Bấm + dưới danh sách Configurations, chọn Duplicate "Debug" Configuration và đặt tên
QA.
Chọn Product → Scheme → Edit Scheme…, bấm Duplicate Scheme và đặt tên, ví dụ
MyApp QA.Trong scheme mới, chọn Run, tab Info, đặt Build Configuration là
QA. Làm tương tự với Archive.
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.
Trong Project navigator, chọn project, rồi chọn target của app ở mục TARGETS.
Mở tab Build Settings, chọn All.
Bấm + bên trái nút Basic, chọn Add User-Defined Setting, đặt tên
AMPLITUDE_SERVER_URL.
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.
Mở tab Info. Trong Custom iOS Target Properties, rê chuột lên một dòng, bấm + và thêm:
Key Type Value 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/httpapivà 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:
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_URLrỗng nên dùng cấu hình Amplitude như trước. flushQueueSize: 1vàflushIntervalMillis: 1000gử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
NSLogghi địa chỉ đang dùng vào log hệ thống, dùng ở bước kiểm tra. Không dùngprint: khi Astra Scout mở app,printkhô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) | Type | Value |
|---|---|---|
App Transport Security Settings → Allows Local Networking (NSAllowsLocalNetworking) | Boolean | YES |
Privacy - Local Network Usage Description (NSLocalNetworkUsageDescription) | String | Bả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ới127.0.0.1và 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:
- Thêm khoá App Transport Security Settings (kiểu Dictionary), nếu chưa có.
- 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. - 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:

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:
- Tạo file
Info-QA.plisttrong thư mục của target: File → New → File from Template… → Property List. - Mở file, thêm hai khoá trên.
- 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.
| Simulator | iOS device | |
|---|---|---|
| File | .app, nén .zip để gửi | .ipa |
| Ký | Không | Development hoặc Ad Hoc |
| Yêu cầu | UDID iOS device của tester có trong provisioning profile |
Bản simulator:
xcodebuild -scheme <Scheme QA> -configuration <Cấu hình QA> -sdk iphonesimulator \
-derivedDataPath build buildFile 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
Trong Astra Scout, kết nối một simulator.
Upload file
.apptheo 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.Chạy một flow có
launchApp:yamlappId: com.example.app --- - launchAppMở 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:
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ạy | serverUrl |
|---|---|
| Emulator | http://10.0.2.2:5051/2/httpapi |
| Android device qua USB | http://127.0.0.1:5051/2/httpapi, sau khi chạy adb reverse tcp:5051 tcp:5051 trên Mac |
| Device qua Wi-Fi | http://<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:
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:
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ứng | Nguyên nhân | Cách sửa |
|---|---|---|
Log ghi serverUrl = Amplitude | Không phải bản QA, hoặc Info.plist thiếu AMPLITUDE_SERVER_URL | Kiể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: false | Chạy app qua flow, bỏ stopApp: false |
| Không thấy dòng log nào | Code ở bước 2 chưa chạy, hoặc dùng print thay vì NSLog | Kiểm tra code khởi tạo Amplitude |
| Simulator nhận được, iOS device thì không | Chưa cho quyền Local Network, khác mạng Wi-Fi, hoặc tắt Nhận event từ device trong mạng | Cho 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ước | Hà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
| Device | scoutServerUrl |
|---|---|
| Simulator | http://127.0.0.1:5051/d/<mã>/2/httpapi |
| iOS device | http://<tên máy Mac>.local:5051/d/<mã>/2/httpapi |
- Astra Scout nhận event ở cổng
5051. Đường dẫn/2/httpapitrù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ủascout-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
scoutServerUrltronglaunchApp: arguments:thì Astra Scout dùng giá trị của flow.
