الكونسول في Xcode هو أداة تصحيح أخطاء لتطوير iOS تعرض مخرجات NSLog و print و os_log وسجلات أعطال التطبيق في الوقت الفعلي. وفقًا لـ Apple Unified Logging، بدءًا من iOS 10 توصي Apple باستخدام os_log بدلاً من NSLog للتجميع المركزي للرسائل عبر Unified Logging System. الكونسول يدمج مخرجات المصحح ورسائل النظام في نافذة Debug Area واحدة، يمكن الوصول إليها في أي لحظة من التطوير.
الملخص
الكونسول هو جزء من Debug Area في Xcode، يقع في اللوحة السفلية للمحرر (View → Debug Area → Activate Console، الاختصار Cmd + Shift + Y). يعرض الكونسول كل المخرجات النصية من التطبيق قيد التشغيل: رسائل من NSLog و os_log و print وتحذيرات وقت التشغيل وتفريغات الاستثناءات التلقائية عند تعطل التطبيق.
الكونسول يعمل في كل من المحاكي والجهاز الفعلي. في المحاكي، تصل الرسائل فورًا عبر أنبوب محلي؛ على الجهاز، تصل عبر اتصال USB بتأخير 1–3 إطار. لتطبيقات الإنتاج، الكونسول على الجهاز غير متاح — يعتمد المطورون على Crashlytics أو Unified Logging مع التجميع عن بُعد عبر log collect.
على عكس تطبيق النظام Console.app على Mac، نافذة الكونسول في Xcode تظهر فقط سجلات التطبيق الحالي قيد التشغيل (مع إمكانية التصفية). Console.app يجمع سجلات جميع العمليات على Mac، بما في ذلك محاكيات iOS. ومع ذلك، لتصحيح أخطاء تطبيقات iOS، يستخدم المطورون الكونسول المدمج في Xcode بسبب تكامله مع مصحح LLDB.
ثلاثة API رئيسية متاحة لمطور iOS للإخراج في الكونسول: NSLog (قديم)، os_log (موصى به)، و print (Swift فقط). لكل منها خصائصها من حيث الأداء والتنسيق والتوافق مع Unified Logging System.
NSLog هي دالة من Foundation، متاحة في Objective-C و Swift. NSLog تخرج رسالة مع طابع زمني واسم العملية و PID. العيوب: NSLog يكتب في مخزن النظام بشكل متزامن، مما يحجب الخيط الحالي أثناء الكتابة. مع الاستدعاءات المتكررة (مثلًا في حلقة)، يُحدث NSLog تأخيرًا ملحوظًا. Apple لا توصي باستخدام NSLog للمشاريع الجديدة، لكنه يبقى متوافقًا مع الكود القديم والمكتبات الخارجية.
os_log هي API من os.framework، تم تقديمها في iOS 10. os_log غير متزامن: يتم وضع الرسالة في قائمة انتظار وكتابتها في المخزن دون حجب الخيط المستدعي. وفقًا لـ WWDC 2016، os_log أسرع 50 مرة من NSLog في سيناريوهات الحمل العالي. os_log يدعم أيضًا التحكم الديناميكي: رسائل مستوى DEBUG تُجمع فقط في بنية Debug، وفي Release يتم تجاهلها دون أي عبء.
print() هي أبسط طريقة إخراج في Swift. print يكتب في stdout (الإخراج القياسي)، الذي يعيد Xcode توجيهه إلى الكونسول. print لا يضيف بيانات وصفية (وقت، مستوى)، لكنه يدعم التخزين المؤقت لـ stdout. للتصحيح السريع، print أداة مريحة، لكن للتسجيل الدائم فهو يقصر أمام os_log من حيث الوظائف والتحكم.
import os.log
// NSLog — قديم، حاظر
NSLog("Application started")
// os_log — موصى به، غير متزامن
let log = OSLog(
subsystem: "com.myapp",
category: "lifecycle"
)
os_log("Application started", log: log)
// print — إخراج Swift سريع
print("Application started")
Unified Logging System (ULS) هي البنية التحتية الشاملة للتسجيل من Apple، تم تقديمها في iOS 10 و macOS Sierra. ULS يجمع الرسائل من جميع عمليات النظام في مخزن واحد مع إمكانية الوصول عن بُعد عبر أداة سطر الأوامر log على Mac. يستخدم المطورون os_log للكتابة في ULS والكونسول للقراءة.
كل OSLog يتم تعريفه بواسطة زوج subsystem (مثلًا com.myapp.network) و category (مثلًا http، websocket). النظام الفرعي هو مجال التطبيق (يمكن لتطبيق واحد أن يحتوي على عدة أنظمة فرعية لوحدات مختلفة). الفئة هي مكون داخل النظام الفرعي. مجموعة subsystem + category تسمح بتصفية مرنة للسجلات في الكونسول و log collect.
| المستوى | OSLogType | العرض في الكونسول | التجميع في Release |
|---|---|---|---|
| Default | .default | دائمًا | نعم |
| Info | .info | عند تفعيل واجهة os_log | نعم |
| Debug | .debug | في بنية Debug فقط | لا |
| Error | .error | دائمًا مع علامة حمراء | نعم |
| Fault | .fault | دائمًا مع علامة بنفسجية | نعم |
أمر log collect على Mac يجمع السجلات المؤرشفة من جهاز iOS متصل في ملف .logarchive. يمكن فتح هذا الملف في Console.app على Mac لتحليل مفصل، بما في ذلك رسائل os_log وسجلات الأعطال والتشخيصات النظامية. لتفعيل التجميع على الجهاز، يجب تفعيل وضع المطور وتوصيل الجهاز عبر USB.
العمل العملي مع الكونسول يتضمن ثلاثة سيناريوهات رئيسية: التسجيل النشط أثناء التطوير، تحليل سجلات الأعطال بعد التعطل، والتشخيص عن بُعد عبر .logarchive. لكل سيناريو مجموعة مثلى من الأدوات والإعدادات.
يوصى بإنشاء OSLog منفصل لكل وحدة من التطبيق مع مستويات: debug (تصحيح مفصل)، info (انتقالات الحالة الرئيسية)، error (الاستثناءات والأعطال). في كونسول Xcode، فعّل التصفية حسب النظام الفرعي لتطبيقك لاستبعاد رسائل النظام التي تخلق ضوضاء وتشتت عن منطق التطبيق.
عند تعطل التطبيق، Xcode يوقف التنفيذ تلقائيًا ويظهر الخيط الذي حدث فيه العطل، مع stack trace كامل في الكونسول. السطر الأول من سجل العطل يحتوي على نوع الاستثناء (NSException، EXC_BAD_ACCESS) والسبب. ادرس stack trace من الأسفل إلى الأعلى: آخر دالة تم استدعاؤها هي موقع العطل. للعناوين المشفرة (في Release)، يتطلب الأمر symbolication عبر dSYM.
// مثال على التكوين المعياري لـ 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"
)
}
// الاستخدام مع المستويات
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 يدعم العديد من الميزات المتقدمة التي تتجاوز التسجيل البسيط. سجلات نقاط الإيقاف تسمح بإخراج رسائل إلى الكونسول دون إيقاف التنفيذ، وأوامر LLDB في Debugger Command تعطي تحكمًا كاملاً في تنسيق الإخراج.
يمكنك تكوين نقطة إيقاف لإخراج رسالة إلى الكونسول ومواصلة التنفيذ تلقائيًا. ضع نقطة إيقاف على السطر المطلوب، انقر بزر الماوس الأيمن → Edit Breakpoint → أضف Debugger Command: «po self» أو «expr @import UIKit» + Debugger Command: «po self.view». حدد Automatically continue after evaluating. بعد التشغيل، ستخرج نقطة الإيقاف نتيجة الأمر إلى الكونسول في كل مرة يتم الوصول إلى السطر، دون مقاطعة الخيط.
كونسول Xcode يدعم تنفيذ أوامر LLDB عشوائية أثناء التوقف عند نقطة إيقاف. po (print object) يخرج وصف الكائن، p (print) يخرج القيم البدائية، و expr ينفذ تعبيرات Swift/ObjC. للإخراج المنسق، استخدم p/CGRectGetWidth. يظهر إخراج LLDB في الكونسول فور الوصول إلى نقطة الإيقاف.
func processUserData(user: User) {
// نقطة الإيقاف هنا مع Debugger Command:
// po "User name: \(user.name)"
// expr user.age = 30
print("Processing user: \(user.name)")
}
// مثال على تسجيل مخصص مع تسلسل
func trackMethodCall(
file: String = #file,
function: String = #function
) {
os_log("[\(function)] called",
log: .uiLifecycle, type: .debug)
}
كونسول Xcode مدمج بشكل وثيق مع Instruments — أداة التنميط في Xcode. عند تشغيل التطبيق عبر Product → Profile مع قالب Logging، يتم تسجيل جميع رسائل os_log في مسار Instruments مع طوابع زمنية. هذا يسمح برؤية السجلات والأداء وأحداث النظام في آن واحد على خط زمني واحد، وهو أمر بالغ الأهمية لتشخيص حالات السباق والتراجعات في الأداء.
الأسئلة الشائعة
NSLog متزامن، يحجب الخيط ويخرج الرسالة دائمًا. os_log غير متزامن، أسرع 50 مرة في سيناريوهات الحمل العالي، يدعم الفئات ويعطل ديناميكيًا مستويات التصحيح في بنيات Release دون فقدان الأداء.
تحقق من مستوى التسجيل: افتراضيًا، الكونسول يعرض فقط default وما فوق. لعرض info و debug، افتح قائمة os_log في كونسول Xcode واختر Include Info Messages و Include Debug Messages في إعدادات المخطط (Edit Scheme → Run → Arguments → OS_ACTIVITY_MODE = debug).
حدد الرسائل المطلوبة في الكونسول، انسخها (Cmd + C) وألصقها في أي محرر نصوص. للحصول على تفريغ كامل، استخدم أمر الطرفية: sudo log collect --device --output /tmp/app_logs.logarchive — يحفظ جميع السجلات من جهاز iOS بتنسيق منظم.
os_log من نوع .default و .error يعملان في Release افتراضيًا. لـ .info و .debug في Release، تحتاج إلى إضافة وسيطة التشغيل -OSLogPreferencesApp «$(PRODUCT_BUNDLE_IDENTIFIER):debug» في مخطط Xcode. بدون هذه الوسيطة، لا تُجمع رسائل التصحيح في Release، مما يوفر موارد الجهاز.
افتح Window → Organizer → Crashes في Xcode. المنظم يعرض جميع سجلات الأعطال المجمعة من أجهزة المختبرين، مجمعة حسب نوع الاستثناء. symbolication يتطلب ملف .dSYM من البنية التي حدث فيها العطل — Xcode يجده تلقائيًا إذا كان الأرشيف متاحًا.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا