<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های shafi.ee</title><link>https://virgool.ir/feed/@shafi.ee</link><description></description><language>fa</language><pubDate>2026-11-11 22:05:18</pubDate><image><url>https://files.virgool.ir/upload/users/25713/avatar/TWQy3N.png</url><title>shafi.ee</title><link>https://virgool.ir/@shafi.ee</link></image><item><title>UITableView+UISearchBar</title><link>https://virgool.ir/@shafi.ee/uitableviewuisearchbar-vbf6prgnv5id</link><description>UITableView + UISearchBarاگر تا اینجا مقاله‌های قبلی رو دنبال کرده باشید دیگه می‌دونید که چه طوری میشه یه tableView ساده رو با RxSwift پیاده سازی کردش و یا اینکه اگر tableView مون چند section مختلف داشت و یا از چند نوع cell تشکیل شده بود چه طوری باید اون رو پیاده سازی کردش. اما تا الان این طوری بوده که ما tableView مون رو به یه datasource وصل کرده بودیم و از اون می‌خوندیم که حالا یا ثابت بود یا از دیتابیس، وب سرویس و یا ... اما اگر بخواییم از چندجا این اطلاعات رو دریافت کنیم و بخونیم چی؟ مثلا فرض کنید یه table داریم از اسامی استان‌های ایران که بالاش هم یه searchBar هستش و وقتی کاربر اسم استانی رو جستجو کردش اسم اون شهرهای فیلتر شده بیاد نه همه شهرها و وقتی هم اسمش رو پاک کرد همه شهرها! یعنی tableView بتونی بین این دو تا datasource تغییر کنه.یعنی دو تا datasource داشته باشیم؟!مثلا فرض کنید ما یه آرایه داریم که tableView مون اون رو نمایش میده و بعدی ما یه searchBar داریم که وقتی چیزی کاربر type کردش اون اطلاعات رو فیلتر کنه و نمایش بده، بالفرض یه لیستی از اسامی شهرها داریم و وقتی کاربر تایپ میکنه &#34;کرم&#34; توی لیست نتایج باید اسم شهرهای کرمان و کرمانشاه رو نشون بده! خوب توضیح بسته و بریم سراغ کدها اما قبلش نیاز هستش با چندتا Operator آشنا بشید.آشنایی با Operator ها:راستش به نظر خودم بعضی مفاهیم رو هرچقدر هم ترجمه بشه اما باز مثل خوندن منابع اصلی نمیشه برای همین برای اشنایی با operator ها اول تعریف کتاب raywenderlich رو بخونیم:Operators are the building blocks of Rx, which you can use to transform, process, and react to events emitted by observables. Just as you can combine simple arithmetic operators like +, -, and / to create complex math expressions, you can chain and compose together Rx&#39;s simple operators to express complex app logic.پس Operator ها سازنده قسمت‌هایی در Rx هستن که، توسط اون‌ها شما می‌تونید انتقال بدید، پردازش کنید، و یا واکنشی نسبت به اتفاق افتادن یک روی داد توسط observable ها رو نشون بدید. همون طوری که شما می‌تونید با ترکیب کردن عملگرهای ساده ای مثل جمع و تفریق و ضرب و ... یک عبارت پیچیده بسازید، می‌تونید با کنارهم قرار دادن این Operator ها عملکردهای پیشرفته ای رو بسازید.آشنایی با اپراتور combineLatest :یکی از پرکاربردترین operatorها combineLatest هستش که وظیفه اش این هستش که مقادیری رو که sequence های مختلف از خودشون منتشر می‌کنند رو باهم دیگه یکی کنه. ( مشاهده دیاگرام اصلی ) combineLatest operatorتمامی operator ها تو Rx همچین نموداری رو برای خودشون دارن که بهش می‌گن RxMarables Diagrams (برای اطلاعات بیشتر اینجا رو ببینید) که خط های فلش دار تایم لاین ایجاد داده روی هر sequence رو نشون میدن و خط عمودی قبل از فلش لحظه تموم شدن اون sequence رو. مثلا توی این نمودار روی خط زمانی اول مقدار ۱ ایجاد میشه بعدش مقدار ۴ روی خط زمانی دوم ایجاد میشه و بعد ۵ روی خط زمانی دوم و بعدش ۲ روی خط زمانی اول و ... خوب حالا فرض کنید ما بخوایم یه جایی رو داشته باشیم که به اتفاقات هر دو جریان زمانی گوش بدیم و مقادیر ایجاد شده رو به صورت هم زمان در هر لحظه داشته باشیم! اینجا جایی هستش که combinLatest به کمک مون میادش که خط زمانی سوم رو برامون به وجود میاره، که توی هر لحظه ای که خط زمانی اول یا دوم مقداری رو ایجاد کنه توی اون لحظه اخرین مقدار هر دو رو بهمون میده و ما بر حسب نیاز می‌تونیم عملیات مورد نظرمون رو روی اون اطلاعات انجام بدیم.ایول این همون چیزیه که برای سرچ میخواستیم!چون قسمت‌های پیاده سازی خود tableView رو توی مقالات قبل گفتم دیگه اینجا فاکتور میگیرم ازش و میرم سر اصل ماجرا. اول از همه میام searchBar ای رو که اماده کردیم رو مقدارش رو به روش Rx ای گوش میدیم تا از تغییراتش مطلع بشیم:searchBar text sequenceخوب اینجا ما اومدیم گفتیم مقدار text که توی searchBar وارد شده رو اگر خالی نیست زمانی که تغییر پیدا کردش بهمون بده. به این شکل متغییر query ما جریان تغییرات متن searchBar رو، توی خودش نگه می‌داره.آشنایی با اپراتور distinctUntilChanged:کار این operator این هستش که از ایجاد مقادیر تکراری جلوگیری می‌کنه، و زمانی مقدار جدید emit میشه که، مقدار تولید شده تکراری نباشه وگرنه جلوی emit شدن رو می‌گیره:همون طوری که می‌بینید مقدار ۱ تولید شد، مقدار دو هم تولید شد اما بار دومی که مقدار ۲ تولید شد جلوش گرفته شد و دوباره که مقدار ۱ تولید شد چون با مقدار قبلی متفاوت بود مقدارش emit شد.خوب حالا که ما مقدار وارد شده داخل searchBar رو به صورت observable داریم و  متغییر rows هم مقادیری رو که tableView باید نمایش بده رو به صورت observable داره، کافی هستش که اول این دوتا observable رو باهم ترکیب کنیم و بعدش نتیجه رو به tableView مون bind کنیم، این طوری tableView ما همیشه یا لیست کل شهرها رو نشون میده یا شهرهایی رو که کاربر داره سرچ میکنه رو!خوب همون طوری که از کد هم معلومه ما نتیجه ترکیب شدن دو تا observable رو bind کردیم به tableView مون و اونجا هم cell مون رو مقدار دهی کردیم، اما یه قسمتی رو که توضیح ندادیم تابع filteredCities هستش، وقتی ما دوتا observable رو با combineLatest ترکیب می‌کنیم، داخل closure ای که داریم مقادیر اون ها رو در اختیار داریم و خروجی مون آرایه ای از جنس CityModel هستش که توسط تابع filteredCities به وجود میادش، این تابع میادش، هم شهر تایپ شده رو میگیره و هم لیست کل شهرها رو، و چک میکنه شهری با اون نام داریم یا نه؛ اگر داشتیم یه آرایه ای از اونها رو بر‌می‌گردونه و اگرم نداشتیم ارایه اصلی که لیست کل شهرها هست رو بر‌میگردونه.filteredCities functionبا این حساب ما روی کلیه‌ی تغییراتی که برای searchBar اتفاق می‌یوفته تسلط داریم و هندلشون می‌کنیم اینکه اگر مقدار جدید وارد شه، مقدارش تغییر کنه، کلا مقدارش رو پاک کنه کاربر و ... .همش همین؟!خوب به همین راحتی میشه یه tableView داشته باشیم که به یه searchBar متصل باشه! خوب حالا که با operator ها اشنا شدیم چندتا کاربرد دیگه شون هم باهم ببینیم.حالت didSelect در tableView:یکی از مواردی رو که تا الان بهش اشاره نکردم این هستش که اگر بخواییم یکی از row های tableView رو انتخاب کنیم باید چی کار کنیم توی Rx ؟ برای این کار ما می‌تونیم از دو تا دستور modelSelected و itemSelected استفاده کنیم، اولی دیتای سطری که انتخاب شده و دومی indexPath سطری که انتخاب شده رو بهمون برمیگردونه.itemSelected و modelSelectedحالا اگر بخواییم همزمان هم دیتایی که انتخاب شده رو داشته باشیم و هم indexPath سطری که انتخاب شده رو چی؟ آشنایی با اپراتور Zip:این بار به جای اینکه از combineLatest استفاده کنیم از Operator ای به اسم zip استفاده کردیم اما کاربردش چه طوری هستش، این هم میادش مثل combineLatest مقدار دو تا observable رو باهم یکی میکنه و خروجی میده به ما که RxMarbles به این شکل هستش ( مشاهده دیاگرام اصلی ):و حالا کدمون میشه به این شکل:Zip Operatorاما خوب اگر این طوری باشه فرقش با combineLatest توی چی هستش؟!تفاوت zip و  combineLatest:بیاید یه بار دیگه دیاگرام هاشون رو کنار هم بذاریم و نگاه‌شون کنیم با دقت بیشتری:combineLatest VS zipتوی اپراتور combineLatest هر کدوم از sequence ها مقداری رو emit کنه ما یه خروجی ای داریم البته بعد از اینکه هر دو sequence اولین خروجی هاشون رو دادن و در واقع یه sequence معطل emit جریان دوم نمی‌شه، توی تصویر سمت چپی ۱ تولید شده بعدش ۴ که اینجا اولین خروجی هست و بعدش ۵ که با تولیدش ما خروجی بعدی رو داریم که ۱و۵ هستش، اما توی zip وقتی هر دو sequence اولین خروجی هاشون رو دادن ما زمانی خروجی داریم که با دوباره هر دو sequence مقادیر جدیدی رو emit کنن، مثلا توی شکل سمت راست اول sunny تولید شده بعدش Lisbon که خروجی این موقع emit شد و بعدش مقدار cloudy توی جریان اول تولید شده ولی ما خروجی ای نداریم تا اینکه sequence دومی بیادش و مقدار london رو emit کنه که توی این لحظه هستش ما خروجی جدید رو میگیریم.چقدر RxSwift لذت بخشه!خوب به نظر می‌رشه هرچیزی که لازم باشه برای tableView توی RxSwift رو بدونیم رو باهم مرور کردیم و یا اگر نیاز جدید باشه می‌تونیم با چیزایی که یاد گرفتیم اون رو برطرف کنیم و راهی براش به وجود بیاریم.سورس کدهای این مقاله رو هم می‌تونید از این ادرس گیت‌هاب دانلود کنید.توی مقاله‌های بعدی سعی میکنم مباحث دیگه‌ای از RxSwift رو با هم بررسی کنیم و مرور کنیم و مطمئن باشید که هرچی بیشتر با RxSwift درگیر بشید لذت کد زدن باهاش رو بهتر لمس می‌کنید و می‌بینید که reactiev programming تا چه حد می‌تونه کمک کننده باشه و تسلط مون رو روی جریان‌های داده ای داخل برنامه بیشتر کنه.مثل همیشه خوشحال میشم که اگر نظر یا پیشنهادی داشتید در مورد مقاله، نوع کد زدن و ... رو باهام در میون بذارید، تا با هم و در کنار هم بیشتر پیشرفت کنیم.?ممنون از همراهی‌تون.امین شفیعی</description><category>shafi.ee</category><author>shafi.ee</author><pubDate>Mon, 28 Jan 2019 02:25:10 +0330</pubDate></item><item><title>UITableView + RxSwift قسمت دوم Multi Section</title><link>https://virgool.ir/@shafi.ee/uitableview-rxswift-قسمت-دوم-multi-section-pib0iwm7fvoz</link><description>UITableView Multi Section in RxSwift بعد از مقاله اول که می‌تونید از اینجا بخونیدش (اگر مقاله قبلی رو هنوز نخوندید اول پیشنهاد می‌کنم که به طور کامل بخونیدش تا با پیاده سازی عادی و ساده TableView به روش Rx آشنا بشید و بعد شروع به خوندن این مقاله کنید)، توی این مقاله می‌خوام کمی بیشتر در مورد نحوه پیاده سازی حالت‌های مختلف UITableView توسط RxSwift براتون توضیح بدم، مثل اینکه اگر چند نوع cell متفاوت داشتیم چی؟ و یا اینکه اصلا چند تا section داشتیم، این جور وقت‌ها باید چی کار کنیم؟ چون توی روش قبل می‌یومدیم آرایه DataSource امون رو به tableView مون bind میکردیم و اونجا هم items رو به کلاس cell مورد نظرمون! و جایی برای تعیین section های مختلف و یا هندل کردن سطرهای متفاوت نبودش! خوب اینجا همون جایی هستش که مفهومی به نام RxDataSource به کمکمون میادش، اما RxDataSource چی هستش؟RxDataSource چیست؟آشنایی با RxDataSourceبه طور کلی از لایبرری RxDataSource برای section بندی tableview انیمیشن های موقع update شدن tableview، حذف سطرهای tableView و ... استفاده میشه، حتی زمان‌هایی که می‌خوایید tableView تون multi cell هم باشه این RxDataSource هستش که به کمکمون میادش! خوب حالا چه طوری میشه از این RxDataSource استفاده کردش؟ اول باید اون رو به پروژه مون اضافه کنیم که این کار رو می‌تونیم از طریق pod انجام بدیم کافی هستش که pod &#39;RxDataSources&#39; رو به فایل pod مون اضافه کنیم و pod رو install کنیم.برای اینکه دوباره نخواییم همه چیز رو از اول بنویسیم از همون پروژه قبلی استفاده می‌کنیم و تکمیلش می‌کنیم و تغییرش می‌دیم جاهاییش رو که نیاز هست. اول از همه باید RxDataSources رو توی لایه viewModel مون اضافه کنیم، حالا باید یه typealias تعریف کنیم از نوع structure ای به نام SectionModel که از structure ها داخلی خود RxDataSource هستش، که اونم خودش به SectionModelType کانفرم (confirm) شده که نوع section هامون رو معلوم می‌کنه، البته راه های دیگه‌ای هم هست اما به شخصه فکر می‌کنم این طوری کدها تمیزتر و خواناتر هستن تا حالتای دیگه (در اصل همه شون یکی هستن)، پس داریم:عکس اولهمون طوری که می‌بینید SectionModel مون از دو تا enum تشکیل شده یکی TableViewSection و اون یکی tableViewItem، متاسفانه یا خوشبختانه به روش Rx ما فقط می‌تونیم یه text ساده رو برای هدر سکشن‌هامون set کنیم و اگر بخواییم یه custom view براش تعیین کنیم باید از همون delegate های قدیمی خود tableView استفاده کنیم یعنی:tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -&gt; UIView? ولی در collectionView این طوری نیست و توسط rx میشه برای header و footer هم custom view تعیین کردش؛ برای همین توی enum ای که برای section ها هستش فقط یه case تعریف کردیم از نوع string یا اگر هر section مون یه مدل خاصی از data رو نشون میده می‌تونیم به ازای هر مدلش یه case تعریف کنیم، اینش بستگی به سلیقه خودمون داره.عکس دوم - دو نوع از حالت های تعریف sectionتو مدل سمت چپ متن عنوان رو می‌تونیم موقع تعریف کردن وارد کنیم که هرچی دادیم به عنوان title داخل section هم همون رو قرار بدیم یا اینکه بیایم type سکشن tableView رو مثل مدل سمت راست تعریف کنیم و بعد خودمون هندل کنیم متنی رو که داخل section نمایش میدیم.بعد از تعریف TableViewSection نوبت به تعریف TableViewItem هستش که در واقع نوع cell هایی هستش که قرار هستش داخل tableView نمایش بدیم، که هم می‌تونیم یه مدل داخل enum case مون قرار بدیم و یا اینکه همون جا تعریف کنیم مدل case چه جوری می‌تونه باشه.حالا تنها کاری که توی لایه viewModel مون مونده این هستش که ارایه datasource که باری tableView مون هستش رو بسازیم و به view پاسش بدیم!اگر مقاله قبلی رو هنوز یادتون باشه پر کردن ارایه tableSections که حکم dataSource مون رو داره و tableView مون رو بهش bind کردیم رو می‌دونید دیگه: Set DataSource Arrayاومدیم TableViewItem هایی که لازم داشتیم رو ساختیم و بعدش داخل TableViewSectionModel ستشون کردیم و بعد این کار رو به تعداد section های مورد نیازمون تکرار کردیم و در اخری onNext متغییر tableSections مون رو call کردیم تا tableView مون که بهش bind شده خودش رو آپدیت کنهلایه View:حالا تنها کاری که باید بکنیم این هستش که dataSource ای رو که توی لایه viewModel ساختیم رو اینور مدیریت کنیم، پس اول از همه میایم یه متغییر به اسم dataSource از جنس RxTableViewSectionedReloadDataSource تعریف می‌کنیم :عکس سوم- تعریف متغیر DataSource حالاتنهاکاریکهبایدبکنیماینهستشکهdataSourceایروکهتویلایهviewModelساختیمرواینورمدیریتکنیم،پساولازهمهمیایمیهمتغییربهاسمdataSourceازجنسRxTableViewSectionedReloadDataSourceتعریفمی‌کنیم،درتعریفdataSourceپارامترهایدیگهایهموجوددارهمثلtitleForFooterInSectionاماخوبمااینجابهایندوتافقطنیازداشتیموبقیهرومقداردهینکردیم،کهحالتکلیشبهاینصورتهستش: عکس چهارمحالا باید بیایم دو تا متغییر configureCell و titleForHeaderInSection رو که توی عکس سوم برای dataSource تعریف کردیم رو پیاده سازی کنیم، هر دوی این متغییرها رو از نوع lazy تعریف کردیم تا اپمون پرفورمنس و مدیریت حافظه بهتری داشته باشه!۱- متغییر configureCell:این متغییر کارش handle کردن تایپ های مختلف cell هامون هستش، که تشخصی بده cell الانی از کدوم تایپ هست و بسازتش.عکس پنجم - configureCellخوب خط اولش که معلومه چی هست، برای جلوگیری از retainCycle این کار رو انجام دادیم و یه switch گذاشتیم که انواع enum های TableViewItem رو که توی viewModel مون تعریف کردیم رو تشخیص بدیم و هر نوعی رو بر اساس cell خودش یه تابع نوشتیم که config اش کنه و اطلاعاتش رو ست کنه، برای تفکیک پذیری بهتر و تمیزتر شدن کدها توابع رو توی یه extention داخل همین viewController نوشتیم.۲- متغیر titleForHeaderInSection:این متغییر هم کارش مدیریت و هندل کردن تایپ‌های مختلف section های tableView مون هستش که داخلش یه switch گذاشتیم تا انواع case های متغییر TableViewSection رو که توی viewModel مون تعریف کردیم رو تشخیص بده و عنوانش رو ازش بگیره، عکس دوممون اینجا به درد می‌خوره الان فکنم بهتر بتونید تشخیص بدید کدوم یکی حالت مناسب‌تر کارتون هست. حالا کافی هستش تا یه تابع به اسم setupBinding تعریف کنیم و tableView مون رو به datasource ای که ساختیم بایند کنیم تا وقتی تابع setDataSource در viewModel فراخوانی شد به صورت خودکار tableView ما ساخته بشه!عکس ششم - تابع setupBidningبر خلاف مقاله قبلی که فقط یه نوع cell داشتیم و tableView مون رو به همون یه دونه bind کردیم، اینجا tableView مون رو به datasource مون بایند می‌کنیم تا اون تشخصی بده الان tableView کدوم نوع cell رو نمایش می‌ده و اون رو config کنه برای کاربر.نکته آخر: حتما یادتون هستش که باید انواع cell هاتون رو هم برای tableView مثل همیشه register کنید دیگه ? !خوب سعی کردیم توی این مقاله و مقاله قبل انواع مختلف tableView رو به روش rx براتون توضیح بدم الان که به کدها نیگاه بکنید می‌بینید که چه تمیزتر و مرتب تر از حالتی که با delegate معمولی tableView رو پیاده سازی می‌کنیم این کار رو انجام دادیم و همه چیز تفکیک بیشتری داره و روی جریان داده‌های اپ هم کنترل بیشتری داریم. این هستش لذت برنامه نویس با RxSwift !قطعا می‌تونی ^_^سورس کدهای این مقاله رو هم می‌تونید از این آدرس گیت هاب دانلود کنید.توی مقاله بعدی سعی می‌کنم که  کمی ریز کاری های بیشتری از کار با tableView رو به روش RxSwift بگم و با چندتا از Operator های مرتبط هم آشناتون کنم، اینکه چه جوری میشه یه cell  رو انتخاب کردش یا چه طور از willDisplayCell استفاده کردش و همین طور اگر مثلا یه SearchBar هم داشته باشه tableView مون چه طوری می‌تونیم لیست فیلتر شده رو نشون بدیم و بین لیست فیلتر شده و لیست اصلی tableView مون سویچ کنه.مثل همیشه خوشحال میشم که اگر نظر یا پیشنهادی داشتید در مورد مقاله، نوع کد زدن و ... رو باهام در میون بذارید، تا با هم و در کنار هم بیشتر پیشرفت کنیم.?ممنون از همراهی‌تون.امین شفیعی</description><category>shafi.ee</category><author>shafi.ee</author><pubDate>Thu, 24 Jan 2019 18:59:39 +0330</pubDate></item><item><title>UITableView + RxSwift  قسمت اول</title><link>https://virgool.ir/@shafi.ee/uitableview-in-rxswift-part-1-tfj4dz03f1xp</link><description>RxSwiftامروز می‌خوام کمی از اطلاعاتی رو که این چند وقته یاد گرفتم رو باهاتون به اشتراک بذارم، اونم در مورد موضوع جذابی به اسم RxSwift! خوب همون طوری که می‌دونید RxSwift یک فریم ورک  Reactive Programming هستش که این امکان رو به ما میده، تا بتونیم از مزیت های این سبک برنامه نویسی توی Swift بهرمند بشیم، اگر نمی‌دونید اینهایی که گفتم چی هستن و می‌خوایید اطلاعات بیشتر و بهتری رو به زبون فارسی ازشون داشته باشید می‌تونید مقاله MVVM + RxSwift on iOS part 1 از دوست خوبم محمد زکی زاده رو مطالعه کنید.چیزی که توی ذهنم هست اینه که، توی مقالات جداگانه ای باهم المان های مختلف رو به روش Rx پیاده سازی کنیم. که توی این مقاله نحوه پیاده سازی یک TableView ساده رو به روش Rx باهم انجام می‌دیم، البته با معماری MVVM. برای همین سعی می‌کنم تا کمتر موارد پیرامونیش رو توضیح بدم و برای توضیحاتشون به مقالات جداگانه ای که هم بهتر توضیح دادن و هم مفصل تر لینک بدم چون قطعا با یک مقاله نمی‌شه همه موارد رو عنوان کرد و این تقسیم بندی می‌تونه کالکشن بهتری رو به وجود بیاره و هم اینکه وقتی یه مقاله خوبی هست بهتره به اشتراک گذاشته بشه تا دوباره نوشته بشه!روش سنتی استفاده از TableViewخوب برای پیاده سازی کردن یه TableView به روش عادی همون طوری که می‌دونید باید اول خود TableView رو یا به صورت دستی و یا از طریق StoryBoard پیاده کنیم و بعدش برای تنظیماتش بیام از توابع Delegate اش استفاده کنیم Delegate هایی مثل:UITableView Delegatesکه می‌تونه حوصله سر بر باشه و ViewController ها مون رو مدام شلوغ کنه مخصوصا توی پروژه های بزرگ، تازه اگر خوب بتونیم هندل کنیم توابع رو و تر و تمیز در بیاریم و از روش هایی که مثل این مقاله گفته استفاده کنیم، اگر این مقاله رو تا الان نخوندید حتما و حتما توصیه می‌کنم که مطالعه اش کنید Complex Table Views in iOS؛ خوب حالا توی این مورد RxSwift چه کمکی می‌تونه به ما بکنه و چیا رو ساده تر و تمیزتر کنه توی کدهامون؟پیاده سازی TableView به روش RxSwiftدر این مقاله سراغ tableView هایی میریم که یک سکشن دارن و چند سکشنی نیستن، چون هم ساده تر هستش و هم برای نقطه شروع بهتر هستن و توی مقالات بعدی میریم سراغ TableView های چند سکشنی که باید از مفهومی به نام RxDataSource استفاده بشه برای پیاده سازیشون. البته TableView های تک سکشنی اما چند نوع cell ای هم هستش که اون رو هم توی مقالات بعدی بهش میرسیم.قدم اول اضافه کردن لایبرری RxSwift هستش، که راحت ترین راهش می‌تونه اضافه کردن اون از طریق CocoaPods باشه، که با اضافه کردن دو خط زیر در فایل pod پروژه‌تون این کار رو انجام بدید: pod &#39;RxSwift&#39;,    &#39;~&gt; 4.0&#39; pod &#39;RxCocoa&#39;,    &#39;~&gt; 4.0&#39;حالا تقسیم بندی فایل های پروژه تون باید به شکل زیر باشه که در ادامه هر کدوم از فایل ها و عملکردشونرو توضیح میدم.ساختار فایل‌های پروژهتوضیحات لایه View:اول از همه باید دو تا لایبرری RxSwift و RxCocoa رو به پروژه import کنیم تا بتونیم ازشون استفاده کنیم، اما خوب این دوتا چی هستن و چه فرقی باهم دارن؟ شاید یکی از مختصرترین و بهترین توضیحاتی رو که برای تعریف این دو لایبرری میشه عنوان کردش این توضیح هستش:RxSwift is a framework for interacting with the Swift programming language, while RxCocoa is a framework that helps make Cocoa APIs used in iOS and OS X easier to use with reactive techniques.این بخشی از توضیحاتی هستش که در این مقاله از سایت raywenderlich آورده شده، در واقع RxSwift اومده خود ویژگی های زبون برنامه نویسی swift رو reactive کرده و RxCocoa اومده المان های گرافیکی و اینترفیس هایی رو که باهاش کار می‌کنیم رو روی این ساختار اورده. (Cocoa APIs)حالا ما نیاز به ۳ تا متغییر زیر داریم:همون طوری که معلوم هستش متغییر viewModel یه instante ای از لایه ViewModel مون هستش که بتونیم از توابعی که اونجا تعریف کریم استفاده کنیم، در مورد DisposeBag باید کمی بیشتر توضیح بدیم؛ در واقع برای مدیریت حافظه و جلوگیری از memory leak ما باید متغییرهایی رو که ساختیم در زمان مناسبی از حافظه آزاد کنیم تا خللی در اجرای برنامه به وجود نیاد و حافظه به درستی مدیریت بشه، و این موضوع توی reactive programming خیلی مهم هستش به خاطر نوع متغییرهایی که تعریف می‌کنیم. برای همین ما یه سبدی درست می‌کنیم و تمام متغییرهای rx ای مون رو توی اون قرار میدیم تا با dismiss شدن اون کنترلرمون تمامی اون متغییرها هم از حافظه آزاد بشن برای همین اومدیم یه متغییری به نام disposeBag رو از نوع DisposeBag تعریف کردیم. و در اخر هم rows رو تعریف کردیم که یک متغییر از نوع ارایه ای از ViewControllerModel هستش، اگر نوع های Subject ها و Variable ها رو توی RxSwift باشون اشنا نیستید و یا تفاوت هاشون رو نمی‌دونید پیشنهاد می‌کنیم این مقاله کوتاه رو بخونید، RxSwift — Subjects، اما مختصرش این هستش که این آرایه اطلاعاتی رو که قرار tableView ما با اون‌ها پر بشه رو تو خودش نگه می‌داره.حالا نوبت binding هستش یعنی در واقع ما باید بیایم اطلاعاتی رو که قرار هستش tableView مون نشون بده رو متصل کنیم بهش که به این کار اصلاحا bind کردن میگن. اول مثل همیشه cell ای رو که tableView مون ازش استفاده می‌کنه رو register  میکنیم:Register Cell حالا کافی هستش که بگیم متغییره rows ما وصل بشه به tableView مون و اونجا هندل کنیم بقیه کارها رو، برای این کار از این کد استفاده میکنیم:Bind Datasource array to tableViewاول میگیم rows باید bind بشه به tableView و بعدش به لطفا rxCocoa میام tableView مون رو هم به cell ای که براش تعریف کردیم متصل می‌کنیم و بعدش وصلش می‌کنیم به disposeBag ای که داریم. و داخل closure ای هم که داریم به cell و row و دیتایی که اون سطر براش اماده شده دسترسی داریم که اومدیم label های cell مون رو باهاش مقدار دهی کردیم. حالا نتیجه اش چی میشه؟ این میشه که هر وقت که متغییر rows ما مقدار دهی بشه چون rows هم به tableView بایند شده میادش به صورت خودکار tableView ما رو هم پر میکنه بدون اینکه ما نیاز داشته باشیم کاری کرده باشیم! جالبه نه؟اما خوب متغییر rows ما کجا مقدار دهی شده؟ توی این قسمت از کد:Bind viewModel datasource variable to viewController variableدر واقع ما اینجا اومدیم چی کار کردیم، اومدیم گفتیم متغییر tableRowsItem که داخل لایه viewModel ما قرار داره رو bind کردیم به متغییر rows و بعدش قرارش دادیم داخل disposeBag مون تا وقتی که صفحه بسته شد این متغییر هم از حافظه آزاد بشه. این طوری در واقع ما میایم:۱- متغییر tableRowsItem رو داخل لایه viewModel مقدار دهی می‌کنیم۲- متغییر tableRowsItem چون به rows بایند شده rows رو هم مقدار دهی می‌کنه۳- متغییر rows هم چون به tableView مون بایند شده میادش و tableView رو پر و مقدار دهی می‌کنه!فکنم حالا متوجه شدید که چرا میگن reactive programming روی data streams متمرکز هستش :) .توجه: فقط به این موضوع هم توجه داشته باشید چون توی این bindig ما با ui سر و کار داریم و ui امون به روزرسانی میشه اومدیم بایند کردن tableRowsItem به rows رو اوردیم روی thread اصلی برنامه، چون به صورت پیش فرض این کارها در پس زمینه انجام میشن نه thread اصلی اپلیکیشن، که این کار  توسط این تیکه کد انجام شده:.observeOn(MainScheduler.instance)خوب حالا برای اینکه برنامه مون کار کنه کافی هستش که لایه ViewModel مون بیادش و DataSource مون رو که tableRowsItem هستش رو پر کنه. برای اینکه کارمون با این لایه تموم بشه کافی هستش که در تابع viewDidLoad کنترلرمون تابع setDataSoruce رو که در viewModel مون هستش رو صدا کنیم.توضیحات لایه ViewModel:توی این لایه چون با UI کاری نداریم پس فقط RxSwift رو import می‌کنیم و نیازی به RxCocoa نداریم. حالا باید متغییر tableRowsItem رو که قبلا گفته بودیم رو تعریف کنیم:var tableRowsItem = PublishSubject&lt;[ViewControllerModel]&gt;()و بعد از اون هم تابع setDataSource مون که کارش ساخت اطلاعات نمایش داده شده توی tableView هستش:Generate mock data to set on tableView خوب بعد از توضیحات تا اینجای مقاله فکنم بدنه این تابع کاملا واضح باشه و تنها موردش onNext ای باشه که برای متغییر tableRowsItem استفاده شده. برای هر Subject بنا بر نوع اش معمولا ۴ تا state وجود داره: onNext, onError, onCompleted و onDisposed که ما برای مقدار دهی به یه subject از onNext اون استفاده می کنیم.توضیحات لایه Model :این لایه هم فقط مدل ای رو که ازش استفاده می‌کنیم رو تعریف می‌کنیم که یک Struct ساده هستش:ViewModel structureحالا کافی هستش که برنامه رو اجرا کنید تا ببینید همه چیز به درستی کار می‌کنه و نیازی به پیاده سازی هیچ کدوم از delegate های tableView نیست!چند نکته:برای بعضی موارد مثل ست کردن ارتفاع cell ها باید از همون توابع قدیمی delegate استفاده بشهبرای ساختن header در tableView باز باید از توابع قدیمی delegate استفاده بشه اما فقط در tableView ولی در CollectionView می‌تونید header و footer کالکشن ویو رو به روش rx ای ست کنید. که این نوع تعریف کردن header نیاز به استفاده از rxDataSource هستش که در مقاله بعد در موردش توضیح می‌دم، البته اگر بخواید یه customView بذارید برای header تیبل تون ( بحث در مورد این مشکل در گیت هاب RxSwift)به عنوان مثال برای ست کردن ارتفاع cell های tableView می‌تونیم دلیگیت tableView مون رو self ست کنیم و تابع heightForRowAt تیبل رو پیاده سازی کنیم:خوب سعی کردم که خیلی کوتاه و ساده و کامل روال کامل پیاده سازی یه tableView رو به روش RxSwift توضیح بدم و اون رو با روش سنتی مقایسه ای کرده باشم.خوشحال میشیم نظراتتون رو بدونم تا مقاله بعدی رو که در مورد tableView پیچیده تری هستش رو بهتر بنویسم.راستی سورس کد این مقاله رو هم می‌تونید از این لینک github دانلود کنید.ممنون از همراهی تون.امین شفیعی</description><category>shafi.ee</category><author>shafi.ee</author><pubDate>Tue, 22 Jan 2019 01:19:00 +0330</pubDate></item></channel></rss>