مرحبا القارئ!
في مقال
سابق ، تحدثت عن دورة
VIP لهندسة
Clean Swift . الآن سنتطرق إلى أحد أهم الموضوعات -
نقل ونقل البيانات بين المشاهد.

نظرية
مكون
جهاز التوجيه مسؤول عن منطق التنقل ونقل البيانات ، والذي يعد جزءًا من المشهد (اختياري بالطبع). تتم تهيئة في
ViewController ، جنبا إلى جنب مع
Interactor والمقدم .
يقوم جهاز التوجيه بتنفيذ بروتوكولين -
RoutingLogic و
DataPassing ، والذي
سنملؤه بوظائفنا . يجب أن يحتوي
RoutingLogic على الأساليب المسؤولة عن الانتقال إلى مشهد معين.
DataPassing يحتوي على متغير
dataStore ، والذي يشير إلى بروتوكول
DataStore .
تقوم Interactor Scenes بتنفيذ بروتوكول
DataStore وتعمل مع المتغيرات المخزنة فيه. يحتوي
جهاز التوجيه نفسه على ارتباط إلى
ViewController من المشهد الخاص به.
باستخدام الرابط إلى
ViewController ، ينتقل
جهاز التوجيه بين المشاهد. للقيام بذلك ، يمكنك استخدام
Segue أو إنشاء مشهد تريد إجراء عملية نقل برمجيًا إليه. الطريقة التي يتم استخدامها ليست مهمة ، والشيء الرئيسي بالنسبة لنا هو وجود رابط لمثيل فئة
ViewController الذي
نتحول إليه.
باستخدام الرابط إلى
DataStore ،
سننقل البيانات من
Interactor لمشهد واحد إلى
Interactor للمشهد الذي ننتقل إليه. وكما ذكرنا سابقًا ، فإن
جهاز التوجيه هو
الذي يحتاج إلى معرفة كيفية القيام بذلك.
ممارسة
على سبيل المثال ، سننقل النص من TextField إلى Label للمشهد الآخر. دعنا نفكر في طريقتين للانتقال بين المشاهد - وفقًا لـ
Segue وبرمجيًا .
تحتوي فئة
جهاز التوجيه على 3 مجموعات من الدلالات:
- طرق من تطبيق RoutingLogic (routeTo)
- الطرق المسؤولة عن التنقل (التنقل ، الانتقال دون Segue)
- طرق نقل البيانات (passDataTo ، إذا كان هناك بيانات لنقل)

إذا نجحنا في الانتقال عبر
Segue ، على سبيل المثال ، عند النقر فوق زر ، فيجب أن
نتجاوز في
ViewController طريقة التحضير (لـ: المرسل :). سيتيح لك هذا الامتداد الاتصال بالطرق تلقائيًا من
جهاز التوجيه باسم
Segue .
إعداد Overriding (لـ: المرسل :) اختياري عند العمل مع Segue. يمكنك استبعادها من الكود واستدعاء performSegue (withIdentifier: sender :) في طريقة Router . هناك حاجة إلى إعداد فقط إذا كنت بحاجة إلى استخدام Segue جنبا إلى جنب مع نقل البيانات. | final class HomeViewController: UIViewController { |
| // ... |
| |
| override func prepare(for segue: UIStoryboardSegue, sender: Any?) { |
| // Segue |
| if let scene = segue.identifier { |
| |
| // , Router |
| // router?.routeToNAME(segue:) |
| let selector = NSSelectorFromString("routeTo\(scene)WithSegue:") |
| |
| // , |
| // Segue |
| if let router = router, router.responds(to: selector) { |
| router.perform(selector, with: segue) |
| } |
| } |
| } |
| |
| // ... |
| } |
الآن نأتي في النهاية إلى الشيء الأكثر إثارة للاهتمام - رمز
جهاز التوجيه . يحتوي المثال على تعليقات ، لذلك سننظر فقط في النقاط الرئيسية.
في هذا
الموجه ، نعمل مع مشهدين -
الصفحة الرئيسية والتفاصيل . تتم معالجة الانتقال من المشهد الرئيسي بطريقتين - بواسطة
Segue وبرمجيًا . يتم نقل البيانات من المشهد الرئيسي إلى مشهد
التفاصيل .
يجب تسمية جميع الطرق في بروتوكول
RoutingLogic وفقًا لمبدأ
routeToNAME ، حيث
NAME هو اسم
Segue (المعرّف) الذي
نحدده عند العمل مع
Storyboard . يعد هذا ضروريًا ليس فقط من أجل راحة وجمال الاستخدام ، ولكن أيضًا من أجل محدد الأسلوب الخاص بنا في
الإعداد (لـ: المرسل :) ViewController ، والذي قمنا بإعادة تعريفه مسبقًا.
أيضا في فئة
HomeRouter هناك طرق تبدأ من
navigateTo و
passDataTo . الأولى مسؤولة عن منطق الانتقال ، في حين أن الأخيرة مسؤولة عن نقل البيانات. يتم إنشاء أساليب navigateTo فقط إذا تم الانتقال برمجيًا.
في المثال ، لدينا
routeToDetail ( طريقة
:) :) . المعلمة
segue اختيارية منذ تحتوي الطريقة على تطبيق يتيح لك الاتصال به دون استخدام
Segue . في كلتا الحالتين الانتقالية ، نحصل على قيم غير اختيارية
لمشهد HomeViewController و
HomeDataStore'a Home ، بالإضافة إلى روابط إلى
ViewController ومشهد DataStore Detail . هنا يجدر الانتباه إلى حقيقة أن
detailDS متغير ويتم تمريره إلى طريقة
passDataToDetail باستخدام المعلمة
pass-through (inout). هذا مهم لأنه بدون
inout ، سيكون علينا وضع علامة على جميع بروتوكولات
DataStore على أنها "ممكنة للتنفيذ فقط مع الفئات" (البروتوكول DetailDataStore: class) ، وهذا يستلزم العديد من الصعوبات ، بما في ذلك التقاط روابط قوية.
| |
| import UIKit |
| |
| /// @objc |
| /// prepare View Controller'e |
| @objc protocol HomeRoutingLogic { |
| /// Detail View Controller |
| func routeToDetail(segue: UIStoryboardSegue?) |
| } |
| |
| protocol HomeDataPassing { |
| var dataStore: HomeDataStore? { get } |
| } |
| |
| final class HomeRouter: NSObject, HomeRoutingLogic, HomeDataPassing { |
| |
| // MARK: - Private |
| |
| // MARK: - Public |
| |
| weak var viewController: HomeViewController? |
| var dataStore: HomeDataStore? |
| |
| // MARK: - HomeRoutingLogic |
| |
| func routeToDetail(segue: UIStoryboardSegue?) { |
| if let segue = segue { |
| // |
| // Segue |
| |
| // Detail View Controller |
| // Data Store Router'e |
| guard |
| let homeDS = dataStore, |
| let detailVC = segue.destination as? DetailViewController, |
| var detailDS = detailVC.router?.dataStore |
| else { fatalError("Fail route to detail") } |
| |
| // , , , |
| // "" |
| passDataToDetail(source: homeDS, destination: &detailDS) |
| } else { |
| // , |
| // Segue |
| |
| // Detail View Controller Storyboard'a |
| // Data Store Router'e |
| guard |
| let viewController = viewController, |
| let homeDS = dataStore, |
| let storyboard = viewController.storyboard, |
| let detailVC = storyboard.instantiateViewController(withIdentifier: "Detail") as? DetailViewController, |
| var detailDS = detailVC.router?.dataStore |
| else { fatalError("Fail route to detail") } |
| |
| passDataToDetail(source: homeDS, destination: &detailDS) |
| |
| // , "" |
| navigateToDetail(source: viewController, destination: detailVC) |
| } |
| } |
| |
| // MARK: - Navigation |
| |
| private func navigateToDetail(source: HomeViewController, destination: DetailViewController) { |
| source.navigationController?.pushViewController(destination, animated: true) |
| } |
| |
| // MARK: - Passing data |
| |
| /// destination inout, |
| /// Data Store |
| private func passDataToDetail(source: HomeDataStore, destination: inout DetailDataStore) { |
| |
| // HomeDataStore DetailDataStore |
| destination.message = source.message |
| } |
| } |
استنتاج
هذا كل شيء. شكرا لك على القراءة حتى النهاية! أدناه ، سأترك رابطًا للمشروع إذا كنت ترغب في تجربة المقالة قيد التنفيذ.
سلسلة من المقالات
- نظرة عامة على هندسة سويفت النظيفة
- تمرير البيانات والبيانات في بنية سويفت النظيفة (أنت هنا)
- عمال النظيفة سويفت الهندسة المعمارية
- اختبار وحدة في الهندسة النظيفة سويفت
- مثال على بنية متجر بسيط عبر الإنترنت Clean Swift
رابط للمشروعمساعدة في كتابة مقال:
باستيان