Swift encode URL: لماذا يتعطل كودك مع الأحرف السيريلية والمسافات
كل مطور أرسل طلب شبكة في Swift مرة واحدة على الأقل واجه هذه المعاناة: تقوم بتكوين URL، وتضيف المعاملات، لكن الخادم يعيد خطأ 400 أو الأسوأ من ذلك - يتجاهل الطلب بصمت. هل هذا مألوف؟ غالبًا ما تكمن المشكلة في ترميز URL غير الصحيح. قد يبدو الأمر بسيطًا - خذ سلسلة نصية، واستبدل المسافات بـ %20، وانتهى الأمر. لكن Swift (مثل أي لغة صارمة) لا يتسامح مع التسرع.
في هذه المقالة، سنستعرض أكثر 5 أخطاء شيوعًا عند Swift encode URL والتي تجمع آلاف المشاهدات على Stack Overflow. ستتعلم كيفية تجنبها وكتابة كود موثوق يعمل مع أي بيانات - من الحروف الإنجليزية إلى الأحرف السيريلية المعقدة والرموز الخاصة.
الخطأ رقم 1: استخدام addingPercentEncoding مع مجموعة أحرف غير صحيحة
هذا هو الفخ الأكثر شيوعًا. يرى العديد من المبتدئين طريقة addingPercentEncoding(withAllowedCharacters:) ويفكرون: "أوه، مثالية!". لكنهم يمررون لها .urlHostAllowed أو .urlPathAllowed لكامل URL. النتيجة - تعطل أو طلب غير صحيح.
لماذا لا يعمل هذا؟
كل جزء من URL (المخطط، المضيف، المسار، معاملات الاستعلام) له مجموعة أحرف مسموح بها خاصة به. إذا قمت بترميز URL بالكامل كمضيف، ستفقد الشرطات المائلة والنقطتين الرأسيتين. إذا قمت بترميزه كمسار، ستعطل سلسلة الاستعلام.
// ❌ خطأ: ترميز URL بالكامل كمضيفlet urlString = "https://example.com/مسار?name=إيفان & لقب=بيتروف"let encoded = urlString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)// النتيجة: "https%3A%2F%2Fexample.com%2F%D9%85%D8%B3%D8%A7%D8%B1%3Fname%3D%D8%A5%D9%8A%D9%81%D8%A7%D9%86%20%26%20%D9%84%D9%82%D8%A8%3D%D8%A8%D9%8A%D8%AA%D8%B1%D9%88%D9%81"// الخادم لن يفهم هذا URLتذكر القاعدة الذهبية: قم بترميز كل جزء من URL بشكل منفصل أو استخدم URLComponents.
النهج الصحيح: URLComponents
// ✅ صحيح: استخدام URLComponentsvar components = URLComponents()components.scheme = "https"components.host = "example.com"components.path = "/مسار"components.queryItems = [ URLQueryItem(name: "name", value: "إيفان & بيتروف"), URLQueryItem(name: "لقب", value: "إيفانوف")]
if let url = components.url { print(url.absoluteString) // "https://example.com/%D9%85%D8%B3%D8%A7%D8%B1?name=%D8%A5%D9%8A%D9%81%D8%A7%D9%86%20%26%20%D8%A8%D9%8A%D8%AA%D8%B1%D9%88%D9%81&%D9%84%D9%82%D8%A8=%D8%A5%D9%8A%D9%81%D8%A7%D9%86%D9%88%D9%81"}URLComponents يطبق تلقائيًا percent encoding الصحيح لكل مكون. هذا يريحك من الصداع ويجعل الكود أنظف.
الخطأ رقم 2: تجاهل queryItems لصالح التجميع اليدوي للسلسلة النصية
"لماذا أحتاج هذه المكونات؟ سألصق السلسلة النصية باستخدام +". فكرة مألوفة؟ وهذا يؤدي إلى الخطأ الشائع الثاني. التجميع اليدوي لسلسلة الاستعلام هو طريق مباشر للأخطاء.
// ❌ خطأ: تجميع يدوي لسلسلة الاستعلامlet name = "إيفان & بيتروف"let query = "name=\\(name)&age=25"let urlString = "https://example.com?\\(query)"// المشكلة: علامة العطف في الاسم ستُعتبر فاصلًا للمعاملاتحتى لو استبدلت المسافات، ستنسى & و # و ? والرموز الخاصة الأخرى. وإذا جاء المعامل من المستخدم؟ توقع الاختراقات والطلبات المعطلة.
الحل: استخدم دائمًا queryItems
// ✅ صحيح: queryItems يقوم بكل العمل نيابة عنكvar components = URLComponents(string: "https://example.com")!components.queryItems = [ URLQueryItem(name: "name", value: "إيفان & بيتروف"), URLQueryItem(name: "age", value: "25"), URLQueryItem(name: "q", value: "Swift encode URL tutorial")]
if let url = components.url { print(url.absoluteString) // "https://example.com?name=%D8%A5%D9%8A%D9%81%D8%A7%D9%86%20%26%20%D8%A8%D9%8A%D8%AA%D8%B1%D9%88%D9%81&age=25&q=Swift%20encode%20URL%20tutorial"}