Az Xcode-beli Console egy hibakereső eszköz iOS-fejlesztéshez, amely valós időben jeleníti meg az NSLog, print, os_log és az alkalmazás crash logjainak kimenetét. A Apple Unified Logging szerint az iOS 10-től kezdve az Apple az os_log használatát ajánlja az NSLog helyett az üzenetek központosított gyűjtéséhez az Unified Logging System-en keresztül. Console egyesíti a debugger kimenetét és a rendszerüzeneteket egyetlen Debug Area ablakban, amely a fejlesztés bármely pillanatában elérhető.
Főbb pontok
Console — a Debug Area része az Xcode-ban, a szerkesztő alsó paneljén található (View → Debug Area → Activate Console, Cmd + Shift + Y billentyűkombináció). A Console a futó alkalmazás összes szöveges kimenetét megjeleníti: üzeneteket az NSLog, os_log, print függvényekből, futásidejű figyelmeztetéseket (runtime warnings) és automatikus kivételkiírásokat az alkalmazás összeomlásakor.
A Console működik mind a szimulátoron, mind a fizikai eszközön. A szimulátoron az üzenetek azonnal megérkeznek egy helyi pipe-on keresztül, az eszközön — USB-kapcsolaton keresztül 1–3 képkocka késéssel. Gyártási alkalmazások esetén a Console nem érhető el az eszközön — a fejlesztő a Crashlytics-re vagy az Unified Logging-re hagyatkozik távoli gyűjtéssel a log collect segítségével.
Ellentétben a Mac-en lévő Console.app rendszeralkalmazással, az Xcode-beli Console ablak csak az aktuálisan futó alkalmazás naplóit jeleníti meg (szűrési lehetőséggel). A Console.app a Mac összes folyamatának naplóit gyűjti, beleértve az iOS szimulátorokat is. Az iOS-alkalmazások hibakereséséhez azonban a fejlesztők a beépített Xcode Console-t használják az LLDB debuggerrel való integráció miatt.
Három fő API áll az iOS-fejlesztő rendelkezésére a Console-ba való kimenethez: NSLog (elavult), os_log (ajánlott) és print (csak Swift). Mindegyiknek megvannak a maga jellemzői a teljesítmény, formázás és az Unified Logging System kompatibilitás tekintetében.
NSLog — függvény a Foundation-ből, elérhető Objective-C-ben és Swift-ben. Az NSLog időbélyeggel, folyamatnévvel és PID-del írja ki az üzenetet. Hátrányai: az NSLog szinkron módon ír a rendszer pufferébe, blokkolva az aktuális szálat az írás idejére. Gyakori hívásoknál (pl. ciklusban) az NSLog észrevehető késleltetést okoz. Az Apple nem ajánlja az NSLog-ot új projektekhez, de kompatibilis marad a régi kóddal és harmadik féltől származó könyvtárakkal.
os_log — API az os.framework-ből, bevezetve az iOS 10-ben. Az os_log aszinkron: az üzenet sorba kerül és pufferbe íródik anélkül, hogy blokkolná a hívó szálat. A WWDC 2016 szerint az os_log 50-szer gyorsabb, mint az NSLog a nagy terhelésű forgatókönyvekben. Az os_log támogatja a dinamikus kezelést is: a DEBUG szintű üzenetek csak a Debug buildben gyűlnek, Release-ben teljesítményveszteség nélkül figyelmen kívül maradnak.
print() — a legegyszerűbb kiírási módszer Swift-ben. A print a stdout-ba (szabványos kimenet) ír, amelyet az Xcode a Console-ba irányít. A print nem ad hozzá metaadatokat (idő, szint), de támogatja a stdout pufferelést. Gyors hibakereséshez a print kényelmes eszköz, de állandó naplózáshoz funkcionalitás és vezérlés tekintetében elmarad az os_log mögött.
import os.log
// NSLog — elavult, blokkoló
NSLog("Application started")
// os_log — ajánlott, aszinkron
let log = OSLog(
subsystem: "com.myapp",
category: "lifecycle"
)
os_log("Application started", log: log)
// print — gyors Swift kiírás
print("Application started")
Unified Logging System (ULS) — az Apple átfogó naplózási infrastruktúrája, bevezetve az iOS 10-ben és a macOS Sierra-ban. Az ULS a rendszer összes folyamatából gyűjt üzeneteket egyetlen tárolóba, távoli hozzáféréssel a Mac-en lévő log parancssori eszközön keresztül. A fejlesztő az os_log-ot használja az ULS-be íráshoz és a Console-t az olvasáshoz.
Minden OSLog egy subsystem (pl. com.myapp.network) és category (pl. http, websocket) párral azonosítható. Az alrendszer az alkalmazás domainje (egy alkalmazásnak több alrendszere is lehet különböző modulokhoz). A kategória egy komponens az alrendszeren belül. A subsystem + category kombináció lehetővé teszi a naplók rugalmas szűrését a Console-ban és a log collect-ben.
| Szint | OSLogType | Megjelenítés a Console-ban | Gyűjtés Release-ben |
|---|---|---|---|
| Default | .default | Mindig | Igen |
| Info | .info | Bekapcsolt os_log UI esetén | Igen |
| Debug | .debug | Csak Debug buildben | Nem |
| Error | .error | Mindig piros címkével | Igen |
| Fault | .fault | Mindig lila címkével | Igen |
A log collect parancs a Mac-en archivált naplókat gyűjt a csatlakoztatott iOS-eszközről egy .logarchive fájlba. Ez a fájl megnyitható a Mac-en lévő Console.app-ban részletes elemzéshez, beleértve az os_log üzeneteket, crash logokat és rendszerdiagnosztikát. Az eszközön történő gyűjtés engedélyezéséhez be kell kapcsolni a Developer Mode-ot és USB-n keresztül csatlakoztatni az eszközt.
Gyakorlati munka a Console-lal három fő forgatókönyvet foglal magában: aktív naplózás fejlesztés közben, crash logok elemzése összeomlás után és távoli diagnosztika .logarchive-on keresztül. Minden forgatókönyvhöz optimális eszköz- és beállításkészlet tartozik.
Ajánlott külön OSLog-ot létrehozni az alkalmazás minden moduljához a következő szintekkel: debug (részletes hibakeresés), info (kulcsfontosságú állapotátmenetek), error (kivételek és meghibásodások). Az Xcode Console-ban kapcsolja be a szűrőt az alkalmazás alrendszere szerint, hogy kizárja a rendszerüzeneteket, amelyek zajt keltenek és elvonják a figyelmet az alkalmazás logikájától.
Az alkalmazás összeomlásakor az Xcode automatikusan leállítja a végrehajtást és megjeleníti a szálat, ahol az összeomlás történt, teljes stack trace-szel a Console-ban. A crash log első sora tartalmazza a kivétel típusát (NSException, EXC_BAD_ACCESS) és okát (reason). Vizsgálja meg a stack trace-t alulról felfelé: az utoljára meghívott metódus az összeomlás helye. Titkosított címek esetén (Release-ben) symbolication szükséges a dSYM-en keresztül.
// Példa moduláris OSLog konfigurációra
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"
)
}
// Használat szintekkel
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)
Xcode Console számos haladó funkciót támogat, amelyek túlmutatnak az egyszerű naplózáson. A breakpoint logok lehetővé teszik üzenetek kiírását a Console-ban a végrehajtás megállítása nélkül, az LLDB parancsok a Debugger Command-ban pedig teljes ellenőrzést biztosítanak a kimenet formázása felett.
Beállíthat egy breakpoint-ot úgy, hogy az üzenetet írjon ki a Console-ban és automatikusan folytassa a végrehajtást. Helyezzen breakpoint-ot a kívánt sorra, kattintson jobb gombbal → Edit Breakpoint → adjon hozzá Debugger Command-ot: “po self” vagy “expr @import UIKit” + Debugger Command: “po self.view”. Jelölje be az Automatically continue after evaluating lehetőséget. Elindítás után a breakpoint minden egyes sor elérésekor kiírja a parancs eredményét a Console-ban anélkül, hogy megszakítaná a szálat.
Xcode Console támogatja tetszőleges LLDB parancsok végrehajtását breakpoint-on való megálláskor. A po (print object) kiírja az objektum leírását, a p (print) — primitív értékeket, az expr — Swift/ObjC kifejezéseket hajt végre. Formázott kimenethez használja a p/CGRectGetWidth parancsot. Az LLDB kimenet azonnal megjelenik a Console-ban a breakpoint elérése után.
func processUserData(user: User) {
// Breakpoint itt Debugger Command-dal:
// po "User name: \(user.name)"
// expr user.age = 30
print("Processing user: \(user.name)")
}
// Példa egyéni naplózásra sorrenddel
func trackMethodCall(
file: String = #file,
function: String = #function
) {
os_log("[\(function)] called",
log: .uiLifecycle, type: .debug)
}
Xcode Console szorosan integrált az Instruments-szel — az Xcode profiling eszközével. Az alkalmazás Product → Profile menüponton keresztül, Logging sablonnal történő indításakor az összes os_log üzenet időbélyegekkel kerül rögzítésre az Instruments nyomvonalában. Ez lehetővé teszi a naplók, teljesítmény és rendszeresemények egyidejű megtekintését egy időskálán, ami kritikus a race condition és a teljesítményregresszió diagnosztizálásához.
Gyakran Ismételt Kérdések
NSLog — szinkron, blokkolja a szálat és mindig kiírja az üzenetet. Az os_log — aszinkron, 50-szer gyorsabb nagy terhelésű forgatókönyvekben, támogatja a kategóriákat és a debug szintek dinamikus kikapcsolását Release buildben teljesítményveszteség nélkül.
Ellenőrizze a naplózási szintet: alapértelmezetten a Console csak a default és afölötti szinteket jeleníti meg. Az info és debug megtekintéséhez nyissa meg az os_log menüt az Xcode Console-ban, és válassza az Include Info Messages és Include Debug Messages lehetőséget, valamint a séma beállításaiban (Edit Scheme → Run → Arguments → OS_ACTIVITY_MODE = debug).
Jelölje ki a kívánt üzeneteket a Console-ban, másolja ki (Cmd + C), és illessze be bármely szövegszerkesztőbe. Teljes dump-hoz használja a terminálparancsot: sudo log collect --device --output /tmp/app_logs.logarchive — ez az iOS-eszköz összes naplóját strukturált formátumban menti el.
Az os_log .default és .error típusai alapértelmezetten működnek Release-ben. A .info és .debug Release-ben történő használatához hozzá kell adni a -OSLogPreferencesApp “$(PRODUCT_BUNDLE_IDENTIFIER):debug” indítási argumentumot az Xcode sémához. Ezen argumentum nélkül a debug üzenetek nem gyűlnek Release-ben, ami eszköz erőforrásokat takarít meg.
Nyissa meg a Window → Organizer → Crashes menüpontot az Xcode-ban. A szervező az összes, a tesztelők eszközeiről gyűjtött crash log-ot mutatja, kivétel típus szerint csoportosítva. A symbolication-hez szükség van a .dSYM fájlra abból a buildből, amelyben az összeomlás történt — az Xcode automatikusan megtalálja, ha az archívum elérhető.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is