<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمد زکی زاده</title>
        <link>https://virgool.io/feed/@mohammad_z74</link>
        <description>عاشق دنیای برنامه نویسی و هوش مصنوعی</description>
        <language>fa</language>
        <pubDate>2026-06-08 03:00:03</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/16996/avatar/yqHyvQ.png?height=120&amp;width=120</url>
            <title>محمد زکی زاده</title>
            <link>https://virgool.io/@mohammad_z74</link>
        </image>

                    <item>
                <title>MVVM + RxSwift on iOS part 2</title>
                <link>https://virgool.io/@mohammad_z74/mvvm-rxswift-on-ios-part-2-r8ktpub8w9yf</link>
                <description>در پارت اول یه مقدمه ای از MVVM و RxSwift گفته شد و اگر به نظرتون RxSwift سخت و با ابهام بوده نگران نباشید، Rx در اول شاید سخت به نظر برسه اما با مثال های این پارت و تمرین ،ساده و قابل فهم میشه.در این پارت یک پروژه کامل رو با دیزاین پترن MVVM با RxSwift می زنیم و از مزایای Rx و MVVM در پروژه ی واقعی بهره میگیریم.پروژه رو می تونید از این لینک تو گیتهاب دانلود کنید.پروژه ای که مد نظر گرفتم یه اپ خیلی سادس که لیستی از آلبوم ها و آهنگ های گروه Linkin Park رو در قالب UICollectionView و UITableView نشون میده. UI Setupبرای اینکه جلو تر در پروژه مجبور نباشیم کالکشن ویو آلبوم ها و تیبل ویو لیست آهنگ ها رو دوباره بزنیم بهتره یه جوری بزنیم که بتونیم بعدا به راحتی ازشون استفاده کنیم ( Reusability )برای اینکار UIViewController مادر رو با استفاده از ContainerView تقسیم به دو قسمت میکنیم:AlbumCollectionViewVC TrackTableViewVCپس یعنی کلاس ویوکنترلر مادر از دو ChildViewController تشکیل شده ( برای مطالعه در مورد ChildViewController و استفاده از آن میتونید این مقاله رو بخونید )عکس استوری بورد از کلاس مادربرای Cellهامون هم از nib استفاده می کنیم که اونم بتونیم به راحتی reuse کنیم :AlbumCollectionViewCellبرای رجیستر کردن cell های فایل nib باید این کد رو در متد viewDidLoad کلاس AlbumCollectionViewVC  بزارید که UICollectionView بفهمه نوع Cell هاش رو:کد رجیستر سلول های albumCollectionViewدقت کنید که این کد باید در کلاس AlbumCollectionViewVC قرار بگیره یعنی یکی از کلاس های فرزند کلاس مادر و کلاس مادر هیچ ارتباطی با ابجکت های کلاس فرزندش فعلا نداره.برای TrackTableViewVC هم دقیقا همین روال با تفاوت اینکه فقط تیبل ویو هستش انجام میدیم. حالا میریم سراغ کلاس مادر و باید ۲ کلاس فرزندمون رو ستاپ کنیم:همون طور که در عکس استوری بورد دیدید جای کلاس های فرزند دو ویو هست که در واقع ویو کنترلر هامون توش هست به این ویو ها ContainerView میگند برای ستاپ این ویو ها از کد زیر استفاده می کنیم:برای این از lazy استفاده کردیم جدا از اینکه initialize خود آلبوم خیلی خوانایی بیشتر داره تا اینکه تو viewDidload انجام شه، تا موقعی که به albumsViewController دستیابی نکنید وارد مموری نشده بالعکس بقیه متغیر های کلاس که موقع ساخته شدن کلاس وارد مموری میشند ( این بخاطر lazy بودن متغیر هست‌ )برای track نیز همین کارا دقیقا انجام میشه . حالا میریم سراغ viewModel و ًRxSwift پروژه:ViewModelدر کلاس ویو مدل صفحه اصلی ما باید دیتا رو از سرورمون بگیریم و پارس کنیم به صورتی که دقیقا ویو میخواد سپس به کلاس مادر بدیم و کلاس مادر اون دیتا ها رو پاس بده به دو تا ویو کنتلر های فرزند پس یعنی کلاس مادر از ویو مدلش درخواست دیتا می کنه و ویو مدل از لایه نتورک درخواستشو میفرسته بعد ویو مول دیتای بازگشتی رو پارس می کنه و آماده به کلاس مادر میده.حالا قسمت قشنگ ماجرا میرسه و Rxswift وارد میشه:خب قبل اینکه وارد کد بشیم ببینیم ویو مدل جز دیتا دیگه چه چیزایی به کلاس ما میده:از اونجایی که ریکوست به سرور میدیم باید یه لودینگ نشون بدیم که کاربر بفهمه در حال لود هست باید به کلاسمون بگیم که ویو لودینگ رو نشون بده یا نه پس یه observables از نوع Bool نیاز داریم که هر وقت true بود یعنی در حال لود هست و هر وقت false بود یعنی لود شده ( اگر نمیدونید  observables چی هست پارت ۱ رو بخونید)۲. ارور های ممکنه از سرور و غیره که میتونه هر چی باشه : پاپ آپ یا ارور اینترنت و ... اینم باید observable از نوع ارور دلخواهمون باشه که اگر مقداری داشت رو صفحه نشون بدیم ۳. دیتا های کالکشن و تیبل ویو...پس ۳ نوع Observable داریم که باید کلاس مادرمون به اینا رجیستر بشه حالا چطوری:این ها متغیر های کلاس ویو مدلمون هستند که هر ۴ تا Observable هستند و بدون مقدار اولیه . سوال براتون پیش میاد که خب PublishSubject چیه؟ Subjectsدر دنیای Rx همون طور که گفته شد یه سری متغیر ها Observer و یه سری Observable هستند، حالا یه سری دیگه هستند که همزمان هم میتونن Observer باشند هم Observable به اینا Subjects میگند.خود Subjects ها به ۴ نوع تقسیم میشند که توضیح راجب تک تکشون مقاله جدا می خواد ولی واسه این پروژه من از PublishSubject استفاده کردم که تقریبا پر کاربرتریته (‌اگر راجع به ۴ سابجکت دوس دارید بخونید این مقالرو پیشنهاد میکنم )‌یکی از دلایل خوب استفاده از این نوع سابجکت اینه که بدون مقدار اولیه میتونه initialize بشه. ViewModel Request:حالا میریم سراغ کدش و ببینیم چطوری دیتا ها رو به ویومون بدیم:قبل اینکه بریم سراغ کد ویو مدل بهتره اول بریم سراغ کد کلاس HomeVC و ۴ متغیر بالا رو وصل کنیم به کلاسمون به ( اصطلاح قسمت data binding ) که کلاسمون آماده باشه برای دیتا هایی که ویو مدل میده بهش در واقع observe میکنیم دیتا های تولیدی ViewModel رو.در کلاس HomeVC در متد ViewDidLoad :در این قسمت داریم loading رو bind می کنیم و بهش میگیم هر مقداری میگیری وصلش کن به rx.isAnimating .. خب الان دارید میگید به این راحتی هر وقت ویومدل true فرستاد به این راحتی لودینگ رو نشون میده باید هم بگم اره و هم بگم نه ...RxCocoa:برای اینکه دیتا ها بتونن بایند بشند به UIkit به لطف RxCocoa پراپرتی های زیادی از ویو های مختلف با دستور .Rx در دسترسند که همه از نوع observable که بتونید خیلی راحت عملیات بایندینگ رو انجام بدید بعضی از observable های کلاس UIView: خب طبیعتا همه ی پراپرتی ها موجود نیست و بعضی ها رو باید خودتون بنویسید مثل isAnimating بالا که من لودینگ رو بهش بایند کردم با این extension : ( فایل ReactiveExtensiones.swift در پروژه)Reactive Extension  حالا که لودینگمون آمادس که ViewModel بهش دیتا بده میریم سراغ بقیه بایندر ها.برای ارور ها مثل پارت اول سابسکرایبشون کافیه بکنیم و به باندینگی نیاز نیست:در کد بالا هر وقت اروری از ویو مدل به وجود بیاد ما اینجا داریم بهش گوش می کنیم چون subscribe کردیم ، حالا شما میتونید هر کاری بکنید با این ارور، که من دارم یه پاپ اپ مانند نشون میدم .باید اشاره کنم که در کد بالا .observeOn(MainScheduler.instance) چیه: این قسمت از کد میاد سیگنال های دریافتی ( اینجا ارورها ) رو از هر thread ی که هست به main thread میاره چون میخوایم رو ui نشون بدیم باید از بکگراند ترد به این ترد بیایم )حالا میریم سراغ آلبوم ها و ترک ها که وصل بشند به UICollectionView و UITableView چون خود پراپرتی های collectionView , tableView در دو کلاس فرزند هستند فعلا کافیه آرایه ای از آلبوم ها و ترک ها رو بایند کنیم به کلاس فرزند و به کلاس فرزند بسپریم که این ها رو نشون بده: (‌در آخر این مقاله این کارو می کنیم‌)حالا برمیگردیم به ویو مدلمون و تولید دیتا رو ببینیم چجوریه:۱.  در اول داریم لودینگ رو true میکنیم و چون تو کلاسمون بایندینگ رو انجام دادیم صفحه کاربر به حالت لودینگ در میاد و تا وقتی که false نفرستیم ادامه داره.۲.در خط بعدی داریم با apimanager که قسمت نتورک اپ و api کال هاست رو انجام میدیم که من از کتابخونه ای استفاده نمی کنم و شما از هر چیزی که واسه نتورکتون استفاده میکنید اینجا کال کنید api تون رو.۳.حالا که جواب از سرور اومده باید به لودینگ خاتمه بدیم پس رو loading میایم false میفرستیم و اپمون از حالت لودینگ در میاد.۴. حالا بنا به جواب سرور اگه به مشکل خوردیم میایم ارور رو با مقدار مورد نظر میفرستیم و دوباره چون کلاس مادر subscribe کرده لودینگ رو داره به لودینگ های emit شده از ویو مدلش گوش میده .۵. اگر هم جواب موفقیت آمیز و بدون ارور گرفتیم میایم با این ۴ خط پارس و به کلاسمون میفرستیم که پاس بده به دو کلاس فرزند البوم و ترک.خب دو خط اول شاید مبهم به نظر برسه یه توضیح مختصر بدم:در بالا با استفاده از SwiftyJson جیسون بازگشتی رو پارس می کنیم و با استفاده از یکی از فانکشن های کاربردی functional programming نوعش رو از JSON به آلبوم تبدیل می کنیم. اینکه انقدر راحت مدلمون ساخته میشه بخاطر Codable بودن مدل هاست که از سوییفت ۴ اضافه شده?.حالا که آماده شد دیتا و پاس دادیم به کلاس فرزند بریم در مرحله آخر که تو CollectionView و TableView نشون بدیم:اگر یادتون باشه در کلاس مادر، ترک ها رو بانید کردیم به tracks از پراپرتی های trackTableViewVC که اینم subject گذاشتیم:حالا در متد viewDidLoad کلاس trackTableViewVC باید ترک ها رو بایند کنیم به UITableView که این کار به لطف RxCocoa در ۲ خط زیر انجام میشه:بله درسته فقط و فقط همین دو خط دیگه نه خبری از ست کردن delegateهست نه خبری از numberOfSections و numberOfRowsInSection و ... خود RxCocoa همرو براتون هندل می کنه خودش model ای که بهش دادید رو ( بایند کردید )‌ میفهمه و با دادن نوع cell همه ی متغیر های لازم برای ساختن tableView ,CollectionView رو بهتون تو closure میده:اولیش row هست ( همون indexPath.row ) دومیش مدل متناظر با row و در آخر cell ای که دادید وبه همین راحتی که دیدید دیتا ها سر جاشون نشون داده میشند . راستی اینکه چطوری cell.track همه ی عکس و غیره رو هندل می کنه : میتونید شما تو همون closure بالا ست کنید اما خب به نظرم تو خود کلاس UITableViewCell انجام بشه خیلی بهتره و قطعا خوانا تر....قبل اینکه تموم کنم مقالرو میتونید با کد زیر انیمیشن خیلی قشنگی به پروژه بدید و حس خوبی به کاربرتون بده:خب ما یه پروژه نسبتا کامل رو با دیزاین پترن MVVM با کمک RxSwift ,RxCocoa زدیم . امیدوارم شما رو تا حد خوبی با این کانسپت ها آشنا کرده باشم . پروژه تمام شده رو میتونید از این لینک دریافت کنید و خوشحال میشم به صفحه گیتهابم سری بزنید.ایمیل من : mohammad_Z74@icloud.com خوشحال میشم نظراتون رو بدونم.</description>
                <category>محمد زکی زاده</category>
                <author>محمد زکی زاده</author>
                <pubDate>Fri, 12 Oct 2018 17:57:00 +0330</pubDate>
            </item>
                    <item>
                <title>MVVM + RxSwift on iOS part 1</title>
                <link>https://virgool.io/nstehran/mvvm-rxswift-on-ios-part-1-lmtp5ommn6oh</link>
                <description>امروز میخوام دیزاین پترن MVVM رو در دنیای برنامه نویسی iOS تا یه حد خوبی معرفی کنم که البته همراه با RxSwift. مقاله در ۲ پارت تقسیم  میشه که در پارت اول یه توضیح خیلی کلی از دیزاین پترن ها میدم و دانش اولیه و مورد نیاز از RxSwift و در پارت دوم یک پروژه ی سمپل رو با MVVM و RxSwift میزنیم. Design patterns:قبل از هر چیزی بهتره یه توضیح بدم که چرا اصلا از دیزاین پترن ها استفاده می کنیم خیلی خلاصه بگم برای اینکه کدمون به اصطلاح spaghetti نشه و بهم نریزه و خب قطعا این تنها دلیلش نیست یکی از دلایلش تست پذیری ه ، دیزاین پترن های زیادی هست که میتونیم به معروف ترین این ها به ٖٖMVC, MVP, MVVM, VIPER اشاره کنیم یه عکس خوب از اسلاید های NSLondon که این ها رو از سه لحاظ تست پذیری،توزیع پذیری و راحتی استفاده مقایسه میکنه:مقایسه دیزاین پترن هاهمه ی این دیزاین پترن ها خوبی ها و بدی های خودشونو دارند اما در اخر هر کدوم به یک نحوی کد مارو تمیز تر و ساده تر میکنند. در این مقاله روی MVVM تاکید شده که امیدوارم آخر قسمت دوم مقاله دلیلشو بفهمید و خوشحال میشم نظرتون رو بدونم.خب اول یه نگاه خیلی کوچیک به MVC  داشته باشیم و بعد بریم سراغ MVVMMVC:احتمالا اگر مدتی باشه که برنامه نویسی iOS کرده باشید با دیزاین پترن MVC آشنا باشید. (‌ در دیزاین پترن ها برای برنامه نویسی iOS، پیشنهاد خود اپل MVC هست )این لایه از سه قسمت اصلی Model , View ,Controller تشکیل شده که ViewController مسولیت به هم وصل کردن ویو و مدل رو داره که از لحاظ تيوری به نظر View و Controller جداهستند اما در دنیای برنامه نویسی iOS این دو لایه تا حد زیادی متاسفانه یکی میشوند ، البته در پروژه های کوچیک همه چی مرتب به نظر میرسه و مشکل خاصی نیست اما وقتی پروژتون از یه حدی بیشتر میشه تقریبا Controller تمامی مسولیت رو به عهده داره ( معروف به Massive View Controller  :دی )که باعث میشه خیلی شلوغ باشه، البته MVC اگر واقعا درست پیاده سازی شه و کنترلتون رو تا حد امکان تقسیم کنید این مشکل تا حدودی حل میشه‌ ولی در این مقاله یه پروژه ی سمپل رو هم با MVC و هم با MVVM میزنیم و خودتون تصمیم بگیرید  براتون کدوم بهتره.(عکس از داکیومنت اپل)MVVM:(عکس از گیتهاب)خب MVVM مخفف Model View ViewModel هست که کنترلتون و انیمیشن های ویو ها و در کل هر متدی که با ویو سر و کار داره تو View قرار می گیره و در ViewModel کال های api و بیزنس لاجیکتون در این لایه قرار میگیره .در واقع این لایه واسط بین مدل و ویو هست و قراره دیتا رو همون طوری که View میخواد از این لایه آماده کنید و به View بدید، و یه نکته ای که هست اگر تو فایل ViewModel دیدید :import UIKitگذاشتید بدونید یه جای کار رو اشتباه کردید و ویومدل نباید هیچ اطلاعی ازش داشته باشه.در پارت دوم مقاله این پترن رو با مثال دقیق بررسی میکنیم.RxSwift: یکی از ویژگی های MVVM بایند بودن ( متصل بودن و سینک بودن ) دیتا و ویو هست که اینکار با RxSwift بسیار دلپذیر میشه.. البته می تونید با delegate یا KVO یا Closure هم اینکارو کنید اما یکی از ویژگی های دنیای Rx اینه که شما اگرRx رو در یک زبون تا حد خوبی یاد بگیرید می تونید در بقیه پلتفرم ها هم استفاده کنید چون بیس و ساختار اصلی  Rx تو همه ی زبونای موجودش یکیه حالا در قسمت اول مقاله می خوام کلیات RxSwift رو توضیح بدم که در واقع بیس دنیای Rx هست و بعد در پارت دوم میریم یه پروژه رو MVVM میزنیم با RxSwift.Reactive programming:خب RxSwift بر مبنای Reactive Programming ساخته شده حالا این یعنی چی:In computing, reactive programming is a programming paradigm oriented around data flows and the propagation of change. This means that it should be possible to express static or dynamic data flows with ease in the programming languages used, and that the underlying execution model will automatically propagate changes through the data flow. — Wikipediaاحتمال خیلی قوی بعد خوندن این پاراگراف هیچی نفهمیدید و بهتره با توضیحات ادامه مقاله درکش کنید:بخوایم مثال خیلی ساده بگیم فرض کنید شما سه متغیر a,b,c دارید که :حالا اگر a رو از ۱ به ۲ تغییر بدیم و c رو پرینت کنیم باز همون ۳ هست مقدار c .اما دنیای reactive مسئله جور دیگریست و مقدار c وابسته به a , b هست و شما اگر a رو از ۱ به ۲ تغییر بدید c هم مقدارش  از ۳ به ۴ تغییر می کنه و لازم نیست خودتون مقدار c رو دوباره تغییر بدید:به شیوه ی اول و رایج کد زنی Imperative programming می گویند.حالا بریم سراغ مباحث اصلی RxSwiftدر دنیای RxSwift و در کل Rx، همه چیز استریمی از اتفاق ها و رویداد هاست ( اعم از UI events, Network requests ) حالا این رو تو ذهنتون باشه که در ادامه با مثال توضیح بدم:گوشی شما یک observable (به فارسی: قابل مشاهده) هست به طور مثال با انتشار یک سری رویداد مثلا زنگ زدن ، نوتیفیکیشن های اپلیکیشن و ... شما رو صدا میزنه و  در واقع شما  گوشیتون رو subscribe کردید و تصمیم می گیرید با این اتفاق چه کنید به طور مثال از بعضی از نوتیفیکشین ها می گذرید یا بعضیاشونو جواب میدید یا ... ( در واقع این اتفاق ها برای شما signal هستند و شما یک observer هستید و تصمیم گیرنده.)حالا وارد مثال دنیای برنامه نویسیش میشیم:Observables and observers (subscribers):در دنیای Rx یک سری از متغیر ها Obsarvable هستند و یک سری observers یا همون subscribers از اونجایی که Obsarvable جنریک هست شما می تونید Obsarvable از تایپی که می خواید بسازید ( هر تایپی که به پروتکول ObservableType کانفرم بشه‌) :خب حالا یک سری Obsarvable تعریف کنیم:در مثال بالا در خط اول Obsarvable از نوع String ، در خط دوم از نوع Int و در آخرین خط از نوع دیکشنری درست کردیم حالا این متغیرهای Obsarvable امون رو باید subscribe کنیم تا بتونیم ازشون سیگنال های منتشر شده رو بخونیم:ممکنه براتون سوال پیش بیاد که در خروجی next و complete چی هستند و چرا فقط &quot;Hello Rx World &quot; چاپ نشده خب برای  جواب این سوال باید اصلی ترین ویژگی Observable ها رو بگم:تمامی Observable  ها در واقع همان sequence هستند که فرق اصلی این sequence با swift sequence در این هست که میتونه مقادیرش asynchronously باشه ( اگر این دو خط رو متوجه نشدید زیاد اشکالی نداره و با توضیح بعدی هم کارتون راه میفته ) بخوایم با شکل بگیم :سکانسی از رویداد هادر عکس بالا سه نوع Observable داریم که اولی از نوع Int هست و ۶ مقدار ۱ تا ۶ رو طی زمان منتشر کرده و بعد تموم شده. در نوع دوم Observable امون از نوع String هستش و از a تا f رو طی زمان منتشر کرده بعد با یک ارور به پایان رسیده. در نوع سوم  Observable از نوع تپ دکمه هستش و به پایان نرسیده و ادامه داره.به این شکل ها که Observable ها رو نشون میدن marble diagrams نامیده میشوند و برای اطلاع بیشتر میتونید هم سایتش و هم اپلیکیشنش رو از استور دانلود کنید. ( اپش اپن سورسم هست :دی ) در دنیای Rx برای هر Observable در طول زمان وجودش ۰ یا تعداد بیشتری event منتشر می کنه ( مثال بالا ) که این event ها enum ای از سه حالت ممکن زیر هستند:1. .next(value: T)  2. .error(error: Error)3. .completed وقتی Observable مقدار یا مقادیری به آن اضافه می شود Observable اونت next را اجرا می کند و مقدار یا مقادیر اضافه شده را از طریق value به subscribers یا observers میدهد .( اعداد ۱ تا ۶ در مثال نوع ۱ ، a تا f در مثال نوع ۲ و tap ها در مثال نوع ۳ )،۹۰ درصد مواقع در پروژه هاتون این متد به کار میاد تا ۲ متد بعدی. اگر  Observable با خطا مواجه شود اونت error را منتشر می کنه و  Observable به اصطلاح تمام میشود . ( مثال نوع ۲ )اگر  Observable به اتمام برسه completed صدا زده میشه ( بعد از صدا زده شدن ۶ در مثال نوع ۱ )برای اینکه یک subscription رو کنسل کنیم و دیگه یک Observable رو unsubscribe کنیم متد dispose رو می تونیم صدا کنیم یا اگر می خواهید بعد از deinit شدن ویوتون خودبه خود اینکار انجام شه یه باید یک متغیر از نوع DisposeBag درست کنیم و این متغیر خودش کار dispose رو در زمان deinit کلاس انجام میده باید اضافه کنم اگر این کار رو نکنید subscribers هاتون باعث به وجود اومدن memory leak میشند. به طور مثال در مثال شکل Obsarvable ها باید subscription به صورت زیر انجام بشه:روش درست subscribeحالا یکم از زیبایی های ترکیب دنیای Rx با functional programming صحبت کنیم، فرض کنید شما  Observable از نوع Int دارید و شما subscribe کردید به اون Obsarvable ، حالا Obsarvable بهتون یه سری از Int میده شما میتونید با فانکشن های فوق العاده کارآمد functional programming یه سری تغییرات روی سیگنال های emit شده از Obsarvable انجام بدید مثلا :map:برای تبدیل سیگنال های منتشر شده قبل اینکه به subscriber یا observer مورد نظر برسه از متد map استفاده میتونید بکنید مثلا یک obsarvable از نوع Int داریم که در طی زمان ۳ عدد ۲و۳و۴ رو emit یا منتشر می کنه حالا می خوایم قبل اینکه به subscriber برسه ۱۰ برابرش کنیم و عدد ۱۰ برابر شده به subscriber برسه:map marbleکد برای mapfilter:شاید بخواید قبل اینکه به subscriber تون برسه بعضی از اونا رو فیلتر کنید مثلا در مثال بالا میخواید بعد از اینکه ضرب در ۱۰ شدن فقط اعدادی که بالای ۲۵ هستند رو چاپ کنه:کد برای filterflatMap:فرض کنید دو عدد obsarvable دارید حالا می خواید این دو تا رو ترکیب کنید و از ترکیب آن ها یک obsarvable بسازید:در مثال بالا obsarvable A و obsarvable B ترکیب شدند و یک obsarvable جدید از ترکیب این دو به وجود آوردند کد:DistinctUntilChanged یا Debounceاین دو متد یکی از پر کاربردترین متد ها هنگام سرچ هستند مثلا کاربر در textfield یه کلمرو سرچ میخواد بکنه شما هم با نوشتن هر کاراکتر از کاربر یه ریکوست به سرور می زنید خب اگر کاربر سریع تایپ کنه شما کلی ریکوست بیهوده به سرور دادید و در صورتی که آخرین جایی که کاربر یه ایست کوتاه کرده باید ریکوست به سرور بدید برای حل این مشکل شما میتونید از تابع Debounce استفاده کنید بدین صورت که :در مثال بالا تا وقتی که متن usernameOutlet هر زیر ۰.۳ ثانیه تغییر کنه به subscriber نمیرسه و طبیعتا تابع سرچ صدا زده نمیشه .تابع DistinctUntilChanged حساس به تغییرات هست بدین معنی که اگر دو سیگنال یکسان برسه تا وقتی که سیگنال تغییر نکنه به subscriber دیگه فرستاده نمیشه.دنیای Rx خیلی بزرگ تر از چیزی که میتونید فکرش رو بکنید هست و من فقط چندین مفاهیم اولیه که به نظرم مورد نیاز پارت بعدی مقاله که یک پروژه ی واقعی رو با RxSwift پیاده می کنیم، بود رو گفتم.کتاب RxSwift از raywenderlich خیلی خوب RxSwift رو از ۰ توضیح داده که خیلی پیشنهاد می کنم خوندنشو.خیلی طبیعیه که با یک مقاله از RxSwift شاید زیاد متوجه نشده باشید چون از مفاهیم پیشرفته سویفت هست و شاید روز ها باید مقاله های مختلف بخونید تا بفهمیدش. در این لینک چندین مقاله خوب رو از قسمت RxSwift اش میتونید ببینید.در آخر بگم که تصمیم ترجمه کردن و نکردن بعضی از اصطلاحات کار ساده ای نبود? و خودتون ببخشید اگر اضافی یا کم ترجمه شده.امیدوارم با قسمت بعدی مقاله که ًRx رو در پروژه ی واقعی با MVVM پیاده سازی میکنیم مفاهیم RxSwift رو بهتر متوجه شید چون با مثال های واقعی درک کردنش بسیار راحت تر خواهد بود.  ایمیل من mohammad_z74@icloud.com هست اگر سوالی داشتید در خدمتم.</description>
                <category>محمد زکی زاده</category>
                <author>محمد زکی زاده</author>
                <pubDate>Fri, 14 Sep 2018 14:19:20 +0430</pubDate>
            </item>
            </channel>
</rss>