├── 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 |
--------------------------------------------------------------------------------