محتويات الدورة

iOS / Swift / التزامن وحدود البيانات / الدرس 8

URLSession وCodable وعقود الردود

افصل نجاح النقل وقبول HTTP وفك الترميز والتحقق من المجال قبل نشر البيانات البعيدة.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • يعبر الطلب عقودا متعددة
  • فك نموذج نقل بأنواع صريحة
  • افحص حد HTTP قبل جسم النجاح

يعبر الطلب عقودا متعددة

يعني اكتمال مهمة بيانات URLSession إنتاج النقل ردا أو خطأ، ولا يعني قبول عملية HTTP أو تطابق الجسم مع النموذج. افحص نوع الرد ورموز الحالة المقبولة قبل فك حمولة النجاح. قد يعيد الخادم جسم خطأ JSON صحيحا مع حالة فاشلة. وقد تحمل 200 بيانات معيبة أو غير صحيحة دلاليا. افصل فئات فشل النقل والبروتوكول والفك والمجال بقدر يخدم التعافي. ولا تعرضها كلها كقائمة فارغة كي يميز المستخدم الفراغ من الفشل.

فك نموذج نقل بأنواع صريحة

تستطيع Codable توليد الربط للخصائص المناسبة، لكنها لا تقرر ثوابت العمل مثل المعرّف غير الفارغ والمقاعد غير السالبة. يفك المقتطف الأول عينة مصطنعة ثم يفحص الشروط قبل العرض. يسبب غياب الحقول المطلوبة والنوع الخاطئ فشل الفك، بينما يتجاهل المفكك المولد الحقول الإضافية عادة ما لم تختَر تشددا آخر. حدّد سياسة التوافق عمدا. وافصل DTO عن نموذج المجال الأغنى عند الحاجة إلى التطبيع أو اتساق السجلات، فلا يثبت الفك كل القواعد.

swift مقتطف توضيحي من Swift أو SwiftUI؛ يتطلب بيئة الأدوات المبيّنة.
import Foundation
struct WorkshopDTO: Decodable {
    let id: String
    let seats: Int
}
enum DecodeFailure: Error { case invalidWorkshop }
func decodeWorkshop(_ data: Data) throws -> WorkshopDTO {
    let item = try JSONDecoder().decode(WorkshopDTO.self, from: data)
    guard !item.id.isEmpty, item.seats >= 0 else { throw DecodeFailure.invalidWorkshop }
    return item
}
let fixture = Data(#"{"id":"w-7","seats":3}"#.utf8)
// try decodeWorkshop(fixture).seats -> 3
الناتج المتوقع
The accepted fixture has identifier w-7 and seats 3.

يفك المثال بايتات محلية فقط، ولا يرسل طلبا أو يفرض السعة المعتمدة.

افحص حد HTTP قبل جسم النجاح

يعرض المقتطف الثاني محملا توضيحيا يستقبل URL من مستدع مراجع. يقبل حالة نجاح ضيقة ثم يستخدم المفكك السابق. وقد يسمح عقد الإنتاج بحالات متعددة أو رد بلا محتوى؛ فحدّدها بدلا من توسيع النطاق عميانا. تُحقن الجلسة لإتاحة بديل النقل. لا تُقدّم أو تُتصل أي وجهة هنا. ويحتاج التطبيق إلى سياسات المهلة والإلغاء والتوثيق والخصوصية والوجهات المسموحة عند حدودها. ولا تصل مدخلا غير موثوق بعنوان اعتباطي وتعتبره وجهة مفوضة.

swift مقتطف توضيحي من Swift أو SwiftUI؛ يتطلب بيئة الأدوات المبيّنة.
enum LoadFailure: Error { case unexpectedResponse }
func loadWorkshop(from url: URL, session: URLSession) async throws -> WorkshopDTO {
    let (data, response) = try await session.data(from: url)
    guard let http = response as? HTTPURLResponse, http.statusCode == 200 else {
        throw LoadFailure.unexpectedResponse
    }
    return try decodeWorkshop(data)
}
الناتج المتوقع
Only an HTTP 200 response with a valid workshop body becomes a model.

يتطلب Foundation والمفكك السابق. هذا مقتطف شبكة غير منفذ ولا وجهة مضبوطة له.

احفظ سياق الخطأ دون كشف الحمولات

قد يحدد DecodingError مسار الحقل والشكل المتوقع، فيساعد على موضع اختلاف المخطط. سجّل سياق حقل آمنا وإصدار النموذج بدلا من رد كامل قد يحوي بيانات شخصية. ترجم الفئات إلى رسائل مفيدة قرب العرض. لا يرجح أن تصلح إعادة البايتات المعيبة مخططا غير متوافق، بينما قد يسمح فشل نقل عابر بإعادة محدودة بحسب الخدمة. وفي الكتابة ميّز الرفض من الاكتمال غير المؤكد كي لا تكرر عملية خادم نجحت.

افصل حالة التحميل عن المحتوى المخزّن

قد يُعلّق التحديث مع بقاء بيانات صحيحة مفيدة. نمذج الحالة صراحة بدلا من محو الشاشة مع كل طلب. وعند الخطأ حدّد هل يخص التحميل الأول أم تحديث محتوى موجود. افحص هوية الطلب قبل اعتماد النجاح والخطأ؛ فقد تنتمي القيمة المفكوكة الصحيحة إلى استعلام أو حساب قديم. يثبت الفك الشكل لا الحداثة. حدّد نطاق المخزن بالهوية والملكية، وقرّر هل يبطل السجل الغائب اختيارا موجودا.

تحقّق من العينات وفئات الرد مستقلة

اختبر عينات محلية للصحيح والحقول المفقودة والنوع الخاطئ والسالب والحقول الإضافية بحسب التوافق. واختبر حد HTTP مزيفا للنجاح وحالة خطأ مع JSON ورد غير HTTP وبيانات نجاح معيبة. لا تتصل بخدمة حقيقية لفحص مفكك. تحتاج الشبكة الفعلية والشهادات والجلسات الخلفية وانتقالات الجهاز إلى تكامل مصرح مستقل. لم يحدث طلب أو تنفيذ SDK في التأليف؛ فالكتل تصف العقود المتوقعة فقط.

الأخطاء الشائعة وإصلاحها

يظهر رد خطأ JSON كمحتوى ناجح

لماذا يحدث؟
فكّت الشيفرة الجسم قبل فحص قبول HTTP.
كيف تصلحه؟
افحص نوع الرد وحالته بحسب العقد.
كيف تتجنب تكراره؟
أدرج JSON صحيحا بحالة فاشلة ضمن العينات.

تصل مقاعد سالبة مفكوكة إلى الواجهة

لماذا يحدث؟
اعتُبر فحص الشكل في Codable فحصا للمجال.
كيف تصلحه؟
افحص ثوابت النموذج بعد الفك أو داخله.
كيف تتجنب تكراره؟
اختبر JSON صحيح الصياغة خاطئ المعنى.

تكشف التشخيصات الرد كاملا

لماذا يحدث؟
جمع التسجيل محتوى أكثر مما يحتاج التشخيص.
كيف تصلحه؟
سجّل مسارات حقول وفئات فشل منقحة.
كيف تتجنب تكراره؟
راجع التسجيل بعينات حساسة مصطنعة.

اختبر فهمك

1. لماذا لا يثبت نجاح await في URLSession وجود ورشة صحيحة؟

اعرض الحل المشروح

قد يحمل الرد حالة خطأ أو شكلا مخالفا أو قيما غير صحيحة. افحص HTTP وفك النموذج المتوقع وتحقق من الثوابت قبل النشر. ثم افحص الحداثة والتفويض عند الاستخدام المؤثر.

2. هل يُحوّل seats المرمّز كنص "3" بصمت؟

اعرض الحل المشروح

فقط إذا سمح عقد الخدمة الموثق بهذا التمثيل. وإلا فارفض الاختلاف لكشف عيوب المخطط. وإذا دعم التحويل فمركزه عند حد الفك مع فحوص النطاق والغموض، لا بتحليل عارض داخل الواجهات.

أهم ما تعلمته

  • يعبر الطلب عقودا متعددة
  • تحقّق من العينات وفئات الرد مستقلة

المراجع الرسمية