
ImagesDataSource: קלאס ולא struct, כי לרוב רוצים אובייקט משותף שמועבר ב-reference. מעבירים אליו את ה-JSON ואת ה-struct בשם MyImage.lazy var: jsonData מוגדר כ-lazy עם closure שמפעיל את עצמו. הוא נוצר רק בשימוש הראשון ונשמר אחר כך. computed property רגיל היה ממיר את המחרוזת בכל גישה מחדש.getImages: מחזירה מערך של MyImage, או מערך ריק אם המידע חסר.getImage עם callback: מקבלת URL ופרמטר שני, closure שמקבל UIImage?. הפונקציה עובדת ברקע ב-DispatchQueue.global, ובסיום מפעילה את ה-callback בתוך DispatchQueue.main.async.@escaping: נדרש כי ה-closure מועבר הלאה לפונקציות אחרות ומופעל אחרי שה-getImage כבר חזרה. בתוך הבלוק צריך לכתוב self במפורש.ImagesDataSource, מקבלים את התמונות, ולכל אחת קוראים ל-getImage ומעבירים closure. בתוכו נוצר ה-UIImageView ונוסף ל-stack view.typealias: אפשר להגדיר ImageCallback ולהשתמש בו במקום לכתוב את הטיפוס כל פעם, ולהוסיף לו תיעוד.self כ-weak reference.הטקסט המלא של הדקות הראשונות בהרצאה «עבודה עם Callbacks עבור משימות אסינכרוניות» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
שלום וברוכים הבאים, בשיעור הקודם למדנו איך לכתוב קוד שיכול לעזור לנו להוריד תמונות מהאינטרנט אבל בנינו את הפרויקט בצורה כזאת שכל העבודה נעשתה ב-view controller הסיבה שבנינו את זה ככה היא שעוד לא למדנו על עבודה עם callbacks וזה בדיוק הנושא של היום ככה אנחנו נוכל לעבוד בצורה מסודרת עם ארכיטקטורה
נכונה שבה אנחנו כותבים קוד שקשור לעבודה עם דאטה ולמודלים בקלאסים נפרדים בסדר המודלים שלנו צריכים להיות מחוץ ל-view controller לכן אנחנו רוצים לעבוד קצת בשביל להגיע למצב הזה.
כדי להגיע למצב הזה שהארכיטקטורה הזאת מכונה MVC, סדר מודל view controller, מודל view controller אומר, אתם רוצים להפריד את המודלים מה-view controller מה-view, אוקיי? כלומר, אם זה view וזה קונטרולר, אז יש לכם גם את המודל.
במודלים אתם מכניסים כל מיני שכבות שלכם, דאטה, דאטה, access logic, network logic, כל מה שאתם רוצים, המון המון קלאסים, פרקטים, מה שתרצו.
Views זה פקדים בעצם, והקונטרולר שולט על הפקדים. הקונטרולר שולט על הפקדים, כלומר הקונטרולר יכול לייצר לעצמו Views, וגם את אלה אפשר לשים בקובץ נפרד, בסדר?
אני יכול לקרוא לזה איזשהו קלאס של View, ולדחוף את זה לקלאס הזה כדי לא לכתוב הרבה קוד ב-View קונטרולר. ה-View קונטרולר, שזה מה שאנחנו נמצאים בו כרגע, אמור להתעסק במשימות של להציג UI, להגיב לאירועים.
מודל, לעומת זאת, אמור להיות כל השאר, בסדר כל הדאטה שלכם. ה-view זה אם אתם רוצים לכתוב שכבות עבור עיצוב, בסדר? זאת אומרת, אם אתם רוצים לכתוב קוד עבור עיצוב או וואטאבר, אז אפשר גם את זה להוציא לקלאס נפרד.
אז בואו נלמד רגע, הנושא של היום זה קולבקים, בסדר? לא mvc. אז אנחנו רוצים ללמוד להוציא את כל זה החוצה, את הקוד שקשור לנטוורקינג, וללמוד איך לקבל ממנו את התשובה בכל זאת.
לצורך ההדגמה בואו נייצר קובץ חדש swift-file ובואו נקרא לזה images data source אוקיי עכשיו בגלל שאני רוצה לעבוד פה עם ui-image אז בסופו של דבר אנחנו נצטרך פה import ל-ui-kit בואו נעשה את זה כבר עכשיו יהיה לנו קלאס של data source אמרנו images data source אז בואו נקרא לזה ככה אנחנו לא
רוצים לרשת משום דבר הסיבה שאני משתמש פה בקלאס היא שהרבה פעמים אנחנו רוצים לעשות את זה אובייקט משותף אסטרקטים מועברים ב-value וקלאסים מועברים ב-rf ולכן הפעם יותר מתאים פה לעשות קלאס טוב, בואו נעביר לפה את כל העבודה שהייתה לא קשורה שעשינו ב-ViewController, נעביר לכאן.
אז יש לנו את זה, זה ה-JSON שלנו, נכון? אז בואו ניקח אותו רגע, בלי כל היתר, ובואו נעשה לעצמנו let json שווה, ונדביק את מה שהיה לנו שם קודם. לא יודע איך, יש לי פה עוד סוגר אחד, אני אוריד אותו, וזה בסדר. אז זה ה-JSON, אוקיי?
כמובן שאת ה-JSON הזה אתם תרצו ללמוד לקבל מהאינטרנט, וזה גם נושא לשיעור, אז אנחנו נדבר על זה גם. הלאה.
מתודה שתביא לכם את התמונות בסדר זאת אומרת הנה הג'ייסון מעולה בואו נביא את התמונות לגבי הג'ייסון דאטה דרך אגב יש לי עוד משהו מעניין להגיד לכם אז בואו אני אגיד היה לי תכונה שם של ג'ייסון דאטה כאן אני יכול לארגן את זה ג'ייסון דאטה אוקיי והטיפוס של זה זה דאטה אבל מה שאני רוצה לעשות פה אני רוצה להגיד שזה שווה לתוצאה שמחזירה הפונקציה הבאה כאן מה שאתם רואים זה פונקציה זה
closure אוקיי והclosure הזה הוא יהיה מופעל ברגע שאני זה פונקציה שהיא מפעילה את עצמה, אוקיי? Self-invoking function. קצת מוזר, נכון? אבל אנחנו רוצים ללמוד על זה.
עכשיו, אנחנו לא רוצים שזה יהיה סתם let, אנחנו רוצים שזה יהיה משתנה lazy var. מה זה lazy var? זה משתנה שניתן יותר מאוחר. מה זה יותר מאוחר? כשמתינים את הקלאס הזה, עדיין אין JSON data.
ברגע שמשתמשים במשתנה הזה פעם ראשונה, הוא יתאם. בואו נעשה רגע את העבודה פה. בואו נעשה return ל-JSON שלנו מלמעלה, נקודה data using utf-8 אוקיי עכשיו זה אופציונל נכון אז בוא נגיד שזה אופציונל פנטסטי שוב פעם lazy variable lazy variable הוא משתנה שלא נטען מיד כשמייצרים את המופע של הקלאס מישהו יעשה עכשיו new ל-image data source
זה עדיין לא יהיה נוצר בסדר זה לא יהיה הותחל מתי זה כן יותחל רק ברגע שאני אשתמש בפונקציה בסדר רק ברגע שאני אשתמש ב-json data בצורה כזאת או אחרת לכן זה כתוב בצורה מוזרה אנחנו אומרים שזה משתנה עצלן, זאת אומרת הוא לא נטען מיד בהתחלה של ה-init.
דבר שני, יש לנו פה פונקציה שהיא מפעילה את עצמה, וברגע שהפונקציה מופעלת, Swift תקרא לפונקציה כדי להפעיל אותה ברגע שאני אשתמש ב-JSONData, והיא תתחיל את המשתנה הזה יותר מאוחר, בסדר?
אז LazyLoadedVariable. אוקיי, אתם לא חייבים להשתמש פה דרך אגב ב-LazyVar, אתם יכולים לעשות תכונה מחושבת. הבעיה שאם אתם תעשו תכונה מחושבת, בואו אני אדגים מה זה תכונה מחושבת, כמו שאתם בטח מכירים, אבל נעשה.
אם הייתי אומר var data, בסדר, וכאן הייתי אומר שזה מסוג של data, נכון? כמו תכונה מחושבת, אופציונל, וכאן הייתי אומר return json.data using utf-8, זאת computed property.
מה הבעיה? שכל פעם הוא הולך ל-Json הזה, ממיר לכם אותו ל-data, הולך ל-Json, ממיר ל-data, הולך ל-Json, ממיר ל-data.
Lazy Variable הוא לא כזה, למרות שהסינטקס פה הוא כמעט אותו דבר, נכון? אבל Lazy Variable הוא הרבה יותר חכם. הוא לא מתחיל את זה בכלל עד שאתם לא משתמשים, בדומה למה שקורה ב-computed property, אבל once הוא התחיל את זה פעם אחת, הוא שומר את זה כתכונה שמורה, ואז לא מחשבים את זה כל פעם, אוקיי?
אז מומלץ פה להשתמש ב-Lazy Variable, זה נחמד, אז השתמשתי. הלאה. אמרנו, רוצים את התמונות ב-View Controller, אז כדי לקבל את התמונות אין בעיה, אנחנו נעשה פשוט פונקציה, get images, תכף נמשיך, אנחנו פשוט ניקח את ה-struct מכאן כדי שהוא
יהיה במקום הנכון ובוא נגזור אותו מהווי קונטרולר בעצם, נעלים אותו משם כי אי אפשר להכריז על דברים פעמיים. טוב, יהיו לנו קצת שגיאות, בואו נמחק מפה קצת דברים, יהיו לנו קצת שגיאות אבל אחר כך כמובן שאנחנו נסדר אותן.
אז כדי לקבל את התמונות, אין בעיה, אני מחזיר מערך של my image, אנחנו נעשה את אותו guard led שהיה לנו קודם, בסדר?
אחרת אני מחזיר מערך ריק עכשיו הדאטה צריך לבדוק שהוא אכן קיים אז בוא נעשה guard let data שווה ל json data מלמעלה אלס נחזיר מערך ריק או יודעים מה בואו נאחד את זה עם ה-guard let הנוכחי כבר באופן הבא אז אני בודק שיש דאטה ואז התמונות תילקחנה מהדאטה הזה אחרת אני מחזיר פה מערך ריק ואם יש לנו תמונות ויש לנו דאטה אז אנחנו יכולים להחזיר את התמונות אוקיי הפונקציה הזאת כתובה get images
עובדת בואו נמשיך חזרה נחזור חזרה ל-view controller ונמחק משם את מה שאנחנו לא צריכים שם, אז אין יותר פרינט ל-images, נפלא. כל הקוד הזה של סקרול ויו וסטאק ויו אנחנו נשאיר כאן, כי זה בסדר מבחינת ה-view controller להתחיל פקדים.
היינו יכולים להוציא גם את זה לקלאס אחר של עיצוב, אבל נעשה את זה בהזדמנות. עכשיו כאן בואו נשים את כל הקוד הזה בהערה ואחר כך נחזור אליו.
אז מבחינת ה-view controller שלנו הוא עכשיו נקי ומצוחצח, מתעסק רק בעבודה עם פקדים, ובאים את שלט הסורס אנחנו צריכים לעבוד. כאן בעצם מתחיל השיעור שלנו. אנחנו רוצים לדבר על נושא מאוד מאוד חשוב בתכנות האסינכרוני שנקרא callbacks, אוקיי?
callbacks בעצם מאפשרים לנו לקרוא לפונקציה, וברגע שהיא מסיימת עם איזושהי עבודה שאנחנו נותנים לה, שהיא תחזיר תשובה, אוקיי? callbacks בעצם מאפשרים לי לכתוב פונקציה שתהיה אסינכרונית, אבל ברגע שהפונקציה מסיימת את העבודה שלה, היא יכולה להודיע על הפונקציה של ה-callback.
איך זה עובד? אנחנו בעצם מגדירים closure בצורה הבאה בואו נעשה פה פונקציה נגיד get image שהיא תיתן לנו url אבל תיתן לנו פה עוד פרמטר שזה ה callback על זה אנחנו רוצים לדבר ה callback הוא בעצם פונקציה אז בואו נכתוב פה משהו שדומה לפונקציה שתקבל תמונה היא תקבל נגיד ui image אוקיי אוקיי כתבתי את הפונקציה הזאת זאת פונקציה סינכרונית
אבל מה מיוחד בפונקציה הזאת הם נותנים לנו url והם אומרים לי ברגע שאתה מסיים תפעיל לי את הפונקציה הזאת וככה אני אדע מזה אוקיי בוא נראה איך אנחנו עובדים עם השיטה הזאת של עבודה עם קולבקים כאן אנחנו נעשה את העבודה שהיינו אמורים לעשות אנחנו נעשה dispatch queue גלובל אנחנו בצורה הסינכרונית נביא את התמונה כדי להביא את התמונה אז
אנחנו נעשה guard let data שווה ל json data מלמעלה בסדר אלס אני לא ממשיך