جهاز التوجيه والبيانات تمرير نظيفة سويفت الهندسة المعمارية

مرحبا القارئ!

في مقال سابق ، تحدثت عن دورة 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 مجموعات من الدلالات:

  1. طرق من تطبيق RoutingLogic (routeTo)
  2. الطرق المسؤولة عن التنقل (التنقل ، الانتقال دون Segue)
  3. طرق نقل البيانات (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
}
}


استنتاج


هذا كل شيء. شكرا لك على القراءة حتى النهاية! أدناه ، سأترك رابطًا للمشروع إذا كنت ترغب في تجربة المقالة قيد التنفيذ.

سلسلة من المقالات


  1. نظرة عامة على هندسة سويفت النظيفة
  2. تمرير البيانات والبيانات في بنية سويفت النظيفة (أنت هنا)
  3. عمال النظيفة سويفت الهندسة المعمارية
  4. اختبار وحدة في الهندسة النظيفة سويفت
  5. مثال على بنية متجر بسيط عبر الإنترنت Clean Swift

رابط للمشروع
مساعدة في كتابة مقال: باستيان

Source: https://habr.com/ru/post/ar454032/


All Articles