Console trong Xcode là một công cụ gỡ lỗi cho phát triển iOS hiển thị đầu ra NSLog, print, os_log và nhật ký sự cố ứng dụng theo thời gian thực. Theo Apple Unified Logging, bắt đầu từ iOS 10, Apple khuyến nghị sử dụng os_log thay vì NSLog để tập trung thu thập thông điệp qua Unified Logging System. Console kết hợp đầu ra trình gỡ lỗi và thông điệp hệ thống trong một cửa sổ Debug Area duy nhất, có thể truy cập bất cứ lúc nào trong quá trình phát triển.
Điểm chính
Console là một phần của Debug Area trong Xcode, nằm ở bảng dưới cùng của trình soạn thảo (View → Debug Area → Activate Console, phím tắt Cmd + Shift + Y). Console hiển thị tất cả đầu ra văn bản từ ứng dụng đang chạy: thông báo từ NSLog, os_log, print, cảnh báo thời gian chạy và kết xuất ngoại lệ tự động khi ứng dụng gặp sự cố.
Console hoạt động cả trên trình mô phỏng và thiết bị vật lý. Trong trình mô phỏng, thông báo đến ngay lập tức qua đường ống cục bộ; trên thiết bị, chúng đến qua kết nối USB với độ trễ 1–3 khung hình. Đối với ứng dụng sản xuất, Console trên thiết bị không khả dụng — các nhà phát triển dựa vào Crashlytics hoặc Unified Logging với thu thập từ xa qua log collect.
Khác với ứng dụng hệ thống Console.app trên Mac, cửa sổ Console trong Xcode chỉ hiển thị nhật ký của ứng dụng đang chạy hiện tại (có khả năng lọc). Console.app thu thập nhật ký của tất cả các tiến trình trên Mac, bao gồm cả trình mô phỏng iOS. Tuy nhiên, để gỡ lỗi ứng dụng iOS, các nhà phát triển sử dụng Console tích hợp sẵn của Xcode do tích hợp với trình gỡ lỗi LLDB.
Ba API chính có sẵn cho nhà phát triển iOS để xuất ra Console: NSLog (lỗi thời), os_log (được khuyến nghị) và print (chỉ Swift). Mỗi API có đặc điểm riêng về hiệu suất, định dạng và khả năng tương thích với Unified Logging System.
NSLog là một hàm từ Foundation, có sẵn trong Objective-C và Swift. NSLog xuất thông báo với dấu thời gian, tên tiến trình và PID. Nhược điểm: NSLog ghi vào bộ đệm hệ thống một cách đồng bộ, chặn luồng hiện tại trong khi ghi. Với các lệnh gọi thường xuyên (ví dụ, trong vòng lặp), NSLog tạo ra độ trễ đáng kể. Apple không khuyến nghị NSLog cho các dự án mới, nhưng nó vẫn tương thích với mã kế thừa và thư viện bên thứ ba.
os_log là API từ os.framework, được giới thiệu trong iOS 10. os_log không đồng bộ: thông báo được xếp hàng đợi và ghi vào bộ đệm mà không chặn luồng gọi. Theo WWDC 2016, os_log nhanh hơn 50 lần so với NSLog trong các kịch bản tải cao. os_log cũng hỗ trợ điều khiển động: các thông báo ở cấp DEBUG chỉ được thu thập trong bản dựng Debug và trong Release chúng bị bỏ qua mà không tốn chi phí.
print() là phương thức xuất đơn giản nhất trong Swift. print ghi vào stdout (đầu ra chuẩn), mà Xcode chuyển hướng đến Console. print không thêm siêu dữ liệu (thời gian, cấp độ) nhưng hỗ trợ đệm stdout. Để gỡ lỗi nhanh, print là công cụ tiện lợi, nhưng để ghi nhật ký lâu dài, nó thua kém os_log về chức năng và khả năng kiểm soát.
import os.log
// NSLog — lỗi thời, chặn
NSLog("Application started")
// os_log — được khuyến nghị, bất đồng bộ
let log = OSLog(
subsystem: "com.myapp",
category: "lifecycle"
)
os_log("Application started", log: log)
// print — đầu ra Swift nhanh
print("Application started")
Unified Logging System (ULS) là cơ sở hạ tầng ghi nhật ký toàn diện của Apple, được giới thiệu trong iOS 10 và macOS Sierra. ULS thu thập thông báo từ tất cả các tiến trình hệ thống vào một kho lưu trữ duy nhất với khả năng truy cập từ xa qua công cụ dòng lệnh log trên Mac. Các nhà phát triển sử dụng os_log để ghi vào ULS và Console để đọc.
Mỗi OSLog được xác định bởi một cặp subsystem (ví dụ: com.myapp.network) và category (ví dụ: http, websocket). Hệ thống con là miền ứng dụng (một ứng dụng có thể có nhiều hệ thống con cho các mô-đun khác nhau). Danh mục là một thành phần trong hệ thống con. Sự kết hợp subsystem + category cho phép lọc nhật ký linh hoạt trong Console và log collect.
| Cấp độ | OSLogType | Hiển thị trong Console | Thu thập trong Release |
|---|---|---|---|
| Default | .default | Luôn luôn | Có |
| Info | .info | Khi bật giao diện os_log | Có |
| Debug | .debug | Chỉ trong bản dựng Debug | Không |
| Error | .error | Luôn có nhãn đỏ | Có |
| Fault | .fault | Luôn có nhãn tím | Có |
Lệnh log collect trên Mac thu thập các nhật ký đã lưu trữ từ thiết bị iOS được kết nối vào một tệp .logarchive. Tệp này có thể được mở trong Console.app trên Mac để phân tích chi tiết, bao gồm thông báo os_log, nhật ký sự cố và chẩn đoán hệ thống. Để bật thu thập trên thiết bị, bạn cần bật Chế độ nhà phát triển và kết nối thiết bị qua USB.
Công việc thực tế với Console bao gồm ba kịch bản chính: ghi nhật ký chủ động trong quá trình phát triển, phân tích nhật ký sự cố sau khi gặp sự cố và chẩn đoán từ xa qua .logarchive. Mỗi kịch bản có một bộ công cụ và cài đặt tối ưu.
Khuyến nghị tạo một OSLog riêng cho mỗi mô-đun ứng dụng với các cấp độ: debug (gỡ lỗi chi tiết), info (chuyển đổi trạng thái chính), error (ngoại lệ và lỗi). Trong Console Xcode, hãy bật bộ lọc theo hệ thống con của ứng dụng để loại trừ các thông báo hệ thống gây nhiễu và phân tán khỏi logic ứng dụng.
Khi ứng dụng gặp sự cố, Xcode tự động dừng thực thi và hiển thị luồng nơi xảy ra sự cố, với dấu vết ngăn xếp đầy đủ trong Console. Dòng đầu tiên của nhật ký sự cố chứa loại ngoại lệ (NSException, EXC_BAD_ACCESS) và lý do. Nghiên cứu dấu vết ngăn xếp từ dưới lên trên: phương thức được gọi cuối cùng là vị trí sự cố. Đối với các địa chỉ đã mã hóa (trong Release), cần symbolication qua dSYM.
// Ví dụ cấu hình mô-đun OSLog
extension OSLog {
static let uiLifecycle = OSLog(
subsystem: "com.myapp.ui",
category: "lifecycle"
)
static let network = OSLog(
subsystem: "com.myapp.network",
category: "http"
)
static let database = OSLog(
subsystem: "com.myapp.data",
category: "core-data"
)
}
// Sử dụng với các cấp độ
os_log("View did load", log: .uiLifecycle, type: .debug)
os_log("HTTP 200 received", log: .network, type: .info)
os_log("Failed to save: \(error.localizedDescription)",
log: .database, type: .error)
Console Xcode hỗ trợ một số tính năng nâng cao vượt ra ngoài việc ghi nhật ký đơn giản. Nhật ký breakpoint cho phép xuất thông báo ra Console mà không dừng thực thi và các lệnh LLDB trong Debugger Command cung cấp khả năng kiểm soát hoàn toàn định dạng đầu ra.
Bạn có thể cấu hình breakpoint để xuất thông báo ra Console và tự động tiếp tục thực thi. Đặt breakpoint trên dòng mong muốn, nhấp chuột phải → Edit Breakpoint → thêm Debugger Command: “po self” hoặc “expr @import UIKit” + Debugger Command: “po self.view”. Chọn Automatically continue after evaluating. Sau khi khởi chạy, breakpoint sẽ xuất kết quả lệnh ra Console mỗi khi dòng đó được truy cập mà không làm gián đoạn luồng.
Console Xcode hỗ trợ thực thi các lệnh LLDB tùy ý khi dừng tại breakpoint. po (print object) xuất mô tả đối tượng, p (print) xuất giá trị nguyên thủy và expr thực thi biểu thức Swift/ObjC. Để xuất có định dạng, sử dụng p/CGRectGetWidth. Đầu ra LLDB xuất hiện trong Console ngay sau khi đạt được breakpoint.
func processUserData(user: User) {
// Breakpoint tại đây với Debugger Command:
// po "User name: \(user.name)"
// expr user.age = 30
print("Processing user: \(user.name)")
}
// Ví dụ ghi nhật ký tùy chỉnh với trình tự
func trackMethodCall(
file: String = #file,
function: String = #function
) {
os_log("[\(function)] called",
log: .uiLifecycle, type: .debug)
}
Console Xcode được tích hợp chặt chẽ với Instruments — công cụ hồ sơ của Xcode. Khi chạy ứng dụng qua Product → Profile với mẫu Logging, tất cả thông báo os_log được ghi lại trong dấu vết Instruments với dấu thời gian. Điều này cho phép bạn xem đồng thời nhật ký, hiệu suất và sự kiện hệ thống trên một dòng thời gian duy nhất, điều quan trọng để chẩn đoán các điều kiện cạnh tranh và suy giảm hiệu suất.
Câu hỏi thường gặp
NSLog đồng bộ, chặn luồng và luôn xuất thông báo. os_log không đồng bộ, nhanh hơn 50 lần trong các kịch bản tải cao, hỗ trợ danh mục và tự động tắt các cấp độ gỡ lỗi trong bản dựng Release mà không giảm hiệu suất.
Kiểm tra cấp độ ghi nhật ký: theo mặc định, Console chỉ hiển thị default trở lên. Để xem info và debug, hãy mở menu os_log trong Console Xcode và chọn Include Info Messages và Include Debug Messages trong cài đặt lược đồ (Edit Scheme → Run → Arguments → OS_ACTIVITY_MODE = debug).
Chọn các thông báo mong muốn trong Console, sao chép (Cmd + C) và dán vào bất kỳ trình soạn thảo văn bản nào. Để có bản sao đầy đủ, hãy sử dụng lệnh terminal: sudo log collect --device --output /tmp/app_logs.logarchive — lệnh này lưu tất cả nhật ký từ thiết bị iOS ở định dạng có cấu trúc.
os_log loại .default và .error hoạt động trong Release theo mặc định. Đối với .info và .debug trong Release, bạn cần thêm đối số khởi chạy -OSLogPreferencesApp “$(PRODUCT_BUNDLE_IDENTIFIER):debug” trong lược đồ Xcode. Nếu không có đối số này, các thông báo gỡ lỗi sẽ không được thu thập trong Release, tiết kiệm tài nguyên thiết bị.
Mở Window → Organizer → Crashes trong Xcode. Trình tổ chức hiển thị tất cả nhật ký sự cố được thu thập từ thiết bị của người kiểm thử, được nhóm theo loại ngoại lệ. Symbolication yêu cầu tệp .dSYM từ bản dựng nơi xảy ra sự cố — Xcode tự động tìm thấy nó nếu có sẵn tệp lưu trữ.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm