├── 01-introduction ├── final │ └── ImageGrid │ │ ├── ImageGrid │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── launch-assets │ │ │ │ ├── Contents.json │ │ │ │ ├── logo-white.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── ImageGridApp.swift │ │ └── ImageGrid.xcodeproj │ │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── starter │ └── ImageGrid │ ├── ImageGrid │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── launch-assets │ │ │ ├── Contents.json │ │ │ ├── logo-white.imageset │ │ │ │ └── Contents.json │ │ │ └── orange FF5A00.colorset │ │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── Info.plist │ └── ImageGridApp.swift │ └── ImageGrid.xcodeproj │ └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── 13-make-class-threadsafe ├── final │ ├── DataRace │ │ ├── DataRace │ │ │ ├── Assets.xcassets │ │ │ │ ├── Contents.json │ │ │ │ ├── AccentColor.colorset │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ ├── Preview Content │ │ │ │ └── Preview Assets.xcassets │ │ │ │ │ └── Contents.json │ │ │ └── DataRaceApp.swift │ │ └── DataRace.xcodeproj │ │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── NameChanger │ │ ├── NameChanger │ │ │ ├── Assets.xcassets │ │ │ │ ├── Contents.json │ │ │ │ ├── launch-assets │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── logo-white.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ │ └── Contents.json │ │ │ ├── Preview Content │ │ │ │ └── Preview Assets.xcassets │ │ │ │ │ └── Contents.json │ │ │ └── Info.plist │ │ └── NameChanger.xcodeproj │ │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Threadsafe.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground ├── starter │ ├── DataRace │ │ ├── DataRace │ │ │ ├── Assets.xcassets │ │ │ │ ├── Contents.json │ │ │ │ ├── AccentColor.colorset │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ └── Preview Content │ │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ └── DataRace.xcodeproj │ │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── NameChanger │ │ ├── NameChanger │ │ │ ├── Assets.xcassets │ │ │ │ ├── Contents.json │ │ │ │ ├── launch-assets │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── logo-white.imageset │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ │ └── Contents.json │ │ │ ├── Preview Content │ │ │ │ └── Preview Assets.xcassets │ │ │ │ │ └── Contents.json │ │ │ └── Info.plist │ │ └── NameChanger.xcodeproj │ │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Threadsafe.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground └── LICENSE.markdown ├── 20-dependencies ├── final │ └── FilterImages │ │ ├── FilterImages │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── launch-assets │ │ │ │ ├── Contents.json │ │ │ │ ├── logo-white.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── ImageDataProvider.swift │ │ └── FilterImages.xcodeproj │ │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── starter │ └── FilterImages │ ├── FilterImages │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── launch-assets │ │ │ ├── Contents.json │ │ │ ├── logo-white.imageset │ │ │ │ └── Contents.json │ │ │ └── orange FF5A00.colorset │ │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── Info.plist │ └── ImageDataProvider.swift │ └── FilterImages.xcodeproj │ └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── 22-cancel-operations ├── final │ └── FilterImages │ │ ├── FilterImages │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── launch-assets │ │ │ │ ├── Contents.json │ │ │ │ ├── logo-white.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── ImageDataProvider.swift │ │ └── FilterImages.xcodeproj │ │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── starter │ └── FilterImages │ ├── FilterImages │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── launch-assets │ │ │ ├── Contents.json │ │ │ ├── logo-white.imageset │ │ │ │ └── Contents.json │ │ │ └── orange FF5A00.colorset │ │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── Info.plist │ └── ImageDataProvider.swift │ └── FilterImages.xcodeproj │ └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── 06-the-right-way-to-download-images ├── final │ └── ImageGrid │ │ ├── ImageGrid │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── launch-assets │ │ │ │ ├── Contents.json │ │ │ │ ├── logo-white.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ └── Info.plist │ │ └── ImageGrid.xcodeproj │ │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── starter │ └── ImageGrid │ ├── ImageGrid │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── launch-assets │ │ │ ├── Contents.json │ │ │ ├── logo-white.imageset │ │ │ │ └── Contents.json │ │ │ └── orange FF5A00.colorset │ │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ └── Info.plist │ └── ImageGrid.xcodeproj │ └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── 05-challenge-a-better-way-to-download-images ├── final │ └── ImageGrid │ │ ├── ImageGrid │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── launch-assets │ │ │ │ ├── Contents.json │ │ │ │ ├── logo-white.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ └── Info.plist │ │ └── ImageGrid.xcodeproj │ │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── starter │ └── ImageGrid │ ├── ImageGrid │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── launch-assets │ │ │ ├── Contents.json │ │ │ ├── logo-white.imageset │ │ │ │ └── Contents.json │ │ │ └── orange FF5A00.colorset │ │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ └── Info.plist │ └── ImageGrid.xcodeproj │ └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── 21-challenge-implement-a-dependency ├── final │ └── FilterImages │ │ ├── FilterImages │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── launch-assets │ │ │ │ ├── Contents.json │ │ │ │ ├── logo-white.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── ImageDataProvider.swift │ │ └── FilterImages.xcodeproj │ │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── starter │ └── FilterImages │ ├── FilterImages │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── launch-assets │ │ │ ├── Contents.json │ │ │ ├── logo-white.imageset │ │ │ │ └── Contents.json │ │ │ └── orange FF5A00.colorset │ │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── Info.plist │ └── ImageDataProvider.swift │ └── FilterImages.xcodeproj │ └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── 14-challenge-make-number-class-threadsafe ├── final │ └── NumberChanger │ │ ├── NumberChanger │ │ ├── Assets.xcassets │ │ │ ├── Contents.json │ │ │ ├── launch-assets │ │ │ │ ├── Contents.json │ │ │ │ ├── logo-white.imageset │ │ │ │ │ └── Contents.json │ │ │ │ └── orange FF5A00.colorset │ │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ │ └── Contents.json │ │ ├── Preview Content │ │ │ └── Preview Assets.xcassets │ │ │ │ └── Contents.json │ │ └── Info.plist │ │ └── NumberChanger.xcodeproj │ │ └── project.xcworkspace │ │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcworkspacedata └── starter │ └── NumberChanger │ ├── NumberChanger │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── launch-assets │ │ │ ├── Contents.json │ │ │ ├── logo-white.imageset │ │ │ │ └── Contents.json │ │ │ └── orange FF5A00.colorset │ │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── app-icon-white-FF5A00-bg.png │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ └── Info.plist │ └── NumberChanger.xcodeproj │ └── project.xcworkspace │ ├── xcshareddata │ └── IDEWorkspaceChecks.plist │ └── contents.xcworkspacedata ├── 15-operations ├── final │ └── Operations.playground │ │ ├── Resources │ │ └── dark_road_small.jpg │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── timeline.xctimeline ├── starter │ └── Operations.playground │ │ ├── Resources │ │ └── dark_road_small.jpg │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift └── LICENSE.markdown ├── 10-use-dispatchsemaphore ├── final │ └── Semaphores.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Sources │ │ └── Duration.swift └── starter │ └── Semaphores.playground │ ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── contents.xcplayground │ ├── Contents.swift │ └── Sources │ └── Duration.swift ├── 03-use-dispatch-queues ├── final │ └── UseDispatchQueues.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Sources │ │ └── Duration.swift ├── starter │ └── UseDispatchQueues.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Sources │ │ └── Duration.swift └── LICENSE.markdown ├── 16-operationqueues ├── final │ └── ExploreOperationQueue.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ ├── timeline.xctimeline │ │ └── Contents.swift ├── starter │ └── ExploreOperationQueue.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift └── LICENSE.markdown ├── 07-create-async-functions ├── final │ ├── UseGroupOfTasks.playground │ │ ├── playground.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift │ └── DispatchGroupWaiting.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift ├── starter │ ├── UseGroupOfTasks.playground │ │ ├── playground.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift │ └── DispatchGroupWaiting.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift └── LICENSE.markdown ├── 04-use-dispatch-work-items ├── final │ └── UseDispatchWorkItem.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground ├── starter │ └── UseDispatchWorkItem.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground └── LICENSE.markdown ├── 08-wrap-an-asynchronous-function ├── final │ └── WrapAsyncFunction.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift └── starter │ └── WrapAsyncFunction.playground │ ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── contents.xcplayground │ └── Contents.swift ├── 09-challenge-download-a-group-of-images ├── final │ └── Images.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift └── starter │ └── Images.playground │ ├── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── contents.xcplayground │ └── Contents.swift ├── 12-explore-priority-inversion ├── final │ └── PriorityInversion.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift ├── starter │ └── PriorityInversion.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ └── Contents.swift └── LICENSE.markdown ├── 18-asynchronous-operations ├── final │ └── CreateAsyncOperation.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground ├── starter │ └── CreateAsyncOperation.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground └── LICENSE.markdown ├── 19-challenge-download-images-in-operationqueue ├── final │ └── DownloadImagesOperationQueue.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ ├── timeline.xctimeline │ │ ├── Sources │ │ └── AsyncOperation.swift │ │ └── Contents.swift ├── starter │ └── DownloadImagesOperationQueue.playground │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── contents.xcplayground │ │ ├── Contents.swift │ │ └── Sources │ │ └── AsyncOperation.swift └── LICENSE.markdown ├── 17-challenge-tiltshiftoperations-in-operationqueue ├── final │ └── TiltShiftOperationsInOperationQueue.playground │ │ ├── Resources │ │ ├── city.jpg │ │ ├── dark_road.jpg │ │ ├── train_day.jpg │ │ ├── train_dusk.jpg │ │ └── train_night.jpg │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground ├── starter │ └── TiltShiftOperationsInOperationQueue.playground │ │ ├── Resources │ │ ├── city.jpg │ │ ├── dark_road.jpg │ │ ├── train_day.jpg │ │ ├── train_dusk.jpg │ │ └── train_night.jpg │ │ ├── playground.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcplayground └── LICENSE.markdown └── README.md /01-introduction/final/ImageGrid/ImageGrid/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/DataRace/DataRace/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/DataRace/DataRace/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/DataRace/DataRace/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/DataRace/DataRace/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Assets.xcassets/launch-assets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /15-operations/final/Operations.playground/Resources/dark_road_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/15-operations/final/Operations.playground/Resources/dark_road_small.jpg -------------------------------------------------------------------------------- /15-operations/starter/Operations.playground/Resources/dark_road_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/15-operations/starter/Operations.playground/Resources/dark_road_small.jpg -------------------------------------------------------------------------------- /15-operations/final/Operations.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /15-operations/starter/Operations.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/final/Semaphores.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/Threadsafe.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /15-operations/starter/Operations.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/final/UseDispatchQueues.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/starter/Semaphores.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/DataRace/DataRace.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/DataRace/DataRace.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/Threadsafe.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /15-operations/final/Operations.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /16-operationqueues/final/ExploreOperationQueue.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/starter/UseDispatchQueues.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07-create-async-functions/final/UseGroupOfTasks.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/UseGroupOfTasks.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/Threadsafe.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /16-operationqueues/starter/ExploreOperationQueue.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /04-use-dispatch-work-items/final/UseDispatchWorkItem.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /04-use-dispatch-work-items/starter/UseDispatchWorkItem.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07-create-async-functions/final/DispatchGroupWaiting.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/DispatchGroupWaiting.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/final/WrapAsyncFunction.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/final/Images.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/starter/Images.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/final/Semaphores.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/starter/Semaphores.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/final/PriorityInversion.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/starter/PriorityInversion.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/DataRace/DataRace/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/Threadsafe.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /18-asynchronous-operations/final/CreateAsyncOperation.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /18-asynchronous-operations/starter/CreateAsyncOperation.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/01-introduction/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/01-introduction/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /03-use-dispatch-queues/final/UseDispatchQueues.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/starter/UseDispatchQueues.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07-create-async-functions/final/UseGroupOfTasks.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/UseGroupOfTasks.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/starter/WrapAsyncFunction.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/DataRace/DataRace/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /16-operationqueues/final/ExploreOperationQueue.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /16-operationqueues/starter/ExploreOperationQueue.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04-use-dispatch-work-items/final/UseDispatchWorkItem.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /04-use-dispatch-work-items/starter/UseDispatchWorkItem.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07-create-async-functions/final/DispatchGroupWaiting.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/DispatchGroupWaiting.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/final/Images.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/starter/Images.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/final/PriorityInversion.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /18-asynchronous-operations/final/CreateAsyncOperation.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/final/WrapAsyncFunction.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/starter/WrapAsyncFunction.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/starter/PriorityInversion.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /18-asynchronous-operations/starter/CreateAsyncOperation.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/20-dependencies/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/20-dependencies/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/final/DownloadImagesOperationQueue.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/22-cancel-operations/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/13-make-class-threadsafe/final/NameChanger/NameChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/starter/DownloadImagesOperationQueue.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/22-cancel-operations/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/13-make-class-threadsafe/starter/NameChanger/NameChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/city.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/city.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/city.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/city.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/final/DownloadImagesOperationQueue.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/starter/DownloadImagesOperationQueue.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/dark_road.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/dark_road.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/train_day.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/train_day.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/train_dusk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/train_dusk.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/train_night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/Resources/train_night.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/dark_road.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/dark_road.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/train_day.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/train_day.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/train_dusk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/train_dusk.jpg -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/train_night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/Resources/train_night.jpg -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/DataRace/DataRace/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/DataRace/DataRace/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kodecocodes/video-cgcdo-materials/HEAD/14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Assets.xcassets/AppIcon.appiconset/app-icon-white-FF5A00-bg.png -------------------------------------------------------------------------------- /15-operations/final/Operations.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /15-operations/starter/Operations.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/final/Semaphores.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/Threadsafe.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/final/UseDispatchQueues.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/starter/Semaphores.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/DataRace/DataRace.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/DataRace/DataRace.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/Threadsafe.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /16-operationqueues/final/ExploreOperationQueue.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/starter/UseDispatchQueues.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /07-create-async-functions/final/UseGroupOfTasks.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/UseGroupOfTasks.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /16-operationqueues/starter/ExploreOperationQueue.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /04-use-dispatch-work-items/final/UseDispatchWorkItem.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /04-use-dispatch-work-items/starter/UseDispatchWorkItem.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /07-create-async-functions/final/DispatchGroupWaiting.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/DispatchGroupWaiting.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/final/WrapAsyncFunction.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/final/Images.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/starter/Images.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/final/PriorityInversion.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/starter/PriorityInversion.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /18-asynchronous-operations/final/CreateAsyncOperation.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /18-asynchronous-operations/starter/CreateAsyncOperation.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/starter/WrapAsyncFunction.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/final/DownloadImagesOperationQueue.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app-icon-white-FF5A00-bg.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/starter/DownloadImagesOperationQueue.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/final/TiltShiftOperationsInOperationQueue.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/starter/TiltShiftOperationsInOperationQueue.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Assets.xcassets/launch-assets/logo-white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.svg", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | }, 12 | "properties" : { 13 | "preserves-vector-representation" : true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Assets.xcassets/launch-assets/orange FF5A00.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "color-space" : "srgb", 6 | "components" : { 7 | "alpha" : "1.000", 8 | "blue" : "0.000", 9 | "green" : "0.353", 10 | "red" : "1.000" 11 | } 12 | }, 13 | "idiom" : "universal" 14 | } 15 | ], 16 | "info" : { 17 | "author" : "xcode", 18 | "version" : 1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /16-operationqueues/final/ExploreOperationQueue.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/UseGroupOfTasks.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Use Group of Tasks 7 | let userQueue = DispatchQueue.global(qos: .userInitiated) 8 | let numberArray = [(0,1), (2,3), (4,5), (6,7), (8,9)] 9 | 10 | //: ## Creating a group 11 | print("=== Group of sync tasks ===\n") 12 | // TODO: Create slowAddGroup 13 | 14 | //: ## Dispatching to a group 15 | // TODO: Loop to add slowAdd tasks to group 16 | 17 | 18 | 19 | //: ## Notification of group completion 20 | //: Will be called only when every task in the dispatch group has completed 21 | let mainQueue = DispatchQueue.main 22 | // TODO: Call notify method 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/starter/PriorityInversion.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import Foundation 5 | import PlaygroundSupport 6 | //: # DispatchSemaphore 7 | // TODO: Create queues with high and low qos values 8 | 9 | let medium = DispatchQueue.global(qos: .userInitiated) 10 | 11 | // TODO: Create semaphore with value 1 12 | 13 | 14 | // TODO: Dispatch task that sleeps before calling semaphore.wait() 15 | 16 | 17 | for i in 1 ... 10 { 18 | medium.async { 19 | print("Running medium task \(i)") 20 | let waitTime = Double(Int.random(in: 0..<7)) 21 | Thread.sleep(forTimeInterval: waitTime) 22 | } 23 | } 24 | 25 | // TODO: Dispatch task that takes a long time 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS Concurrency with GCD & Operations: Materials 2 | 3 | This repo contains all the downloadable materials and projects associated with the **[iOS Concurrency with GCD & Operations](https://www.kodeco.com/38462287-ios-concurrency-with-gcd-operations)** from [Kodeco](https://www.kodeco.com). 4 | 5 | Each edition has its own branch, named `versions/[VERSION]`. The default branch for this repo is for the most recent edition. 6 | 7 | ## Release History 8 | 9 | | Branch | Version | Release Date | 10 | | ---------------------------------------------------------------------------------------- |:-------:|:------------:| 11 | | [versions/3.0](https://github.com/kodecocodes/video-cgcdo-materials/tree/versions/3.0) | 3.0 | 2020-06-23 | 12 | | [versions/4.0](https://github.com/kodecocodes/video-cgcdo-materials/tree/versions/4.0) | 4.0 | 2023-09-12 | 13 | -------------------------------------------------------------------------------- /15-operations/final/Operations.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /07-create-async-functions/final/UseGroupOfTasks.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Use Group of Tasks 7 | let userQueue = DispatchQueue.global(qos: .userInitiated) 8 | let numberArray = [(0,1), (2,3), (4,5), (6,7), (8,9)] 9 | 10 | //: ## Creating a group 11 | print("=== Group of sync tasks ===\n") 12 | // DONE: Create slowAddGroup 13 | let slowAddGroup = DispatchGroup() 14 | //: ## Dispatching to a group 15 | // DONE: Loop to add slowAdd tasks to group 16 | for inValue in numberArray { 17 | userQueue.async(group: slowAddGroup) { 18 | let result = slowAdd(inValue) 19 | print("Result = \(result)") 20 | } 21 | } 22 | 23 | 24 | //: ## Notification of group completion 25 | //: Will be called only when every task in the dispatch group has completed 26 | let mainQueue = DispatchQueue.main 27 | // DONE: Call notify method 28 | slowAddGroup.notify(queue: mainQueue) { 29 | print("SLOW ADD: Completed all tasks") 30 | sleep(3) 31 | PlaygroundPage.current.finishExecution() 32 | } 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /07-create-async-functions/starter/DispatchGroupWaiting.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # DispatchGroup Waiting 7 | //: You can make the current thread wait for a dispatch group to complete. 8 | //: 9 | //: __DANGER__ This is a synchronous call on the __current__ queue, so will block it. You cannot have anything in the group that needs to use the current queue, otherwise you'll deadlock. 10 | let group = DispatchGroup() 11 | let queue = DispatchQueue.global(qos: .userInitiated) 12 | 13 | queue.async(group: group) { 14 | print("Start task 1") 15 | // TODO: Sleep for 4 seconds 16 | print("End task 1") 17 | } 18 | 19 | queue.async(group: group) { 20 | print("Start task 2") 21 | // TODO: Sleep for 1 second 22 | print("End task 2") 23 | } 24 | 25 | group.notify(queue: DispatchQueue.global()) { 26 | // TODO: Announce completion, stop playground page 27 | 28 | 29 | } 30 | //: The tasks continue to run, even if the wait times out. 31 | // TODO: Wait for 5 seconds, then for 3 seconds 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/final/DownloadImagesOperationQueue.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/starter/WrapAsyncFunction.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Wrapping an Asynchronous Function for DispatchGroup 7 | //: There are lots of asynchronous APIs that don't have group parameters. What can you do with them, so the group knows when they *really* finish? 8 | //: 9 | //: Remember from Part 1 the `slowAdd` function you wrapped as an asynchronous function? 10 | let numberArray = [(0,1), (2,3), (4,5), (6,7), (8,9)] 11 | 12 | func asyncAdd(_ input: (Int, Int), 13 | runQueue: DispatchQueue = DispatchQueue.global(qos: .userInitiated), 14 | completionQueue: DispatchQueue = DispatchQueue.main, 15 | completion: @escaping (Result) -> ()) { 16 | runQueue.async { 17 | let result = slowAddPlus(input) 18 | completionQueue.async { completion(result) } 19 | } 20 | } 21 | //: Wrap `asyncAdd` function 22 | // TODO: Create asyncAdd_Group 23 | 24 | 25 | 26 | 27 | 28 | print("\n=== Group of async tasks ===\n") 29 | let wrappedGroup = DispatchGroup() 30 | 31 | for pair in numberArray { 32 | // TODO: use the new function here to calculate the sums of the array 33 | 34 | } 35 | 36 | // TODO: Notify of completion 37 | 38 | 39 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/final/PriorityInversion.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import Foundation 5 | import PlaygroundSupport 6 | //: # Priority Inversion 7 | // DONE: Create queues with high and low qos values 8 | let high = DispatchQueue.global(qos: .userInteractive) 9 | let medium = DispatchQueue.global(qos: .userInitiated) 10 | let low = DispatchQueue.global(qos: .background) 11 | // DONE: Create semaphore with value 1 12 | let semaphore = DispatchSemaphore(value: 1) 13 | 14 | // DONE: Dispatch task that sleeps before calling semaphore.wait() 15 | high.async { 16 | sleep(2) 17 | print("High priority task is now waiting") 18 | semaphore.wait() 19 | defer { semaphore.signal() } 20 | print("High priority task is now running") 21 | sleep(1) 22 | PlaygroundPage.current.finishExecution() 23 | } 24 | 25 | for i in 1 ... 10 { 26 | medium.async { 27 | print("Running medium task \(i)") 28 | let waitTime = Double(Int.random(in: 0..<7)) 29 | Thread.sleep(forTimeInterval: waitTime) 30 | } 31 | } 32 | 33 | // DONE: Dispatch task that takes a long time 34 | low.async { 35 | semaphore.wait() 36 | defer { semaphore.signal() } 37 | print("Low priority task is now running") 38 | sleep(5) 39 | } 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /07-create-async-functions/final/DispatchGroupWaiting.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # DispatchGroup Waiting 7 | //: You can make the current thread wait for a dispatch group to complete. 8 | //: 9 | //: __DANGER__ This is a synchronous call on the __current__ queue, so will block it. You cannot have anything in the group that needs to use the current queue, otherwise you'll deadlock. 10 | let group = DispatchGroup() 11 | let queue = DispatchQueue.global(qos: .userInitiated) 12 | 13 | queue.async(group: group) { 14 | print("Start task 1") 15 | // DONE: Sleep for 4 seconds 16 | sleep(4) 17 | print("End task 1") 18 | } 19 | 20 | queue.async(group: group) { 21 | print("Start task 2") 22 | // DONE: Sleep for 1 second 23 | sleep(1) 24 | print("End task 2") 25 | } 26 | 27 | group.notify(queue: DispatchQueue.global()) { 28 | // DONE: Announce completion, stop playground page 29 | print("All tasks completed at last!") 30 | sleep(1) 31 | PlaygroundPage.current.finishExecution() 32 | } 33 | //: The tasks continue to run, even if the wait times out. 34 | // DONE: Wait for 5 seconds, then for 3 seconds 35 | if group.wait(timeout: .now() + 3) == .timedOut { 36 | print("I got tired of waiting.") 37 | } else { 38 | print("All the tasks have completed.") 39 | } 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/starter/Images.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Download a Group of Images 7 | let group = DispatchGroup() 8 | let queue = DispatchQueue.global() 9 | 10 | let base = "https://cdn.kodeco.com/books/con/image-from-rawpixel-id-" 11 | let ids = [466881, 466910, 466925, 466931, 466978, 467028, 467032, 467042, 467052] 12 | var images: [UIImage] = [] 13 | //: Use a dispatch group to download these images and perform these actions when all the images have finished downloading: Print "All done!", show images[0] and terminate the playground. 14 | // Hint 1: How to download one image 15 | let url = URL(string: "\(base)\(ids[0])-jpeg.jpg")! 16 | URLSession.shared.dataTask(with: url) { data, response, error in 17 | if error == nil, let data = data, let image = UIImage(data: data) { 18 | images.append(image) 19 | } 20 | }.resume() 21 | 22 | // Step 1: Fill in this DispatchGroup wrapper 23 | func dataTask_Group(with url: URL, group: DispatchGroup, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) { 24 | 25 | 26 | 27 | 28 | } 29 | 30 | for id in ids { 31 | guard let url = URL(string: "\(base)\(id)-jpeg.jpg") else { continue } 32 | // Step 2: Call dataTask_Group 33 | 34 | 35 | 36 | 37 | } 38 | 39 | // Step 3: Fill in group.notify handler 40 | group.notify(queue: queue) { 41 | 42 | 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /16-operationqueues/starter/ExploreOperationQueue.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Explore OperationQueue 7 | //: `OperationQueue` is responsible for scheduling and running a set of operations, somewhere in the background. 8 | //: ## Creating a queue 9 | //: Creating a queue is simple, using the default initializer; you can also set the maximum number of queued operations that can execute at the same time: 10 | // TODO: Create printerQueue 11 | 12 | // TODO later: Set maximum to 2 13 | //: ## Adding `Operations` to Queues 14 | /*: `Operation`s can be added to queues directly as closures 15 | - important: 16 | Adding operations to a queue is really "cheap"; although the operations can start executing as soon as they arrive on the queue, adding them is completely asynchronous. 17 | \ 18 | You can see that here, with the result of the `duration` function: 19 | */ 20 | // Uncomment these lines: Add 5 operations to printerQueue 21 | //duration { 22 | // printerQueue.addOperation { print("Hello"); sleep(3) } 23 | // printerQueue.addOperation { print("my"); sleep(3) } 24 | // printerQueue.addOperation { print("name"); sleep(3) } 25 | // printerQueue.addOperation { print("is"); sleep(3) } 26 | // printerQueue.addOperation { print("Audrey"); sleep(3) } 27 | //} 28 | 29 | // TODO: Measure duration of all operations 30 | 31 | PlaygroundPage.current.finishExecution() 32 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/starter/Semaphores.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # DispatchSemaphore 7 | let group = DispatchGroup() 8 | let queue = DispatchQueue.global(qos: .userInteractive) 9 | // TODO: Create a semaphore that allows four concurrent accesses 10 | 11 | // TODO: Simulate downloading group of images 12 | 13 | 14 | 15 | 16 | 17 | 18 | // Really download group of images 19 | let base = "https://wolverine.raywenderlich.com/books/con/image-from-rawpixel-id-" 20 | let ids = [466881, 466910, 466925, 466931, 466978, 467028, 467032, 467042, 467052] 21 | var images: [UIImage] = [] 22 | 23 | // TODO: Add semaphore argument to dataTask_Group 24 | func dataTask_Group_Semaphore( 25 | with url: URL, 26 | group: DispatchGroup, 27 | completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) { 28 | // TODO: wait for semaphore before entering group 29 | 30 | group.enter() 31 | URLSession.shared.dataTask(with: url) { data, response, error in 32 | defer { 33 | group.leave() 34 | // TODO: signal the semaphore after leaving the group 35 | 36 | } 37 | completionHandler(data, response, error) 38 | }.resume() 39 | } 40 | 41 | duration { 42 | for id in ids { 43 | guard let url = URL(string: "\(base)\(id)-jpeg.jpg") else { continue } 44 | // TODO: Call dataTask_Group_Semaphore 45 | 46 | } 47 | 48 | group.notify(queue: queue) { 49 | print("All done!") 50 | images[0] 51 | PlaygroundPage.current.finishExecution() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /16-operationqueues/final/ExploreOperationQueue.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Explore OperationQueue 7 | //: `OperationQueue` is responsible for scheduling and running a set of operations, somewhere in the background. 8 | //: ## Creating a queue 9 | //: Creating a queue is simple, using the default initializer; you can also set the maximum number of queued operations that can execute at the same time: 10 | // DONE: Create printerQueue 11 | let printerQueue = OperationQueue() 12 | // DONE later: Set maximum to 2 13 | printerQueue.maxConcurrentOperationCount = 2 14 | //: ## Adding `Operations` to Queues 15 | /*: `Operation`s can be added to queues directly as closures 16 | - important: 17 | Adding operations to a queue is really "cheap"; although the operations can start executing as soon as they arrive on the queue, adding them is completely asynchronous. 18 | \ 19 | You can see that here, with the result of the `duration` function: 20 | */ 21 | // Uncomment these lines: Add 5 operations to printerQueue 22 | duration { 23 | printerQueue.addOperation { print("Hello"); sleep(3) } 24 | printerQueue.addOperation { print("my"); sleep(3) } 25 | printerQueue.addOperation { print("name"); sleep(3) } 26 | printerQueue.addOperation { print("is"); sleep(3) } 27 | printerQueue.addOperation { print("Audrey"); sleep(3) } 28 | } 29 | 30 | // DONE: Measure duration of all operations 31 | duration { 32 | printerQueue.waitUntilAllOperationsAreFinished() 33 | } 34 | PlaygroundPage.current.finishExecution() 35 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/starter/DownloadImagesOperationQueue.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Downloading Images in an OperationQueue 7 | //: Subclass `AsyncOperation` to create an operation that 8 | //: uses `URLSession` `dataTask(with:)` to download an image. 9 | //: Then use this in an `OperationQueue` to download the images 10 | //: represented by the `ids` array. 11 | class ImageLoadOperation: AsyncOperation { 12 | private let url: URL 13 | var image: UIImage? 14 | 15 | init(url: URL) { 16 | self.url = url 17 | super.init() 18 | } 19 | 20 | // TODO: Call dataTask with url and save image 21 | override func main() { 22 | 23 | } 24 | } 25 | //: For each `id`, create a `url`. 26 | //: Then, for each url, create an `ImageLoadOperation`, 27 | //: and add it to an `OperationQueue`. 28 | //: When each operation completes, add its output `image` to the `images` array. 29 | let base = "https://cdn.kodeco.com/books/con/image-from-rawpixel-id-" 30 | let ids = [466881, 466910, 466925, 466931, 466978, 467028, 467032, 467042, 467052] 31 | var images: [UIImage] = [] 32 | let queue = OperationQueue() 33 | 34 | for id in ids { 35 | guard let url = URL(string: "\(base)\(id)-jpeg.jpg") else { continue } 36 | // TODO: Create operation with completionBlock and add to queue 37 | 38 | } 39 | 40 | duration { 41 | queue.waitUntilAllOperationsAreFinished() 42 | } 43 | sleep(1) // give playground time to finish counting 44 | 45 | images[8] 46 | 47 | PlaygroundPage.current.finishExecution() 48 | -------------------------------------------------------------------------------- /15-operations/starter/Operations.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Operations 7 | //: An `Operation` represents a 'unit of work', and can be constructed as a `BlockOperation` or as a custom subclass of `Operation`. 8 | //: ## BlockOperation 9 | //: Create a `BlockOperation` to add two numbers 10 | var result: Int? 11 | // TODO: Create and run sumOperation 12 | 13 | 14 | 15 | 16 | //: Run a `BlockOperation` with multiple blocks: 17 | let multiPrinter = BlockOperation() 18 | multiPrinter.addExecutionBlock { print("Hello"); sleep(2) } 19 | multiPrinter.addExecutionBlock { print("my"); sleep(2) } 20 | multiPrinter.addExecutionBlock { print("name"); sleep(2) } 21 | multiPrinter.addExecutionBlock { print("is"); sleep(2) } 22 | multiPrinter.addExecutionBlock { print("Audrey"); sleep(2) } 23 | 24 | //multiPrinter.completionBlock = { 25 | // print("Finished multiPrinting!") 26 | //} 27 | 28 | duration { 29 | multiPrinter.start() 30 | } 31 | 32 | //: ## Subclassing `Operation` 33 | //: Allows you more control over precisely what the `Operation` is doing 34 | let inputImage = UIImage(named: "dark_road_small.jpg") 35 | // TODO: Create TiltShiftOperation 36 | class TiltShiftOperation: Operation { 37 | private static let context = CIContext() 38 | 39 | // TODO: Add input & output properties and init 40 | 41 | 42 | 43 | override func main() { 44 | // TODO: Filter the input image 45 | 46 | 47 | // TODO: Create a CGImage 48 | // let fromRect = CGRect(origin: .zero, size: inputImage.size) 49 | 50 | // TODO: Create and output a UIImage 51 | 52 | } 53 | } 54 | 55 | // TODO: Run TiltShiftOperation 56 | 57 | 58 | 59 | PlaygroundPage.current.finishExecution() 60 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/NameChanger/NameChanger/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/starter/NameChanger/NameChanger/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/final/ImageGrid/ImageGrid/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /06-the-right-way-to-download-images/starter/ImageGrid/ImageGrid/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/final/ImageGrid/ImageGrid/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /05-challenge-a-better-way-to-download-images/starter/ImageGrid/ImageGrid/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/final/NumberChanger/NumberChanger/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /14-challenge-make-number-class-threadsafe/starter/NumberChanger/NumberChanger/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIRequiredDeviceCapabilities 31 | 32 | armv7 33 | 34 | UIStatusBarHidden 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/final/DownloadImagesOperationQueue.playground/Sources/AsyncOperation.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import Foundation 5 | 6 | extension AsyncOperation { 7 | public enum State: String { 8 | case ready, executing, finished 9 | 10 | fileprivate var keyPath: String { 11 | "is\(rawValue.capitalized)" 12 | } 13 | } 14 | } 15 | 16 | open class AsyncOperation: Operation { 17 | // Create thread-safe state management 18 | private let stateQueue = DispatchQueue(label: "AsyncOperationState", 19 | attributes: .concurrent) 20 | private var stateValue: State = .ready 21 | public var state: State { 22 | get { 23 | stateQueue.sync { return stateValue } 24 | } 25 | set { 26 | let oldValue = state 27 | willChangeValue(forKey: newValue.keyPath) 28 | willChangeValue(forKey: state.keyPath) 29 | stateQueue.sync(flags: .barrier) { 30 | stateValue = newValue 31 | } 32 | didChangeValue(forKey: oldValue.keyPath) 33 | didChangeValue(forKey: state.keyPath) 34 | } 35 | } 36 | 37 | // Override properties 38 | override open var isReady: Bool { 39 | super.isReady && state == .ready 40 | } 41 | 42 | override open var isExecuting: Bool { 43 | state == .executing 44 | } 45 | 46 | override open var isFinished: Bool { 47 | state == .finished 48 | } 49 | 50 | override open var isAsynchronous: Bool { 51 | true 52 | } 53 | 54 | // Override methods 55 | override open func start() { 56 | if isCancelled { 57 | state = .finished 58 | return 59 | } 60 | main() 61 | state = .executing 62 | } 63 | 64 | override open func cancel() { 65 | super.cancel() 66 | state = .finished 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/starter/DownloadImagesOperationQueue.playground/Sources/AsyncOperation.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import Foundation 5 | 6 | extension AsyncOperation { 7 | public enum State: String { 8 | case ready, executing, finished 9 | 10 | fileprivate var keyPath: String { 11 | "is\(rawValue.capitalized)" 12 | } 13 | } 14 | } 15 | 16 | open class AsyncOperation: Operation { 17 | // Create thread-safe state management 18 | private let stateQueue = DispatchQueue(label: "AsyncOperationState", 19 | attributes: .concurrent) 20 | private var stateValue: State = .ready 21 | public var state: State { 22 | get { 23 | stateQueue.sync { return stateValue } 24 | } 25 | set { 26 | let oldValue = state 27 | willChangeValue(forKey: newValue.keyPath) 28 | willChangeValue(forKey: state.keyPath) 29 | stateQueue.sync(flags: .barrier) { 30 | stateValue = newValue 31 | } 32 | didChangeValue(forKey: oldValue.keyPath) 33 | didChangeValue(forKey: state.keyPath) 34 | } 35 | } 36 | 37 | // Override properties 38 | override open var isReady: Bool { 39 | super.isReady && state == .ready 40 | } 41 | 42 | override open var isExecuting: Bool { 43 | state == .executing 44 | } 45 | 46 | override open var isFinished: Bool { 47 | state == .finished 48 | } 49 | 50 | override open var isAsynchronous: Bool { 51 | true 52 | } 53 | 54 | // Override methods 55 | override open func start() { 56 | if isCancelled { 57 | state = .finished 58 | return 59 | } 60 | main() 61 | state = .executing 62 | } 63 | 64 | override open func cancel() { 65 | super.cancel() 66 | state = .finished 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /09-challenge-download-a-group-of-images/final/Images.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Download a Group of Images 7 | let group = DispatchGroup() 8 | let queue = DispatchQueue.global() 9 | 10 | let base = "https://cdn.kodeco.com/books/con/image-from-rawpixel-id-" 11 | let ids = [466881, 466910, 466925, 466931, 466978, 467028, 467032, 467042, 467052] 12 | var images: [UIImage] = [] 13 | //: Use a dispatch group to download these images and perform these actions when all the images have finished downloading: Print "All done!", show images[0] and terminate the playground. 14 | // Hint 1: How to download one image 15 | let url = URL(string: "\(base)\(ids[0])-jpeg.jpg")! 16 | URLSession.shared.dataTask(with: url) { data, response, error in 17 | if error == nil, let data = data, let image = UIImage(data: data) { 18 | images.append(image) 19 | } 20 | }.resume() 21 | 22 | // Step 1: Fill in this DispatchGroup wrapper 23 | func dataTask_Group(with url: URL, group: DispatchGroup, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) { 24 | group.enter() 25 | URLSession.shared.dataTask(with: url) { data, response, error in 26 | defer { group.leave() } 27 | completionHandler(data, response, error) 28 | }.resume() 29 | } 30 | 31 | for id in ids { 32 | guard let url = URL(string: "\(base)\(id)-jpeg.jpg") else { continue } 33 | // Step 2: Call dataTask_Group 34 | dataTask_Group(with: url, group: group) { data, _, error in 35 | if error == nil, let data = data, let image = UIImage(data: data) { 36 | images.append(image) 37 | } 38 | } 39 | } 40 | 41 | // Step 3: Fill in group.notify handler 42 | group.notify(queue: queue) { 43 | print("All done!") 44 | images[0] 45 | PlaygroundPage.current.finishExecution() 46 | } 47 | -------------------------------------------------------------------------------- /15-operations/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /16-operationqueues/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/final/Semaphores.playground/Sources/Duration.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | /// THE SOFTWARE. 28 | 29 | import Foundation 30 | 31 | public func duration(_ block: () -> ()) -> TimeInterval { 32 | let startTime = Date() 33 | block() 34 | return Date().timeIntervalSince(startTime) 35 | } 36 | -------------------------------------------------------------------------------- /10-use-dispatchsemaphore/starter/Semaphores.playground/Sources/Duration.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | /// THE SOFTWARE. 28 | 29 | import Foundation 30 | 31 | public func duration(_ block: () -> ()) -> TimeInterval { 32 | let startTime = Date() 33 | block() 34 | return Date().timeIntervalSince(startTime) 35 | } 36 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/final/UseDispatchQueues.playground/Sources/Duration.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | /// THE SOFTWARE. 28 | 29 | import Foundation 30 | 31 | public func duration(_ block: () -> ()) -> TimeInterval { 32 | let startTime = Date() 33 | block() 34 | return Date().timeIntervalSince(startTime) 35 | } 36 | -------------------------------------------------------------------------------- /03-use-dispatch-queues/starter/UseDispatchQueues.playground/Sources/Duration.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | /// THE SOFTWARE. 28 | 29 | import Foundation 30 | 31 | public func duration(_ block: () -> ()) -> TimeInterval { 32 | let startTime = Date() 33 | block() 34 | return Date().timeIntervalSince(startTime) 35 | } 36 | -------------------------------------------------------------------------------- /04-use-dispatch-work-items/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /07-create-async-functions/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /12-explore-priority-inversion/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /18-asynchronous-operations/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /17-challenge-tiltshiftoperations-in-operationqueue/LICENSE.markdown: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | -------------------------------------------------------------------------------- /08-wrap-an-asynchronous-function/final/WrapAsyncFunction.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Wrapping an Asynchronous Function for DispatchGroup 7 | //: There are lots of asynchronous APIs that don't have group parameters. What can you do with them, so the group knows when they *really* finish? 8 | //: 9 | //: Remember from Part 1 the `slowAdd` function you wrapped as an asynchronous function? 10 | let numberArray = [(0,1), (2,3), (4,5), (6,7), (8,9)] 11 | 12 | func asyncAdd(_ input: (Int, Int), 13 | runQueue: DispatchQueue = DispatchQueue.global(qos: .userInitiated), 14 | completionQueue: DispatchQueue = DispatchQueue.main, 15 | completion: @escaping (Result) -> ()) { 16 | runQueue.async { 17 | let result = slowAddPlus(input) 18 | completionQueue.async { completion(result) } 19 | } 20 | } 21 | //: Wrap `asyncAdd` function 22 | // DONE: Create asyncAdd_Group 23 | func asyncAdd_Group( 24 | _ input: (Int, Int), 25 | runQueue: DispatchQueue = DispatchQueue.global(qos: .userInitiated), 26 | completionQueue: DispatchQueue = DispatchQueue.main, 27 | group: DispatchGroup, 28 | completion: @escaping (Result) -> ()) { 29 | group.enter() 30 | asyncAdd(input) { result in 31 | defer { group.leave() } 32 | completionQueue.async { 33 | completion(result) 34 | } 35 | } 36 | } 37 | 38 | 39 | print("\n=== Group of async tasks ===\n") 40 | let wrappedGroup = DispatchGroup() 41 | 42 | for pair in numberArray { 43 | // DONE: use the new function here to calculate the sums of the array 44 | asyncAdd_Group(pair, group: wrappedGroup) { result in 45 | print("Result = \(result)") 46 | } 47 | } 48 | 49 | // DONE: Notify of completion 50 | wrappedGroup.notify(queue: DispatchQueue.main) { 51 | print("WRAPPED ASYNC ADD: Completed all tasks") 52 | sleep(1) 53 | PlaygroundPage.current.finishExecution() 54 | } 55 | 56 | -------------------------------------------------------------------------------- /19-challenge-download-images-in-operationqueue/final/DownloadImagesOperationQueue.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2023 Kodeco Inc. 2 | // For full license & permission details, see LICENSE.markdown. 3 | 4 | import UIKit 5 | import PlaygroundSupport 6 | //: # Downloading Images in an OperationQueue 7 | //: Subclass `AsyncOperation` to create an operation that 8 | //: uses `URLSession` `dataTask(with:)` to download an image. 9 | //: Then use this in an `OperationQueue` to download the images 10 | //: represented by the `ids` array. 11 | class ImageLoadOperation: AsyncOperation { 12 | private let url: URL 13 | var image: UIImage? 14 | 15 | init(url: URL) { 16 | self.url = url 17 | super.init() 18 | } 19 | 20 | // DONE: Call dataTask with url and save image 21 | override func main() { 22 | URLSession.shared.dataTask(with: url) { 23 | [weak self] data, response, error in 24 | guard let self else { return } 25 | defer { self.state = .finished } 26 | guard error == nil, let data else { return } 27 | image = UIImage(data: data) 28 | } 29 | .resume() 30 | } 31 | } 32 | //: For each `id`, create a `url`. 33 | //: Then, for each url, create an `ImageLoadOperation`, 34 | //: and add it to an `OperationQueue`. 35 | //: When each operation completes, add its output `image` to the `images` array. 36 | let base = "https://cdn.kodeco.com/books/con/image-from-rawpixel-id-" 37 | let ids = [466881, 466910, 466925, 466931, 466978, 467028, 467032, 467042, 467052] 38 | var images: [UIImage] = [] 39 | let queue = OperationQueue() 40 | 41 | for id in ids { 42 | guard let url = URL(string: "\(base)\(id)-jpeg.jpg") else { continue } 43 | // DONE: Create operation with completionBlock and add to queue 44 | let op = ImageLoadOperation(url: url) 45 | op.completionBlock = { 46 | if let image = op.image { images.append(image) } 47 | } 48 | queue.addOperation(op) 49 | } 50 | 51 | duration { 52 | queue.waitUntilAllOperationsAreFinished() 53 | } 54 | sleep(1) // give playground time to finish counting 55 | 56 | images[8] 57 | 58 | PlaygroundPage.current.finishExecution() 59 | -------------------------------------------------------------------------------- /20-dependencies/final/FilterImages/FilterImages/ImageDataProvider.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import UIKit 34 | 35 | protocol ImageDataProvider { 36 | var image: UIImage? { get } 37 | } 38 | -------------------------------------------------------------------------------- /20-dependencies/starter/FilterImages/FilterImages/ImageDataProvider.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import UIKit 34 | 35 | protocol ImageDataProvider { 36 | var image: UIImage? { get } 37 | } 38 | -------------------------------------------------------------------------------- /22-cancel-operations/final/FilterImages/FilterImages/ImageDataProvider.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2020 Razeware LLC 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import UIKit 34 | 35 | protocol ImageDataProvider { 36 | var image: UIImage? { get } 37 | } 38 | -------------------------------------------------------------------------------- /22-cancel-operations/starter/FilterImages/FilterImages/ImageDataProvider.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2020 Razeware LLC 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import UIKit 34 | 35 | protocol ImageDataProvider { 36 | var image: UIImage? { get } 37 | } 38 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/final/FilterImages/FilterImages/ImageDataProvider.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2020 Razeware LLC 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import UIKit 34 | 35 | protocol ImageDataProvider { 36 | var image: UIImage? { get } 37 | } 38 | -------------------------------------------------------------------------------- /21-challenge-implement-a-dependency/starter/FilterImages/FilterImages/ImageDataProvider.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2020 Razeware LLC 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import UIKit 34 | 35 | protocol ImageDataProvider { 36 | var image: UIImage? { get } 37 | } 38 | -------------------------------------------------------------------------------- /01-introduction/final/ImageGrid/ImageGrid/ImageGridApp.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import SwiftUI 34 | 35 | @main 36 | struct ImageGridApp: App { 37 | var body: some Scene { 38 | WindowGroup { 39 | ContentView() 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /01-introduction/starter/ImageGrid/ImageGrid/ImageGridApp.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import SwiftUI 34 | 35 | @main 36 | struct ImageGridApp: App { 37 | var body: some Scene { 38 | WindowGroup { 39 | ContentView() 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /13-make-class-threadsafe/final/DataRace/DataRace/DataRaceApp.swift: -------------------------------------------------------------------------------- 1 | /// Copyright (c) 2023 Kodeco Inc. 2 | /// 3 | /// Permission is hereby granted, free of charge, to any person obtaining a copy 4 | /// of this software and associated documentation files (the "Software"), to deal 5 | /// in the Software without restriction, including without limitation the rights 6 | /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | /// copies of the Software, and to permit persons to whom the Software is 8 | /// furnished to do so, subject to the following conditions: 9 | /// 10 | /// The above copyright notice and this permission notice shall be included in 11 | /// all copies or substantial portions of the Software. 12 | /// 13 | /// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, 14 | /// distribute, sublicense, create a derivative work, and/or sell copies of the 15 | /// Software in any work that is designed, intended, or marketed for pedagogical or 16 | /// instructional purposes related to programming, coding, application development, 17 | /// or information technology. Permission for such use, copying, modification, 18 | /// merger, publication, distribution, sublicensing, creation of derivative works, 19 | /// or sale is expressly withheld. 20 | /// 21 | /// This project and source code may use libraries or frameworks that are 22 | /// released under various Open-Source licenses. Use of those libraries and 23 | /// frameworks are governed by their own individual licenses. 24 | /// 25 | /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 | /// THE SOFTWARE. 32 | 33 | import SwiftUI 34 | 35 | @main 36 | struct DataRaceApp: App { 37 | var body: some Scene { 38 | WindowGroup { 39 | ContentView() 40 | } 41 | } 42 | } 43 | --------------------------------------------------------------------------------