├── CODEOWNERS
├── software-design-principles
├── dry-principle
│ ├── starter
│ │ └── DRY
│ │ │ ├── DRY
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── profile_photo.imageset
│ │ │ │ │ ├── profile_photo.png
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── User.swift
│ │ │ ├── ProfileViewController.swift
│ │ │ ├── WelcomeViewController.swift
│ │ │ ├── Info.plist
│ │ │ ├── Base.lproj
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ └── AppDelegate.swift
│ │ │ └── DRY.xcodeproj
│ │ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ └── solution
│ │ └── DRY
│ │ ├── DRY
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ ├── profile_photo.imageset
│ │ │ │ ├── profile_photo.png
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── User.swift
│ │ ├── ProfileViewController.swift
│ │ ├── WelcomeViewController.swift
│ │ ├── Info.plist
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ └── AppDelegate.swift
│ │ └── DRY.xcodeproj
│ │ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── dependency-inversion-principle
│ ├── solution
│ │ └── ImageCache.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── ImageCache.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── liskov-substitution-principle
│ ├── starter
│ │ └── RectangleArea.playground
│ │ │ ├── contents.xcplayground
│ │ │ └── Contents.swift
│ └── solution
│ │ └── RectangleArea.playground
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace
│ │ └── contents.xcworkspacedata
│ │ └── Contents.swift
├── interface-segregation-principle
│ ├── solution
│ │ └── InterfaceSegregationPlayground.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── InterfaceSegregationPlayground.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── open-closed-principle
│ ├── starter
│ │ └── AreaCalculator
│ │ │ ├── AreaCalculator.xcodeproj
│ │ │ └── project.xcworkspace
│ │ │ │ └── contents.xcworkspacedata
│ │ │ └── AreaCalculator
│ │ │ ├── AreaCalculator.swift
│ │ │ ├── ViewController.swift
│ │ │ ├── Info.plist
│ │ │ ├── Base.lproj
│ │ │ ├── Main.storyboard
│ │ │ └── LaunchScreen.storyboard
│ │ │ ├── Assets.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── AppDelegate.swift
│ └── solution
│ │ └── AreaCalculator
│ │ ├── AreaCalculator.xcodeproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── AreaCalculator
│ │ ├── ViewController.swift
│ │ ├── AreaCalculator.swift
│ │ ├── Info.plist
│ │ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── AppDelegate.swift
└── single-responsibility-principle
│ ├── starter
│ └── SingleResponsibilityPrinciple
│ │ ├── SingleResponsibilityPrinciple.xcodeproj
│ │ └── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── SingleResponsibilityPrinciple
│ │ ├── ViewController.swift
│ │ ├── Game.swift
│ │ ├── Info.plist
│ │ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── AppDelegate.swift
│ └── solution
│ └── SingleResponsibilityPrinciple
│ ├── SingleResponsibilityPrinciple.xcodeproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── SingleResponsibilityPrinciple
│ ├── ViewController.swift
│ ├── Game.swift
│ ├── Info.plist
│ ├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ └── AppDelegate.swift
├── creational-design-patterns
├── object-pool
│ ├── solution
│ │ └── ObjectPool
│ │ │ ├── ObjectPool
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── snowflake.imageset
│ │ │ │ │ ├── snowflake.png
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── Info.plist
│ │ │ ├── Base.lproj
│ │ │ │ ├── Main.storyboard
│ │ │ │ └── LaunchScreen.storyboard
│ │ │ ├── AppDelegate.swift
│ │ │ └── ViewController.swift
│ │ │ └── ObjectPool.xcodeproj
│ │ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── project.pbxproj
│ └── starter
│ │ └── ObjectPool
│ │ ├── ObjectPool
│ │ ├── Assets.xcassets
│ │ │ ├── Contents.json
│ │ │ ├── snowflake.imageset
│ │ │ │ ├── snowflake.png
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── Base.lproj
│ │ │ ├── Main.storyboard
│ │ │ └── LaunchScreen.storyboard
│ │ ├── AppDelegate.swift
│ │ └── ViewController.swift
│ │ └── ObjectPool.xcodeproj
│ │ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ │ └── project.pbxproj
├── builder
│ ├── solution
│ │ └── FormSubmission.playground
│ │ │ ├── contents.xcplayground
│ │ │ └── Contents.swift
│ └── starter
│ │ └── FormSubmission.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── factory-methods
│ ├── solution
│ │ └── Music.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── Music.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── singleton
│ ├── solution
│ │ └── Singleton.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── Singleton.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── dependency-injection
│ ├── solution
│ │ └── ImageCache.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── ImageCache.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
└── builder-exercise
│ └── SignUpApp
│ ├── SignUpApp.xcodeproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── SignUpApp
│ ├── SignUpForm.swift
│ ├── EmailVIewController.swift
│ ├── PasswordViewController.swift
│ ├── UsernameViewController.swift
│ ├── Info.plist
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ └── AppDelegate.swift
├── anti-patterns
├── god-object-exercise
│ └── GodObjectExercise.playground
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace
│ │ └── contents.xcworkspacedata
│ │ └── Contents.swift
└── deep-inheritance-exercise
│ └── DeepInheritanceExercise.playground
│ ├── contents.xcplayground
│ └── Contents.swift
├── structural-design-patterns
├── adapter
│ ├── solution
│ │ └── Adapter.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── Adapter.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── facade
│ ├── starter
│ │ └── OrderFacade.playground
│ │ │ ├── contents.xcplayground
│ │ │ └── Contents.swift
│ └── solution
│ │ └── OrderFacade.playground
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace
│ │ └── contents.xcworkspacedata
│ │ └── Contents.swift
└── decorator
│ ├── solution
│ └── Decorators.playground
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace
│ │ └── contents.xcworkspacedata
│ │ └── Contents.swift
│ └── starter
│ └── Decorators.playground
│ ├── contents.xcplayground
│ └── Contents.swift
├── behavioral-design-patterns
├── command
│ ├── solution
│ │ └── MusicPlayer.playground
│ │ │ ├── contents.xcplayground
│ │ │ └── Contents.swift
│ └── starter
│ │ └── MusicPlayer.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── mediator
│ ├── solution
│ │ └── EmailSender.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── EmailSender.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
├── observer
│ ├── solution
│ │ └── LocationPlayground.playground
│ │ │ ├── contents.xcplayground
│ │ │ ├── playground.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ │ └── Contents.swift
│ └── starter
│ │ └── LocationPlayground.playground
│ │ ├── contents.xcplayground
│ │ ├── playground.xcworkspace
│ │ └── contents.xcworkspacedata
│ │ └── Contents.swift
└── chain-of-responsibility
│ ├── solution
│ └── ImageProcessing.playground
│ │ ├── contents.xcplayground
│ │ └── Contents.swift
│ └── starter
│ └── ImageProcessing.playground
│ ├── contents.xcplayground
│ └── Contents.swift
├── .gitignore
├── .github
└── workflows
│ └── manual.yml
└── README.md
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @udacity/active-public-content
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/anti-patterns/god-object-exercise/GodObjectExercise.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/structural-design-patterns/adapter/solution/Adapter.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/structural-design-patterns/adapter/starter/Adapter.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/structural-design-patterns/facade/starter/OrderFacade.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/command/solution/MusicPlayer.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/command/starter/MusicPlayer.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/mediator/solution/EmailSender.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/mediator/starter/EmailSender.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder/solution/FormSubmission.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder/starter/FormSubmission.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/factory-methods/solution/Music.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/factory-methods/starter/Music.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/singleton/solution/Singleton.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/singleton/starter/Singleton.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/structural-design-patterns/decorator/solution/Decorators.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/structural-design-patterns/decorator/starter/Decorators.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/structural-design-patterns/facade/solution/OrderFacade.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/anti-patterns/deep-inheritance-exercise/DeepInheritanceExercise.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/anti-patterns/god-object-exercise/GodObjectExercise.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/observer/solution/LocationPlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/observer/starter/LocationPlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/structural-design-patterns/adapter/solution/Adapter.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/mediator/solution/EmailSender.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/creational-design-patterns/dependency-injection/solution/ImageCache.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/dependency-injection/starter/ImageCache.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/singleton/solution/Singleton.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/structural-design-patterns/decorator/solution/Decorators.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/structural-design-patterns/facade/solution/OrderFacade.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/creational-design-patterns/factory-methods/solution/Music.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/chain-of-responsibility/solution/ImageProcessing.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/chain-of-responsibility/starter/ImageProcessing.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/observer/solution/LocationPlayground.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/observer/starter/LocationPlayground.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/dependency-inversion-principle/solution/ImageCache.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/software-design-principles/dependency-inversion-principle/starter/ImageCache.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/liskov-substitution-principle/starter/RectangleArea.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/dependency-injection/solution/ImageCache.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/Assets.xcassets/profile_photo.imageset/profile_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/udacity/iosnd-design-patterns/HEAD/software-design-principles/dry-principle/solution/DRY/DRY/Assets.xcassets/profile_photo.imageset/profile_photo.png
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/Assets.xcassets/profile_photo.imageset/profile_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/udacity/iosnd-design-patterns/HEAD/software-design-principles/dry-principle/starter/DRY/DRY/Assets.xcassets/profile_photo.imageset/profile_photo.png
--------------------------------------------------------------------------------
/software-design-principles/liskov-substitution-principle/solution/RectangleArea.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder/starter/FormSubmission.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | struct SignUpSubmission {
6 | let username: String
7 | let email: String
8 | let phoneNumber: String
9 | }
10 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/Assets.xcassets/snowflake.imageset/snowflake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/udacity/iosnd-design-patterns/HEAD/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/Assets.xcassets/snowflake.imageset/snowflake.png
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/Assets.xcassets/snowflake.imageset/snowflake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/udacity/iosnd-design-patterns/HEAD/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/Assets.xcassets/snowflake.imageset/snowflake.png
--------------------------------------------------------------------------------
/software-design-principles/dependency-inversion-principle/solution/ImageCache.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/liskov-substitution-principle/solution/RectangleArea.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/interface-segregation-principle/solution/InterfaceSegregationPlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/software-design-principles/interface-segregation-principle/starter/InterfaceSegregationPlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/software-design-principles/interface-segregation-principle/solution/InterfaceSegregationPlayground.playground/playground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/User.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct User {
12 | let id: Int
13 | let firstName: String
14 | let lastName: String
15 | }
16 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/creational-design-patterns/singleton/starter/Singleton.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | class NetworkClient {
6 | func fetchUsers() {
7 | // Performs network call and fetches users
8 | }
9 |
10 | func fetchMessages() {
11 | // Performs network call and fetches messages
12 | }
13 |
14 | // ...more methods here
15 | }
16 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/SignUpForm.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SignUpForm.swift
3 | // SignUpApp
4 | //
5 | // Created by Christopher Arriola on 2/23/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct SignUpForm {
12 | let email: String
13 | let password: String
14 | let username: String
15 |
16 | // TODO: Create builder class
17 | }
18 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/User.swift:
--------------------------------------------------------------------------------
1 | //
2 | // User.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct User {
12 | let id: Int
13 | let firstName: String
14 | let lastName: String
15 |
16 | var displayName: String {
17 | return "\(self.firstName) \(Array(self.lastName)[0])"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/Assets.xcassets/profile_photo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "profile_photo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/Assets.xcassets/profile_photo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "profile_photo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/Assets.xcassets/snowflake.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "snowflake.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/Assets.xcassets/snowflake.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "snowflake.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/anti-patterns/deep-inheritance-exercise/DeepInheritanceExercise.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | class Person {
6 | var name: String?
7 | }
8 |
9 | class Musician: Person {
10 | var yearsTrained: Int?
11 | }
12 |
13 | class Guitarist: Musician {
14 | enum GuitarType {
15 | case acoustic, electric
16 | }
17 |
18 | var preferredGuitarType: GuitarType?
19 | }
20 |
21 | class LeadGuitarist: Guitarist {
22 | }
23 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/EmailVIewController.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // EmailVIewController.swift
4 | // SignUpApp
5 | //
6 | // Created by Christopher Arriola on 2/22/18.
7 | // Copyright © 2018 Udacity. All rights reserved.
8 | //
9 |
10 | import UIKit
11 |
12 | class EmailViewController: UIViewController {
13 | @IBOutlet weak var textFieldEmail: UITextField!
14 |
15 | @IBAction func onSubmitTapped(_ sender: Any) {
16 | // TODO Build form object here
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/creational-design-patterns/dependency-injection/starter/ImageCache.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | protocol Cache {
6 | func cache(object: NSObject)
7 | }
8 |
9 | class InMemoryCache: Cache {
10 | func cache(object: NSObject) {
11 | // Cache object in-memory
12 | }
13 | }
14 |
15 | class ImageCache {
16 | let objectCache: Cache
17 |
18 | init() {
19 | objectCache = InMemoryCache()
20 | }
21 | }
22 |
23 | let imageCache = ImageCache()
24 |
25 |
--------------------------------------------------------------------------------
/structural-design-patterns/adapter/starter/Adapter.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | class MessageSender {
6 | func send(message: Message) {
7 | for recipient in message.recipients {
8 | // Send message to recipient
9 | }
10 | }
11 | }
12 |
13 | struct Message {
14 | let id: String
15 | let text: String
16 | let recipients: [String]
17 | }
18 |
19 | struct LegacyMessage {
20 | let id: String
21 | let text: String
22 | let recipient: String
23 | }
24 |
--------------------------------------------------------------------------------
/creational-design-patterns/singleton/solution/Singleton.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | class NetworkClient {
6 | static let shared = NetworkClient()
7 |
8 | private init() {
9 | }
10 |
11 | func fetchUsers() {
12 | // Performs network call and fetches users
13 | }
14 |
15 | func fetchMessages() {
16 | // Performs network call and fetches messages
17 | }
18 |
19 | // ...more methods here
20 | }
21 |
22 | NetworkClient.shared.fetchMessages()
23 |
--------------------------------------------------------------------------------
/structural-design-patterns/decorator/starter/Decorators.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | enum Instrument {
4 | case guitar
5 | case drums
6 | case bass
7 | // ...
8 | }
9 |
10 | protocol Musician {
11 | var instrument: Instrument { get }
12 | func play()
13 | }
14 |
15 | extension Musician {
16 | func play() {
17 | print("plays the \(instrument)")
18 | }
19 | }
20 |
21 | class Guitarist: Musician {
22 | var instrument: Instrument { return .guitar }
23 | }
24 |
25 | class Drummer: Musician {
26 | var instrument: Instrument { return .drums }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/creational-design-patterns/dependency-injection/solution/ImageCache.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | protocol Cache {
6 | func cache(object: NSObject)
7 | }
8 |
9 | class InMemoryCache: Cache {
10 | func cache(object: NSObject) {
11 | // Cache object in-memory
12 | }
13 | }
14 |
15 | class DiskCache: Cache {
16 | func cache(object: NSObject) {
17 | // cache object to disk
18 | }
19 | }
20 |
21 | class ImageCache {
22 | let objectCache: Cache
23 |
24 | init(objectCache: Cache) {
25 | self.objectCache = objectCache
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 | .AppleDouble
4 | .LSOverride
5 | Icon
6 | ._*
7 | .Spotlight-V100
8 | .Trashes
9 |
10 | # Xcode
11 | build/
12 | *.pbxuser
13 | !default.pbxuser
14 | *.mode1v3
15 | !default.mode1v3
16 | *.mode2v3
17 | !default.mode2v3
18 | *.perspectivev3
19 | !default.perspectivev3
20 | xcuserdata
21 | *.xcuserdatad
22 | *.xccheckout
23 | *.moved-aside
24 | DerivedData
25 | *.xcuserstate
26 | *.DS_Store
27 | xcshareddata
28 |
29 | # Project
30 | *.xcworkspace
31 | !default.xcworkspace
32 | xcuserdatad/
33 |
34 | # Carthage
35 | Carthage/Build
36 | Carthage/Checkouts
37 |
38 | # Cocoapods
39 | Pods/
40 |
41 | # secret
42 | pancit-firebase-key.json
43 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/ProfileViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileViewController.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class ProfileViewController: UIViewController {
13 | @IBOutlet weak var label: UILabel!
14 |
15 | var user: User!
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | label.text = user.displayName
20 | }
21 |
22 | @IBAction func onBackPressed(_ sender: Any) {
23 | dismiss(animated: true)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator/AreaCalculator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AreaCalculator.swift
3 | // AreaCalculator
4 | //
5 | // Created by Christopher Arriola on 1/24/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol Shape {
12 | }
13 |
14 | struct Rectangle: Shape {
15 | let width: Int
16 | let height: Int
17 | }
18 |
19 | class AreaCalculator {
20 | func computeArea(shape: Shape) -> Double {
21 | if let rectangle = shape as? Rectangle {
22 | return Double(rectangle.width * rectangle.height)
23 | }
24 | return 0
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/ProfileViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileViewController.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class ProfileViewController: UIViewController {
13 | @IBOutlet weak var label: UILabel!
14 |
15 | var user: User!
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | label.text = "\(user.firstName) \(Array(user.lastName)[0])"
20 | }
21 |
22 | @IBAction func onBackPressed(_ sender: Any) {
23 | dismiss(animated: true)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // AreaCalculator
4 | //
5 | // Created by Christopher Arriola on 1/24/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // AreaCalculator
4 | //
5 | // Created by Christopher Arriola on 1/24/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/PasswordViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PasswordViewController.swift
3 | // SignUpApp
4 | //
5 | // Created by Christopher Arriola on 2/22/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PasswordViewController: UIViewController {
12 | @IBOutlet weak var textFieldPassword: UITextField!
13 |
14 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
15 | if segue.identifier == "goToEmailViewSegue" {
16 | let emailViewController = segue.destination as! EmailViewController
17 | // TODO Pass builder object to emailViewController
18 | }
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/structural-design-patterns/facade/starter/OrderFacade.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | // An order for a ticket to a concert
6 | struct Order {
7 | let userId: String
8 | let payment: PaymentInformation
9 | let concert: Concert
10 | }
11 |
12 | // A user's payment information
13 | struct PaymentInformation {
14 | let creditCardNumber: String
15 | // ...other fields
16 | }
17 |
18 | // A concert
19 | struct Concert {
20 | let id: String
21 | // ...other fields
22 | }
23 |
24 | // A class for interacting with different concerts
25 | class ConcertManager {
26 | }
27 |
28 | // A class for processing payments
29 | class PaymentProcessor {
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/software-design-principles/dependency-inversion-principle/starter/ImageCache.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import Foundation
4 |
5 | class Message {
6 | let id: String
7 | let text: String
8 |
9 | init(id: String, text: String) {
10 | self.id = id
11 | self.text = text
12 | }
13 | }
14 |
15 | class MessageCacher {
16 | let cache: InMemoryCache
17 |
18 | init(cache: InMemoryCache) {
19 | self.cache = cache
20 | }
21 |
22 | func store(message: Message) {
23 | cache.cache(object: message)
24 | }
25 | }
26 |
27 | class InMemoryCache {
28 | func cache(object: AnyObject) {
29 | // caches object
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/UsernameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SignUpApp
4 | //
5 | // Created by Christopher Arriola on 2/9/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class UsernameViewController: UIViewController {
12 |
13 | @IBOutlet weak var textFieldUsername: UITextField!
14 |
15 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
16 | if segue.identifier == "goToPasswordViewSegue" {
17 | let passwordViewController = segue.destination as! PasswordViewController
18 | // TODO Create builder object and pass it to passwordViewController
19 | }
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder/solution/FormSubmission.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | struct SignUpSubmission {
6 | let username: String
7 | let email: String
8 | let phoneNumber: String
9 | // ...
10 |
11 | class Builder {
12 | var username: String?
13 | var email: String?
14 | var phoneNumber: String?
15 |
16 | func build() -> SignUpSubmission? {
17 | guard let username = username, let email = email, let phoneNumber = phoneNumber else {
18 | return nil
19 | }
20 | return SignUpSubmission(username: username, email: email, phoneNumber: phoneNumber)
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SingleResponsibilityPrinciple
4 | //
5 | // Created by Christopher Arriola on 1/22/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SingleResponsibilityPrinciple
4 | //
5 | // Created by Christopher Arriola on 1/22/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 |
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/dependency-inversion-principle/solution/ImageCache.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import Foundation
4 |
5 | class Message {
6 | let id: String
7 | let text: String
8 |
9 | init(id: String, text: String) {
10 | self.id = id
11 | self.text = text
12 | }
13 | }
14 |
15 | protocol ObjectCache {
16 | func cache(object: AnyObject)
17 | }
18 |
19 | class MessageCacher {
20 | let cache: ObjectCache
21 |
22 | init(cache: ObjectCache) {
23 | self.cache = cache
24 | }
25 |
26 | func store(message: Message) {
27 | cache.cache(object: message)
28 | }
29 | }
30 |
31 | class InMemoryCache: ObjectCache {
32 | func cache(object: AnyObject) {
33 | // caches object
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator/AreaCalculator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AreaCalculator.swift
3 | // AreaCalculator
4 | //
5 | // Created by Christopher Arriola on 1/24/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | protocol Shape {
12 | var area: Double { get }
13 | }
14 |
15 | struct Circle: Shape {
16 | let radius: Int
17 |
18 | var area: Double {
19 | return Double(radius * radius) * Double.pi
20 | }
21 | }
22 |
23 | struct Rectangle: Shape {
24 | let width: Int
25 | let height: Int
26 |
27 | var area: Double {
28 | return Double(width * height)
29 | }
30 | }
31 |
32 | class AreaCalculator {
33 | func computeArea(shape: Shape) -> Double {
34 | return shape.area
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/anti-patterns/god-object-exercise/GodObjectExercise.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | class AppSettings {
6 |
7 | private let defaults = UserDefaults.standard
8 |
9 | var userId: String {
10 | return defaults.string(forKey: "user_id") ?? ""
11 | }
12 |
13 | // MARK: User preferences
14 |
15 | var userPreference1: Bool {
16 | return defaults.bool(forKey: "user_preference_1")
17 | }
18 |
19 | var userPreference2: Bool {
20 | return defaults.bool(forKey: "user_preference_2")
21 | }
22 |
23 | // MARK: Onboarding
24 |
25 | var hasSeenFeature1: Bool {
26 | return defaults.bool(forKey: "has_seen_feature_1")
27 | }
28 |
29 | var hasSeenFeature2: Bool {
30 | return defaults.bool(forKey: "has_seen_feature_2")
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/WelcomeViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WelcomeViewController.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class WelcomeViewController: UIViewController {
13 | @IBOutlet weak var label: UILabel!
14 |
15 | private var user: User!
16 |
17 | override func viewDidLoad() {
18 | user = User(id: 1, firstName: "Steve", lastName: "Jobs")
19 | label.text = user.displayName
20 | }
21 |
22 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
23 | if segue.identifier == "showProfileSegue" {
24 | let profileViewController = segue.destination as! ProfileViewController
25 | profileViewController.user = user
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/WelcomeViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WelcomeViewController.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class WelcomeViewController: UIViewController {
13 | @IBOutlet weak var label: UILabel!
14 |
15 | private var user: User!
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | user = User(id: 1, firstName: "Steve", lastName: "Jobs")
20 | label.text = "\(user.firstName) \(Array(user.lastName)[0])"
21 | }
22 |
23 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
24 | if segue.identifier == "showProfileSegue" {
25 | let profileViewController = segue.destination as! ProfileViewController
26 | profileViewController.user = user
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/software-design-principles/interface-segregation-principle/starter/InterfaceSegregationPlayground.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | /**
6 | * Protocol for a Game.
7 | */
8 | protocol Game {
9 | func start()
10 | func pause()
11 | func stop()
12 | func save()
13 | func restore()
14 | func setDifficulty(to difficulty: Int)
15 | }
16 |
17 | class RPGGame: Game {
18 | // All methods used!
19 | func start() { }
20 | func pause() { }
21 | func stop() { }
22 | func save() { }
23 | func restore() { }
24 | func setDifficulty(to difficulty: Int) { }
25 | }
26 |
27 | class TapBasedGame: Game {
28 | // Only these methods are used
29 | func start() { }
30 | func pause() { }
31 | func stop() { }
32 |
33 | // These methods not used
34 | func save() { }
35 | func restore() { }
36 | func setDifficulty(to difficulty: Int) { }
37 | }
38 |
--------------------------------------------------------------------------------
/software-design-principles/liskov-substitution-principle/solution/RectangleArea.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 | import Foundation
5 |
6 | protocol Shape {
7 | var area: Int { get }
8 | }
9 |
10 | class Rectangle: Shape {
11 | var width: Int
12 | var height: Int
13 |
14 | var area: Int {
15 | return width * height
16 | }
17 |
18 | init(width: Int, height: Int) {
19 | self.width = width
20 | self.height = height
21 | }
22 | }
23 |
24 | class Square: Shape {
25 | var side: Int
26 |
27 | var area: Int {
28 | return side * side
29 | }
30 |
31 | init(side: Int) {
32 | self.side = side
33 | }
34 | }
35 |
36 |
37 | func printArea(shape: Shape) {
38 | print(shape.area)
39 | }
40 |
41 | let rectangle = Rectangle(width: 3, height: 4)
42 | printArea(shape: rectangle)
43 |
44 | let square = Square(side: 3)
45 | printArea(shape: square)
46 |
--------------------------------------------------------------------------------
/software-design-principles/interface-segregation-principle/solution/InterfaceSegregationPlayground.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | /**
6 | * A game that can be saved.
7 | */
8 | protocol Saveable {
9 | func save()
10 | func restore()
11 | }
12 |
13 | /**
14 | * A game with which the difficulty can be adjusted
15 | */
16 | protocol VariablyDifficultGame {
17 | func setDifficulty(to difficulty: Int)
18 | }
19 |
20 | /**
21 | * Protocol for a Game.
22 | */
23 | protocol Game {
24 | func start()
25 | func pause()
26 | func stop()
27 | }
28 |
29 | class RPGGame: Game, Saveable, VariablyDifficultGame {
30 | // All methods used!
31 | func start() { }
32 | func pause() { }
33 | func stop() { }
34 |
35 | func save() { }
36 | func restore() { }
37 |
38 | func setDifficulty(to difficulty: Int) { }
39 | }
40 |
41 | class TapBasedGame: Game {
42 | // Only these methods are used
43 | func start() { }
44 | func pause() { }
45 | func stop() { }
46 | }
47 |
--------------------------------------------------------------------------------
/structural-design-patterns/adapter/solution/Adapter.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | class MessageSender {
6 | func send(message: Message) {
7 | for recipient in message.recipients {
8 | // Send message to recipient
9 | }
10 | }
11 | }
12 |
13 | struct Message {
14 | let id: String
15 | let text: String
16 | let recipients: [String]
17 | }
18 |
19 | struct LegacyMessage {
20 | let id: String
21 | let text: String
22 | let recipient: String
23 | }
24 |
25 | struct LegacyMessageAdapter {
26 | let legacyMessage: LegacyMessage
27 |
28 | var message: Message {
29 | return Message(id: legacyMessage.id, text: legacyMessage.text, recipients: [legacyMessage.recipient])
30 | }
31 | }
32 |
33 | // Usage
34 | let messageSender = MessageSender()
35 | let legacyMessage = LegacyMessage(id: "abc", text: "hello", recipient: "john")
36 | let legacyMessageAdapter = LegacyMessageAdapter(legacyMessage: legacyMessage)
37 | messageSender.send(message: legacyMessageAdapter.message)
38 |
39 |
--------------------------------------------------------------------------------
/structural-design-patterns/facade/solution/OrderFacade.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | // An order for a ticket to a concert
6 | struct Order {
7 | let userId: String
8 | let payment: PaymentInformation
9 | let concert: Concert
10 | }
11 |
12 | // A user's payment information
13 | struct PaymentInformation {
14 | let creditCardNumber: String
15 | // ...other fields
16 | }
17 |
18 | // A concert
19 | struct Concert {
20 | let id: String
21 | // ...other fields
22 | }
23 |
24 | // A class for interacting with different concerts
25 | class ConcertManager {
26 | }
27 |
28 | // A class for processing payments
29 | class PaymentProcessor {
30 | }
31 |
32 | class OrderFacade {
33 | let concertManager: ConcertManager
34 | let paymentProcessor: PaymentProcessor
35 |
36 | init(concertManager: ConcertManager, paymentProcessor: PaymentProcessor) {
37 | self.concertManager = concertManager
38 | self.paymentProcessor = paymentProcessor
39 | }
40 |
41 | func process(order: Order) {
42 | // process order
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/observer/starter/LocationPlayground.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 | import CoreLocation
3 |
4 | /// An observer that is notified of changes whenever the user’s location changes.
5 | protocol LocationObserver: class {
6 | func didLocationChange(location: CLLocation)
7 | }
8 |
9 | /// A service (i.e. the “subject”) that listens to changes to a user’s location and reports those changes to its observers.
10 | class LocationService: NSObject, CLLocationManagerDelegate {
11 |
12 | private lazy var locationManager: CLLocationManager = {
13 | let locationManager = CLLocationManager()
14 | locationManager.delegate = self
15 | locationManager.desiredAccuracy = kCLLocationAccuracyBest
16 | return locationManager
17 | }()
18 |
19 | func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
20 | // TODO
21 | }
22 |
23 | func startUpdates() {
24 | locationManager.startUpdatingLocation()
25 | }
26 |
27 | func stopUpdates() {
28 | locationManager.stopUpdatingLocation()
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Game.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Game.swift
3 | // SingleResponsibilityPrinciple
4 | //
5 | // Created by Christopher Arriola on 1/22/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class Game {
13 | private var score: Int
14 | private var difficulty: Int
15 | private var level: Int
16 |
17 | init(score: Int, difficulty: Int, level: Int) {
18 | self.score = score
19 | self.difficulty = difficulty
20 | self.level = level
21 | }
22 |
23 | func backgroundColor() -> UIColor {
24 | switch self.level {
25 | case 1...10: return UIColor.black
26 | case 11...20: return UIColor.blue
27 | default: return UIColor.red
28 | }
29 | }
30 |
31 | func incrementScore() {
32 | self.score += 10 * difficulty
33 | }
34 |
35 | func updateLevel(to level: Int) {
36 | self.level = level
37 | }
38 |
39 | func changeDifficulty(to difficulty: Int) {
40 | self.difficulty = difficulty
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/chain-of-responsibility/starter/ImageProcessing.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | struct Image {
6 | let data: Data
7 | }
8 |
9 | /// Protocol to be implemented by a handler or image processing unit.
10 | protocol ImageHandler {
11 | func handle(image: Image)
12 | }
13 |
14 | /// Image handler that creates a gray scale image from the input image
15 | class GrayscaleConverter: ImageHandler {
16 | func handle(image: Image) {
17 | // create grayscale image
18 | }
19 | }
20 |
21 | /// Image handler that creates a thumbnail image from the input image
22 | class ThumbnailCreator: ImageHandler {
23 | func handle(image: Image) {
24 | // create thumbnail image
25 | }
26 | }
27 |
28 | /// A class that processes an image
29 | class ImageProcessor {
30 | private var handlers: [ImageHandler] = []
31 |
32 | init() {
33 | handlers = [
34 | GrayscaleConverter(),
35 | ThumbnailCreator()
36 | ]
37 | }
38 |
39 | func process(image: Image) {
40 | for handler in handlers {
41 | handler.handle(image: image)
42 | }
43 | }
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/creational-design-patterns/factory-methods/starter/Music.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | protocol Band {
6 | var name: String { get }
7 |
8 | func playMusic()
9 | }
10 |
11 | class JazzBand: Band {
12 | var name: String {
13 | return "Jazz Vibes"
14 | }
15 |
16 | func playMusic() {
17 | // Play jazz music
18 | }
19 | }
20 |
21 | class ElectronicBand: Band {
22 | var name: String {
23 | return "Above and Beyond"
24 | }
25 |
26 | func playMusic() {
27 | // Play electronic music
28 | }
29 | }
30 |
31 | class PostRockBand: Band {
32 | var name: String {
33 | return "Balmorhea"
34 | }
35 |
36 | func playMusic() {
37 | // Play post-rock music
38 | }
39 | }
40 |
41 | enum Mood {
42 | case classy, focus, dance
43 | }
44 |
45 | class MusicClient {
46 | func playMusic(for mood: Mood) {
47 | let band: Band
48 | switch mood {
49 | case .classy:
50 | band = JazzBand()
51 | case .dance:
52 | band = ElectronicBand()
53 | case .focus:
54 | band = PostRockBand()
55 | }
56 | band.playMusic()
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/software-design-principles/liskov-substitution-principle/starter/RectangleArea.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 | import Foundation
5 |
6 | class Rectangle {
7 | var width: Int
8 | var height: Int
9 |
10 | var area: Int {
11 | return width * height
12 | }
13 |
14 | init(width: Int, height: Int) {
15 | self.width = width
16 | self.height = height
17 | }
18 | }
19 |
20 | class Square: Rectangle {
21 |
22 | init(side: Int) {
23 | super.init(width: side, height: side)
24 | }
25 |
26 | override var width: Int {
27 | didSet {
28 | guard oldValue != width else { return }
29 | height = width
30 | }
31 | }
32 |
33 | override var height: Int {
34 | didSet {
35 | guard oldValue != height else { return }
36 | width = height
37 | }
38 | }
39 | }
40 |
41 |
42 | func printArea(rectangle: Rectangle) {
43 | rectangle.width = 3
44 | rectangle.height = 4
45 | print(rectangle.area) // Should print 12 (4 * 3)
46 | }
47 |
48 | let rectangle = Rectangle(width: 1, height: 1)
49 | printArea(rectangle: rectangle)
50 |
51 | let square = Square(side: 1)
52 | printArea(rectangle: square)
53 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/mediator/starter/EmailSender.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | /// 1. Consumer
6 | struct User {
7 | let name: String
8 | let emailAddress: String
9 | }
10 |
11 | /// 2. Producer
12 | class CustomerRepresentative {
13 | func sendPromotionEmail() {
14 | let email = Email(body: "Get 50% off your next purchase!", subject: "Promo")
15 | let demographics = EmailDemographics(isActiveUser: true, madePurchaseRecently: true)
16 |
17 | let mediator = EmailMediator()
18 | mediator.send(email: email, toUsersWith: demographics)
19 | }
20 | }
21 |
22 | struct Email {
23 | let body: String
24 | let subject: String
25 | }
26 |
27 | struct EmailDemographics {
28 | let isActiveUser: Bool
29 | let madePurchaseRecently: Bool
30 | }
31 |
32 | /// 3. Mediator
33 | class EmailMediator {
34 |
35 | private var users: [User] = [
36 | User(name: "John", emailAddress: "john@emailprovider.com"),
37 | User(name: "Mary", emailAddress: "mary@emailprovider.com"),
38 | User(name: "Bob", emailAddress: "bob@emailprovider.com")
39 | ]
40 |
41 | func send(email: Email, toUsersWith demographic: EmailDemographics) {
42 | // TODO
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/chain-of-responsibility/solution/ImageProcessing.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | struct Image {
6 | let data: Data
7 | }
8 |
9 | /// Protocol to be implemented by a handler or image processing unit.
10 | protocol ImageHandler {
11 | func handle(image: Image)
12 | }
13 |
14 | /// Image handler that creates a gray scale image from the input image
15 | class GrayscaleCreator: ImageHandler {
16 | func handle(image: Image) {
17 | // create grayscale image
18 | }
19 | }
20 |
21 | /// Image handler that creates a thumbnail image from the input image
22 | class ThumbnailCreator: ImageHandler {
23 | func handle(image: Image) {
24 | // create thumbnail image
25 | }
26 | }
27 |
28 | class ImagePersister: ImageHandler {
29 | func handle(image: Image) {
30 |
31 | }
32 | }
33 |
34 | /// A class that processes an image
35 | class ImageProcessor {
36 | private var handlers: [ImageHandler] = []
37 |
38 | init() {
39 | handlers = [
40 | GrayscaleCreator(),
41 | ThumbnailCreator(),
42 | ImagePersister()
43 | ]
44 | }
45 |
46 | func process(image: Image) {
47 | for handler in handlers {
48 | handler.handle(image: image)
49 | }
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/command/starter/MusicPlayer.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 | import Foundation
3 |
4 | /// A protocol that defines a command to play a song.
5 | protocol PlaySongCommand {
6 | func play()
7 | }
8 |
9 | /// A command to play a song that needs to be fetched over the network first
10 | class RemoteSongCommand: PlaySongCommand {
11 | let songURL: URL
12 |
13 | init(songURL: URL) {
14 | self.songURL = songURL
15 | }
16 |
17 | func play() {
18 | // Fetch song file over the network
19 | // Play song file after fetching from the network
20 | }
21 | }
22 |
23 | /// A command to play a song that is available in disk.
24 | class LocalSongCommand: PlaySongCommand {
25 | let songURL: URL
26 |
27 | init(songURL: URL) {
28 | self.songURL = songURL
29 | }
30 |
31 | func play() {
32 | // Fetch song file from disk
33 | // Play song file after fetching from disk
34 | }
35 | }
36 |
37 | /**
38 | The music player which can execute and queue PlaySongCommands.
39 | */
40 | class MusicPlayer {
41 |
42 | func play(command: PlaySongCommand) {
43 | // TODO
44 | }
45 |
46 | func addToQueue(command: PlaySongCommand) {
47 | // TODO
48 | }
49 |
50 | func playNext() {
51 | // TODO
52 | }
53 | }
54 |
55 |
56 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/observer/solution/LocationPlayground.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import CoreLocation
4 |
5 | /// An observer that is notified of changes whenever the user’s location changes.
6 | protocol LocationObserver: class {
7 | func didLocationChange(location: CLLocation)
8 | }
9 |
10 | /// A service (i.e. the “subject”) that listens to changes to a user’s location and reports those changes to its observers.
11 | class LocationService: NSObject, CLLocationManagerDelegate {
12 |
13 | var observers = [LocationObserver]()
14 |
15 | private lazy var locationManager: CLLocationManager = {
16 | let locationManager = CLLocationManager()
17 | locationManager.delegate = self
18 | locationManager.desiredAccuracy = kCLLocationAccuracyBest
19 | return locationManager
20 | }()
21 |
22 | func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
23 | for observer in observers {
24 | observer.didLocationChange(location: locations[0])
25 | }
26 | }
27 |
28 | func subscribe(observer: LocationObserver) {
29 | observers.append(observer)
30 | }
31 |
32 | func startUpdates() {
33 | locationManager.startUpdatingLocation()
34 | }
35 |
36 | func stopUpdates() {
37 | locationManager.stopUpdatingLocation()
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/creational-design-patterns/factory-methods/solution/Music.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | protocol Band {
6 | var name: String { get }
7 |
8 | func playMusic()
9 | }
10 |
11 | class JazzBand: Band {
12 | var name: String {
13 | return "Jazz Vibes"
14 | }
15 |
16 | func playMusic() {
17 | // Play jazz music
18 | }
19 | }
20 |
21 | class ElectronicBand: Band {
22 | var name: String {
23 | return "Above and Beyond"
24 | }
25 |
26 | func playMusic() {
27 | // Play electronic music
28 | }
29 | }
30 |
31 | class PostRockBand: Band {
32 | var name: String {
33 | return "Balmorhea"
34 | }
35 |
36 | func playMusic() {
37 | // Play post-rock music
38 | }
39 | }
40 |
41 | enum Mood {
42 | case classy, focus, dance
43 | }
44 |
45 | class BandFactory {
46 | func createBand(forMood mood: Mood) -> Band {
47 | let band: Band
48 | switch mood {
49 | case .classy:
50 | band = JazzBand()
51 | case .dance:
52 | band = ElectronicBand()
53 | case .focus:
54 | band = PostRockBand()
55 | }
56 | return band
57 | }
58 | }
59 |
60 | class MusicClient {
61 | func playMusic(for mood: Mood) {
62 | let band = BandFactory().createBand(forMood: mood)
63 | band.playMusic()
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/structural-design-patterns/decorator/solution/Decorators.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | enum Instrument {
4 | case guitar
5 | case drums
6 | case bass
7 | // ...
8 | }
9 |
10 | protocol Musician {
11 | var instrument: Instrument { get }
12 | func play()
13 | }
14 |
15 | extension Musician {
16 | func play() {
17 | print("plays the \(instrument)")
18 | }
19 | }
20 |
21 | class Guitarist: Musician {
22 | var instrument: Instrument { return .guitar }
23 | }
24 |
25 | class Drummer: Musician {
26 | var instrument: Instrument { return .drums }
27 | }
28 |
29 | class MusicianDecorator: Musician {
30 | var instrument: Instrument { return decoratedMusician.instrument }
31 |
32 | private let decoratedMusician: Musician
33 |
34 | init(_ decoratedMusician: Musician) {
35 | self.decoratedMusician = decoratedMusician
36 | }
37 |
38 | func play() {
39 | decoratedMusician.play()
40 | }
41 | }
42 |
43 | class GuitarDecorator: MusicianDecorator {
44 | override func play() {
45 | super.play()
46 | print(" and play the \(Instrument.guitar)")
47 | }
48 | }
49 |
50 | class DrummerDecorator: MusicianDecorator {
51 | override func play() {
52 | super.play()
53 | print(" and play the \(Instrument.drums)")
54 | }
55 | }
56 |
57 | let drummerAndGuitarist = DrummerDecorator(Guitarist())
58 | drummerAndGuitarist.play()
59 |
60 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/command/solution/MusicPlayer.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 | import Foundation
3 |
4 | /// A protocol that defines a command to play a song.
5 | protocol PlaySongCommand {
6 | func play()
7 | }
8 |
9 | /// A command to play a song that needs to be fetched over the network first
10 | class RemoteSongCommand: PlaySongCommand {
11 | let songURL: URL
12 |
13 | init(songURL: URL) {
14 | self.songURL = songURL
15 | }
16 |
17 | func play() {
18 | // Fetch song file over the network
19 | // Play song file after fetching from the network
20 | }
21 | }
22 |
23 | /// A command to play a song that is available in disk.
24 | class LocalSongCommand: PlaySongCommand {
25 | let songURL: URL
26 |
27 | init(songURL: URL) {
28 | self.songURL = songURL
29 | }
30 |
31 | func play() {
32 | // Fetch song file from disk
33 | // Play song file after fetching from disk
34 | }
35 | }
36 |
37 | /**
38 | The music player which can execute and queue PlaySongCommands.
39 | */
40 | class MusicPlayer {
41 |
42 | private var queue: [PlaySongCommand] = []
43 |
44 | func play(command: PlaySongCommand) {
45 | command.play()
46 | }
47 |
48 | func addToQueue(command: PlaySongCommand) {
49 | queue.append(command)
50 | }
51 |
52 | func playNext() {
53 | guard !queue.isEmpty else { return }
54 | let command = queue.removeFirst()
55 | play(command: command)
56 | }
57 | }
58 |
59 |
60 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/behavioral-design-patterns/mediator/solution/EmailSender.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: Playground - noun: a place where people can play
2 |
3 | import UIKit
4 |
5 | /// 1. Consumer
6 | struct User {
7 | let name: String
8 | let emailAddress: String
9 | }
10 |
11 | /// 2. Producer
12 | class CustomerRepresentative {
13 | func sendPromotionEmail() {
14 | let email = Email(body: "Get 50% off your next purchase!", subject: "Promo")
15 | let demographics = EmailDemographics(isActiveUser: true, madePurchaseRecently: true)
16 |
17 | let mediator = EmailMediator()
18 | mediator.send(email: email, toUsersWith: demographics)
19 | }
20 | }
21 |
22 | struct Email {
23 | let body: String
24 | let subject: String
25 | }
26 |
27 | struct EmailDemographics {
28 | let isActiveUser: Bool
29 | let madePurchaseRecently: Bool
30 | }
31 |
32 | /// 3. Mediator
33 | class EmailMediator {
34 |
35 | private var users: [User] = [
36 | User(name: "John", emailAddress: "john@emailprovider.com"),
37 | User(name: "Mary", emailAddress: "mary@emailprovider.com"),
38 | User(name: "Bob", emailAddress: "bob@emailprovider.com")
39 | ]
40 |
41 | func send(email: Email, toUsersWith demographic: EmailDemographics) {
42 | for user in users {
43 | if user.satisfies(demographic: demographic) {
44 | send(email: email, to: user)
45 | }
46 | }
47 | }
48 |
49 | private func send(email: Email, to user: User) {
50 | // Send email
51 | }
52 | }
53 |
54 | extension User {
55 | func satisfies(demographic: EmailDemographics) -> Bool {
56 | return true
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Game.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Game.swift
3 | // SingleResponsibilityPrinciple
4 | //
5 | // Created by Christopher Arriola on 1/22/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class GameViewState {
13 | func backgroundColor(level: Int) -> UIColor {
14 | switch level {
15 | case 1...10: return UIColor.black
16 | case 11...20: return UIColor.blue
17 | default: return UIColor.red
18 | }
19 | }
20 | }
21 |
22 | class ScoreTracker {
23 |
24 | private var score: Int
25 |
26 | init(score: Int) {
27 | self.score = score
28 | }
29 |
30 | func incrementScore(difficulty: Int) {
31 | self.score += 10 * difficulty
32 | }
33 | }
34 |
35 | class Game {
36 | private var difficulty: Int
37 | private var level: Int
38 | private var scoreTracker: ScoreTracker
39 | private var viewState = GameViewState()
40 |
41 | init(score: Int, difficulty: Int, level: Int) {
42 | self.scoreTracker = ScoreTracker(score: score)
43 | self.difficulty = difficulty
44 | self.level = level
45 | }
46 |
47 | func incrementScore() {
48 | scoreTracker.incrementScore(difficulty: difficulty)
49 | }
50 |
51 | func backgroundColor() -> UIColor {
52 | return viewState.backgroundColor(level: level)
53 | }
54 |
55 | func updateLevel(to level: Int) {
56 | self.level = level
57 | }
58 |
59 | func changeDifficulty(to difficulty: Int) {
60 | self.difficulty = difficulty
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.github/workflows/manual.yml:
--------------------------------------------------------------------------------
1 | # Workflow to ensure whenever a Github PR is submitted,
2 | # a JIRA ticket gets created automatically.
3 | name: Manual Workflow
4 |
5 | # Controls when the action will run.
6 | on:
7 | # Triggers the workflow on pull request events but only for the master branch
8 | pull_request_target:
9 | types: [opened, reopened]
10 |
11 | # Allows you to run this workflow manually from the Actions tab
12 | workflow_dispatch:
13 |
14 | jobs:
15 | test-transition-issue:
16 | name: Convert Github Issue to Jira Issue
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@master
21 |
22 | - name: Login
23 | uses: atlassian/gajira-login@master
24 | env:
25 | JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
26 | JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
27 | JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
28 |
29 | - name: Create NEW JIRA ticket
30 | id: create
31 | uses: atlassian/gajira-create@master
32 | with:
33 | project: CONUPDATE
34 | issuetype: Task
35 | summary: |
36 | Github PR [Assign the ND component] | Repo: ${{ github.repository }} | PR# ${{github.event.number}}
37 | description: |
38 | Repo link: https://github.com/${{ github.repository }}
39 | PR no. ${{ github.event.pull_request.number }}
40 | PR title: ${{ github.event.pull_request.title }}
41 | PR description: ${{ github.event.pull_request.description }}
42 | In addition, please resolve other issues, if any.
43 | fields: '{"components": [{"name":"Github PR"}], "customfield_16449":"https://classroom.udacity.com/", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}'
44 |
45 | - name: Log created issue
46 | run: echo "Issue ${{ steps.create.outputs.issue }} was created"
47 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // DRY
4 | //
5 | // Created by Christopher Arriola on 1/21/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/creational-design-patterns/builder-exercise/SignUpApp/SignUpApp/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SignUpApp
4 | //
5 | // Created by Christopher Arriola on 2/9/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ObjectPool
4 | //
5 | // Created by Christopher Arriola on 2/5/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ObjectPool
4 | //
5 | // Created by Christopher Arriola on 2/5/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/solution/AreaCalculator/AreaCalculator/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // AreaCalculator
4 | //
5 | // Created by Christopher Arriola on 1/24/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/software-design-principles/open-closed-principle/starter/AreaCalculator/AreaCalculator/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // AreaCalculator
4 | //
5 | // Created by Christopher Arriola on 1/24/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ObjectPool
4 | //
5 | // Created by Christopher Arriola on 2/5/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | private var timer: Timer?
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | // Do any additional setup after loading the view, typically from a nib.
18 | }
19 |
20 | override func viewWillAppear(_ animated: Bool) {
21 | super.viewWillAppear(animated)
22 |
23 | // 1. Create a timer that will add snowflakes at regular intervals
24 | timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { _ in
25 |
26 | // 2. When the timer is triggered, add a snowflake
27 | let snowflake = SnowflakeView()
28 | snowflake.animateFallingSnowflake(to: self.view)
29 | }
30 | }
31 |
32 | override func viewWillDisappear(_ animated: Bool) {
33 | timer?.invalidate()
34 | timer = nil
35 | super.viewWillDisappear(animated)
36 | }
37 | }
38 |
39 | class SnowflakeView: UIImageView {
40 |
41 | private var randomXPosition: CGFloat {
42 | get {
43 | let maxX = self.superview?.frame.width ?? self.frame.width
44 | return CGFloat(arc4random_uniform(UInt32(maxX)))
45 | }
46 | }
47 |
48 | init() {
49 | super.init(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
50 | sharedInit()
51 | }
52 |
53 | required init?(coder aDecoder: NSCoder) {
54 | super.init(coder: aDecoder)
55 | sharedInit()
56 | }
57 |
58 | private func sharedInit() {
59 | image = UIImage(named: "snowflake")
60 | contentMode = .scaleAspectFit
61 | }
62 |
63 | func animateFallingSnowflake(to view: UIView) {
64 | view.addSubview(self)
65 |
66 | frame = CGRect(x: randomXPosition, y: -self.frame.height, width: self.frame.width, height: self.frame.height)
67 |
68 | UIView.animate(withDuration: 3, animations: {
69 | self.frame = CGRect(x: self.randomXPosition, y: self.superview!.frame.height + self.frame.height, width: self.frame.width, height: self.frame.height)
70 | }) { _ in
71 | // Animation complete
72 | }
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/solution/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SingleResponsibilityPrinciple
4 | //
5 | // Created by Christopher Arriola on 1/22/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/software-design-principles/single-responsibility-principle/starter/SingleResponsibilityPrinciple/SingleResponsibilityPrinciple/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SingleResponsibilityPrinciple
4 | //
5 | // Created by Christopher Arriola on 1/22/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iOS - Mobile Design Patterns
2 | This repository contains applications, and Xcode Playground files, to demonstrate concepts taught in Udacity's "iOS - Mobile Design Patterns". Each project contains a starter, and corresponding solution, to be used to follow along the videos throughout the course.
3 |
4 | The concepts with projects/playground files are:
5 |
6 | ### Software Design Principles
7 | * [Keep it DRY](https://github.com/udacity/iosnd-design-patterns/tree/master/software-design-principles/dry-principle)
8 | * [Single Responsibility Principle](https://github.com/udacity/iosnd-design-patterns/tree/master/software-design-principles/single-responsibility-principle)
9 | * [Open/Closed Principle](https://github.com/udacity/iosnd-design-patterns/tree/master/software-design-principles/open-closed-principle)
10 | * [Liskov Substitution Principle](https://github.com/udacity/iosnd-design-patterns/tree/master/software-design-principles/liskov-substitution-principle)
11 | * [Interface Segregation Principle](https://github.com/udacity/iosnd-design-patterns/tree/master/software-design-principles/interface-segregation-principle)
12 | * [Dependency Inversion Principle](https://github.com/udacity/iosnd-design-patterns/tree/master/software-design-principles/dependency-inversion-principle)
13 |
14 | ### Creational Design Patterns
15 | * [Factory Methods](https://github.com/udacity/iosnd-design-patterns/tree/master/creational-design-patterns/factory-methods)
16 | * [Singleton](https://github.com/udacity/iosnd-design-patterns/tree/master/creational-design-patterns/singleton)
17 | * [Dependency Injection](https://github.com/udacity/iosnd-design-patterns/tree/master/creational-design-patterns/dependency-injection)
18 | * [Object Pool](https://github.com/udacity/iosnd-design-patterns/tree/master/creational-design-patterns/object-pool)
19 | * [Builder](https://github.com/udacity/iosnd-design-patterns/tree/master/creational-design-patterns/builder)
20 | * [Builder Exercise](https://github.com/udacity/iosnd-design-patterns/tree/master/creational-design-patterns/builder-exercise/SignUpApp)
21 |
22 | ### Structural Design Patterns
23 | * [Adapter](https://github.com/udacity/iosnd-design-patterns/tree/master/structural-design-patterns/adapter)
24 | * [Facade](https://github.com/udacity/iosnd-design-patterns/tree/master/structural-design-patterns/facade)
25 | * [Decorator](https://github.com/udacity/iosnd-design-patterns/tree/master/structural-design-patterns/decorator)
26 |
27 | ### Behavioral Design Patterns
28 | * [Observer](https://github.com/udacity/iosnd-design-patterns/tree/master/behavioral-design-patterns/observer)
29 | * [Command](https://github.com/udacity/iosnd-design-patterns/tree/master/behavioral-design-patterns/command)
30 | * [Chain of Responsibility](https://github.com/udacity/iosnd-design-patterns/tree/master/behavioral-design-patterns/chain-of-responsibility)
31 | * [Mediator](https://github.com/udacity/iosnd-design-patterns/tree/master/behavioral-design-patterns/mediator)
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ObjectPool
4 | //
5 | // Created by Christopher Arriola on 2/5/18.
6 | // Copyright © 2018 Udacity. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | private var timer: Timer?
14 | private var snowflakePool: [SnowflakeView] = []
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 | // Do any additional setup after loading the view, typically from a nib.
19 | for _ in 1...100 {
20 | let snowflake = SnowflakeView()
21 | snowflakePool.append(snowflake)
22 | }
23 | }
24 |
25 | override func viewWillAppear(_ animated: Bool) {
26 | super.viewWillAppear(animated)
27 |
28 | // 1. Create a timer that will add snowflakes at regular intervals
29 | timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { _ in
30 |
31 | // 2. When the timer is triggered, add a snowflake
32 | guard let snowflake = self.snowflakePool.popLast() else {
33 | print("No more snowflakes in the pool!")
34 | return
35 | }
36 | snowflake.animateFallingSnowflake(to: self.view) {
37 | self.snowflakePool.append(snowflake)
38 | }
39 | }
40 | }
41 |
42 | override func viewWillDisappear(_ animated: Bool) {
43 | timer?.invalidate()
44 | timer = nil
45 | super.viewWillDisappear(animated)
46 | }
47 | }
48 |
49 | class SnowflakeView: UIImageView {
50 |
51 | private var randomXPosition: CGFloat {
52 | get {
53 | let maxX = self.superview?.frame.width ?? self.frame.width
54 | return CGFloat(arc4random_uniform(UInt32(maxX)))
55 | }
56 | }
57 |
58 | init() {
59 | super.init(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
60 | sharedInit()
61 | }
62 |
63 | required init?(coder aDecoder: NSCoder) {
64 | super.init(coder: aDecoder)
65 | sharedInit()
66 | }
67 |
68 | private func sharedInit() {
69 | image = UIImage(named: "snowflake")
70 | contentMode = .scaleAspectFit
71 | }
72 |
73 | func animateFallingSnowflake(to view: UIView, completion: @escaping (() -> Void)) {
74 | view.addSubview(self)
75 |
76 | frame = CGRect(x: randomXPosition, y: -self.frame.height, width: self.frame.width, height: self.frame.height)
77 |
78 | UIView.animate(withDuration: 3, animations: {
79 | self.frame = CGRect(x: self.randomXPosition, y: self.superview!.frame.height + self.frame.height, width: self.frame.width, height: self.frame.height)
80 | }) { _ in
81 | // Animation complete
82 | completion()
83 | }
84 | }
85 | }
86 |
87 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/solution/DRY/DRY/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/software-design-principles/dry-principle/starter/DRY/DRY/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
27 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/solution/ObjectPool/ObjectPool.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 8399925A2029114B00C76A1E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839992592029114B00C76A1E /* AppDelegate.swift */; };
11 | 8399925C2029114B00C76A1E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8399925B2029114B00C76A1E /* ViewController.swift */; };
12 | 8399925F2029114B00C76A1E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8399925D2029114B00C76A1E /* Main.storyboard */; };
13 | 839992612029114B00C76A1E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 839992602029114B00C76A1E /* Assets.xcassets */; };
14 | 839992642029114B00C76A1E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 839992622029114B00C76A1E /* LaunchScreen.storyboard */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | 839992562029114B00C76A1E /* ObjectPool.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ObjectPool.app; sourceTree = BUILT_PRODUCTS_DIR; };
19 | 839992592029114B00C76A1E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
20 | 8399925B2029114B00C76A1E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
21 | 8399925E2029114B00C76A1E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
22 | 839992602029114B00C76A1E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
23 | 839992632029114B00C76A1E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
24 | 839992652029114B00C76A1E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
25 | /* End PBXFileReference section */
26 |
27 | /* Begin PBXFrameworksBuildPhase section */
28 | 839992532029114B00C76A1E /* Frameworks */ = {
29 | isa = PBXFrameworksBuildPhase;
30 | buildActionMask = 2147483647;
31 | files = (
32 | );
33 | runOnlyForDeploymentPostprocessing = 0;
34 | };
35 | /* End PBXFrameworksBuildPhase section */
36 |
37 | /* Begin PBXGroup section */
38 | 8399924D2029114B00C76A1E = {
39 | isa = PBXGroup;
40 | children = (
41 | 839992582029114B00C76A1E /* ObjectPool */,
42 | 839992572029114B00C76A1E /* Products */,
43 | );
44 | sourceTree = "";
45 | };
46 | 839992572029114B00C76A1E /* Products */ = {
47 | isa = PBXGroup;
48 | children = (
49 | 839992562029114B00C76A1E /* ObjectPool.app */,
50 | );
51 | name = Products;
52 | sourceTree = "";
53 | };
54 | 839992582029114B00C76A1E /* ObjectPool */ = {
55 | isa = PBXGroup;
56 | children = (
57 | 839992592029114B00C76A1E /* AppDelegate.swift */,
58 | 8399925B2029114B00C76A1E /* ViewController.swift */,
59 | 8399925D2029114B00C76A1E /* Main.storyboard */,
60 | 839992602029114B00C76A1E /* Assets.xcassets */,
61 | 839992622029114B00C76A1E /* LaunchScreen.storyboard */,
62 | 839992652029114B00C76A1E /* Info.plist */,
63 | );
64 | path = ObjectPool;
65 | sourceTree = "";
66 | };
67 | /* End PBXGroup section */
68 |
69 | /* Begin PBXNativeTarget section */
70 | 839992552029114B00C76A1E /* ObjectPool */ = {
71 | isa = PBXNativeTarget;
72 | buildConfigurationList = 839992682029114B00C76A1E /* Build configuration list for PBXNativeTarget "ObjectPool" */;
73 | buildPhases = (
74 | 839992522029114B00C76A1E /* Sources */,
75 | 839992532029114B00C76A1E /* Frameworks */,
76 | 839992542029114B00C76A1E /* Resources */,
77 | );
78 | buildRules = (
79 | );
80 | dependencies = (
81 | );
82 | name = ObjectPool;
83 | productName = ObjectPool;
84 | productReference = 839992562029114B00C76A1E /* ObjectPool.app */;
85 | productType = "com.apple.product-type.application";
86 | };
87 | /* End PBXNativeTarget section */
88 |
89 | /* Begin PBXProject section */
90 | 8399924E2029114B00C76A1E /* Project object */ = {
91 | isa = PBXProject;
92 | attributes = {
93 | LastSwiftUpdateCheck = 0920;
94 | LastUpgradeCheck = 0920;
95 | ORGANIZATIONNAME = Udacity;
96 | TargetAttributes = {
97 | 839992552029114B00C76A1E = {
98 | CreatedOnToolsVersion = 9.2;
99 | ProvisioningStyle = Automatic;
100 | };
101 | };
102 | };
103 | buildConfigurationList = 839992512029114B00C76A1E /* Build configuration list for PBXProject "ObjectPool" */;
104 | compatibilityVersion = "Xcode 8.0";
105 | developmentRegion = en;
106 | hasScannedForEncodings = 0;
107 | knownRegions = (
108 | en,
109 | Base,
110 | );
111 | mainGroup = 8399924D2029114B00C76A1E;
112 | productRefGroup = 839992572029114B00C76A1E /* Products */;
113 | projectDirPath = "";
114 | projectRoot = "";
115 | targets = (
116 | 839992552029114B00C76A1E /* ObjectPool */,
117 | );
118 | };
119 | /* End PBXProject section */
120 |
121 | /* Begin PBXResourcesBuildPhase section */
122 | 839992542029114B00C76A1E /* Resources */ = {
123 | isa = PBXResourcesBuildPhase;
124 | buildActionMask = 2147483647;
125 | files = (
126 | 839992642029114B00C76A1E /* LaunchScreen.storyboard in Resources */,
127 | 839992612029114B00C76A1E /* Assets.xcassets in Resources */,
128 | 8399925F2029114B00C76A1E /* Main.storyboard in Resources */,
129 | );
130 | runOnlyForDeploymentPostprocessing = 0;
131 | };
132 | /* End PBXResourcesBuildPhase section */
133 |
134 | /* Begin PBXSourcesBuildPhase section */
135 | 839992522029114B00C76A1E /* Sources */ = {
136 | isa = PBXSourcesBuildPhase;
137 | buildActionMask = 2147483647;
138 | files = (
139 | 8399925C2029114B00C76A1E /* ViewController.swift in Sources */,
140 | 8399925A2029114B00C76A1E /* AppDelegate.swift in Sources */,
141 | );
142 | runOnlyForDeploymentPostprocessing = 0;
143 | };
144 | /* End PBXSourcesBuildPhase section */
145 |
146 | /* Begin PBXVariantGroup section */
147 | 8399925D2029114B00C76A1E /* Main.storyboard */ = {
148 | isa = PBXVariantGroup;
149 | children = (
150 | 8399925E2029114B00C76A1E /* Base */,
151 | );
152 | name = Main.storyboard;
153 | sourceTree = "";
154 | };
155 | 839992622029114B00C76A1E /* LaunchScreen.storyboard */ = {
156 | isa = PBXVariantGroup;
157 | children = (
158 | 839992632029114B00C76A1E /* Base */,
159 | );
160 | name = LaunchScreen.storyboard;
161 | sourceTree = "";
162 | };
163 | /* End PBXVariantGroup section */
164 |
165 | /* Begin XCBuildConfiguration section */
166 | 839992662029114B00C76A1E /* Debug */ = {
167 | isa = XCBuildConfiguration;
168 | buildSettings = {
169 | ALWAYS_SEARCH_USER_PATHS = NO;
170 | CLANG_ANALYZER_NONNULL = YES;
171 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
172 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
173 | CLANG_CXX_LIBRARY = "libc++";
174 | CLANG_ENABLE_MODULES = YES;
175 | CLANG_ENABLE_OBJC_ARC = YES;
176 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
177 | CLANG_WARN_BOOL_CONVERSION = YES;
178 | CLANG_WARN_COMMA = YES;
179 | CLANG_WARN_CONSTANT_CONVERSION = YES;
180 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
181 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
182 | CLANG_WARN_EMPTY_BODY = YES;
183 | CLANG_WARN_ENUM_CONVERSION = YES;
184 | CLANG_WARN_INFINITE_RECURSION = YES;
185 | CLANG_WARN_INT_CONVERSION = YES;
186 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
187 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
188 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
189 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
190 | CLANG_WARN_STRICT_PROTOTYPES = YES;
191 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
192 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
193 | CLANG_WARN_UNREACHABLE_CODE = YES;
194 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
195 | CODE_SIGN_IDENTITY = "iPhone Developer";
196 | COPY_PHASE_STRIP = NO;
197 | DEBUG_INFORMATION_FORMAT = dwarf;
198 | ENABLE_STRICT_OBJC_MSGSEND = YES;
199 | ENABLE_TESTABILITY = YES;
200 | GCC_C_LANGUAGE_STANDARD = gnu11;
201 | GCC_DYNAMIC_NO_PIC = NO;
202 | GCC_NO_COMMON_BLOCKS = YES;
203 | GCC_OPTIMIZATION_LEVEL = 0;
204 | GCC_PREPROCESSOR_DEFINITIONS = (
205 | "DEBUG=1",
206 | "$(inherited)",
207 | );
208 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
209 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
210 | GCC_WARN_UNDECLARED_SELECTOR = YES;
211 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
212 | GCC_WARN_UNUSED_FUNCTION = YES;
213 | GCC_WARN_UNUSED_VARIABLE = YES;
214 | IPHONEOS_DEPLOYMENT_TARGET = 11.2;
215 | MTL_ENABLE_DEBUG_INFO = YES;
216 | ONLY_ACTIVE_ARCH = YES;
217 | SDKROOT = iphoneos;
218 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
219 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
220 | };
221 | name = Debug;
222 | };
223 | 839992672029114B00C76A1E /* Release */ = {
224 | isa = XCBuildConfiguration;
225 | buildSettings = {
226 | ALWAYS_SEARCH_USER_PATHS = NO;
227 | CLANG_ANALYZER_NONNULL = YES;
228 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
229 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
230 | CLANG_CXX_LIBRARY = "libc++";
231 | CLANG_ENABLE_MODULES = YES;
232 | CLANG_ENABLE_OBJC_ARC = YES;
233 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
234 | CLANG_WARN_BOOL_CONVERSION = YES;
235 | CLANG_WARN_COMMA = YES;
236 | CLANG_WARN_CONSTANT_CONVERSION = YES;
237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
238 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
239 | CLANG_WARN_EMPTY_BODY = YES;
240 | CLANG_WARN_ENUM_CONVERSION = YES;
241 | CLANG_WARN_INFINITE_RECURSION = YES;
242 | CLANG_WARN_INT_CONVERSION = YES;
243 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
244 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
245 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
246 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
247 | CLANG_WARN_STRICT_PROTOTYPES = YES;
248 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
249 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
250 | CLANG_WARN_UNREACHABLE_CODE = YES;
251 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
252 | CODE_SIGN_IDENTITY = "iPhone Developer";
253 | COPY_PHASE_STRIP = NO;
254 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
255 | ENABLE_NS_ASSERTIONS = NO;
256 | ENABLE_STRICT_OBJC_MSGSEND = YES;
257 | GCC_C_LANGUAGE_STANDARD = gnu11;
258 | GCC_NO_COMMON_BLOCKS = YES;
259 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
260 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
261 | GCC_WARN_UNDECLARED_SELECTOR = YES;
262 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
263 | GCC_WARN_UNUSED_FUNCTION = YES;
264 | GCC_WARN_UNUSED_VARIABLE = YES;
265 | IPHONEOS_DEPLOYMENT_TARGET = 11.2;
266 | MTL_ENABLE_DEBUG_INFO = NO;
267 | SDKROOT = iphoneos;
268 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
269 | VALIDATE_PRODUCT = YES;
270 | };
271 | name = Release;
272 | };
273 | 839992692029114B00C76A1E /* Debug */ = {
274 | isa = XCBuildConfiguration;
275 | buildSettings = {
276 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
277 | CODE_SIGN_STYLE = Automatic;
278 | DEVELOPMENT_TEAM = 3K82E7YE87;
279 | INFOPLIST_FILE = ObjectPool/Info.plist;
280 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
281 | PRODUCT_BUNDLE_IDENTIFIER = udacity.ObjectPool;
282 | PRODUCT_NAME = "$(TARGET_NAME)";
283 | SWIFT_VERSION = 4.0;
284 | TARGETED_DEVICE_FAMILY = "1,2";
285 | };
286 | name = Debug;
287 | };
288 | 8399926A2029114B00C76A1E /* Release */ = {
289 | isa = XCBuildConfiguration;
290 | buildSettings = {
291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
292 | CODE_SIGN_STYLE = Automatic;
293 | DEVELOPMENT_TEAM = 3K82E7YE87;
294 | INFOPLIST_FILE = ObjectPool/Info.plist;
295 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
296 | PRODUCT_BUNDLE_IDENTIFIER = udacity.ObjectPool;
297 | PRODUCT_NAME = "$(TARGET_NAME)";
298 | SWIFT_VERSION = 4.0;
299 | TARGETED_DEVICE_FAMILY = "1,2";
300 | };
301 | name = Release;
302 | };
303 | /* End XCBuildConfiguration section */
304 |
305 | /* Begin XCConfigurationList section */
306 | 839992512029114B00C76A1E /* Build configuration list for PBXProject "ObjectPool" */ = {
307 | isa = XCConfigurationList;
308 | buildConfigurations = (
309 | 839992662029114B00C76A1E /* Debug */,
310 | 839992672029114B00C76A1E /* Release */,
311 | );
312 | defaultConfigurationIsVisible = 0;
313 | defaultConfigurationName = Release;
314 | };
315 | 839992682029114B00C76A1E /* Build configuration list for PBXNativeTarget "ObjectPool" */ = {
316 | isa = XCConfigurationList;
317 | buildConfigurations = (
318 | 839992692029114B00C76A1E /* Debug */,
319 | 8399926A2029114B00C76A1E /* Release */,
320 | );
321 | defaultConfigurationIsVisible = 0;
322 | defaultConfigurationName = Release;
323 | };
324 | /* End XCConfigurationList section */
325 | };
326 | rootObject = 8399924E2029114B00C76A1E /* Project object */;
327 | }
328 |
--------------------------------------------------------------------------------
/creational-design-patterns/object-pool/starter/ObjectPool/ObjectPool.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 8399925A2029114B00C76A1E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 839992592029114B00C76A1E /* AppDelegate.swift */; };
11 | 8399925C2029114B00C76A1E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8399925B2029114B00C76A1E /* ViewController.swift */; };
12 | 8399925F2029114B00C76A1E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8399925D2029114B00C76A1E /* Main.storyboard */; };
13 | 839992612029114B00C76A1E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 839992602029114B00C76A1E /* Assets.xcassets */; };
14 | 839992642029114B00C76A1E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 839992622029114B00C76A1E /* LaunchScreen.storyboard */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | 839992562029114B00C76A1E /* ObjectPool.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ObjectPool.app; sourceTree = BUILT_PRODUCTS_DIR; };
19 | 839992592029114B00C76A1E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
20 | 8399925B2029114B00C76A1E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
21 | 8399925E2029114B00C76A1E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
22 | 839992602029114B00C76A1E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
23 | 839992632029114B00C76A1E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
24 | 839992652029114B00C76A1E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
25 | /* End PBXFileReference section */
26 |
27 | /* Begin PBXFrameworksBuildPhase section */
28 | 839992532029114B00C76A1E /* Frameworks */ = {
29 | isa = PBXFrameworksBuildPhase;
30 | buildActionMask = 2147483647;
31 | files = (
32 | );
33 | runOnlyForDeploymentPostprocessing = 0;
34 | };
35 | /* End PBXFrameworksBuildPhase section */
36 |
37 | /* Begin PBXGroup section */
38 | 8399924D2029114B00C76A1E = {
39 | isa = PBXGroup;
40 | children = (
41 | 839992582029114B00C76A1E /* ObjectPool */,
42 | 839992572029114B00C76A1E /* Products */,
43 | );
44 | sourceTree = "";
45 | };
46 | 839992572029114B00C76A1E /* Products */ = {
47 | isa = PBXGroup;
48 | children = (
49 | 839992562029114B00C76A1E /* ObjectPool.app */,
50 | );
51 | name = Products;
52 | sourceTree = "";
53 | };
54 | 839992582029114B00C76A1E /* ObjectPool */ = {
55 | isa = PBXGroup;
56 | children = (
57 | 839992592029114B00C76A1E /* AppDelegate.swift */,
58 | 8399925B2029114B00C76A1E /* ViewController.swift */,
59 | 8399925D2029114B00C76A1E /* Main.storyboard */,
60 | 839992602029114B00C76A1E /* Assets.xcassets */,
61 | 839992622029114B00C76A1E /* LaunchScreen.storyboard */,
62 | 839992652029114B00C76A1E /* Info.plist */,
63 | );
64 | path = ObjectPool;
65 | sourceTree = "";
66 | };
67 | /* End PBXGroup section */
68 |
69 | /* Begin PBXNativeTarget section */
70 | 839992552029114B00C76A1E /* ObjectPool */ = {
71 | isa = PBXNativeTarget;
72 | buildConfigurationList = 839992682029114B00C76A1E /* Build configuration list for PBXNativeTarget "ObjectPool" */;
73 | buildPhases = (
74 | 839992522029114B00C76A1E /* Sources */,
75 | 839992532029114B00C76A1E /* Frameworks */,
76 | 839992542029114B00C76A1E /* Resources */,
77 | );
78 | buildRules = (
79 | );
80 | dependencies = (
81 | );
82 | name = ObjectPool;
83 | productName = ObjectPool;
84 | productReference = 839992562029114B00C76A1E /* ObjectPool.app */;
85 | productType = "com.apple.product-type.application";
86 | };
87 | /* End PBXNativeTarget section */
88 |
89 | /* Begin PBXProject section */
90 | 8399924E2029114B00C76A1E /* Project object */ = {
91 | isa = PBXProject;
92 | attributes = {
93 | LastSwiftUpdateCheck = 0920;
94 | LastUpgradeCheck = 0920;
95 | ORGANIZATIONNAME = Udacity;
96 | TargetAttributes = {
97 | 839992552029114B00C76A1E = {
98 | CreatedOnToolsVersion = 9.2;
99 | ProvisioningStyle = Automatic;
100 | };
101 | };
102 | };
103 | buildConfigurationList = 839992512029114B00C76A1E /* Build configuration list for PBXProject "ObjectPool" */;
104 | compatibilityVersion = "Xcode 8.0";
105 | developmentRegion = en;
106 | hasScannedForEncodings = 0;
107 | knownRegions = (
108 | en,
109 | Base,
110 | );
111 | mainGroup = 8399924D2029114B00C76A1E;
112 | productRefGroup = 839992572029114B00C76A1E /* Products */;
113 | projectDirPath = "";
114 | projectRoot = "";
115 | targets = (
116 | 839992552029114B00C76A1E /* ObjectPool */,
117 | );
118 | };
119 | /* End PBXProject section */
120 |
121 | /* Begin PBXResourcesBuildPhase section */
122 | 839992542029114B00C76A1E /* Resources */ = {
123 | isa = PBXResourcesBuildPhase;
124 | buildActionMask = 2147483647;
125 | files = (
126 | 839992642029114B00C76A1E /* LaunchScreen.storyboard in Resources */,
127 | 839992612029114B00C76A1E /* Assets.xcassets in Resources */,
128 | 8399925F2029114B00C76A1E /* Main.storyboard in Resources */,
129 | );
130 | runOnlyForDeploymentPostprocessing = 0;
131 | };
132 | /* End PBXResourcesBuildPhase section */
133 |
134 | /* Begin PBXSourcesBuildPhase section */
135 | 839992522029114B00C76A1E /* Sources */ = {
136 | isa = PBXSourcesBuildPhase;
137 | buildActionMask = 2147483647;
138 | files = (
139 | 8399925C2029114B00C76A1E /* ViewController.swift in Sources */,
140 | 8399925A2029114B00C76A1E /* AppDelegate.swift in Sources */,
141 | );
142 | runOnlyForDeploymentPostprocessing = 0;
143 | };
144 | /* End PBXSourcesBuildPhase section */
145 |
146 | /* Begin PBXVariantGroup section */
147 | 8399925D2029114B00C76A1E /* Main.storyboard */ = {
148 | isa = PBXVariantGroup;
149 | children = (
150 | 8399925E2029114B00C76A1E /* Base */,
151 | );
152 | name = Main.storyboard;
153 | sourceTree = "";
154 | };
155 | 839992622029114B00C76A1E /* LaunchScreen.storyboard */ = {
156 | isa = PBXVariantGroup;
157 | children = (
158 | 839992632029114B00C76A1E /* Base */,
159 | );
160 | name = LaunchScreen.storyboard;
161 | sourceTree = "";
162 | };
163 | /* End PBXVariantGroup section */
164 |
165 | /* Begin XCBuildConfiguration section */
166 | 839992662029114B00C76A1E /* Debug */ = {
167 | isa = XCBuildConfiguration;
168 | buildSettings = {
169 | ALWAYS_SEARCH_USER_PATHS = NO;
170 | CLANG_ANALYZER_NONNULL = YES;
171 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
172 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
173 | CLANG_CXX_LIBRARY = "libc++";
174 | CLANG_ENABLE_MODULES = YES;
175 | CLANG_ENABLE_OBJC_ARC = YES;
176 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
177 | CLANG_WARN_BOOL_CONVERSION = YES;
178 | CLANG_WARN_COMMA = YES;
179 | CLANG_WARN_CONSTANT_CONVERSION = YES;
180 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
181 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
182 | CLANG_WARN_EMPTY_BODY = YES;
183 | CLANG_WARN_ENUM_CONVERSION = YES;
184 | CLANG_WARN_INFINITE_RECURSION = YES;
185 | CLANG_WARN_INT_CONVERSION = YES;
186 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
187 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
188 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
189 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
190 | CLANG_WARN_STRICT_PROTOTYPES = YES;
191 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
192 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
193 | CLANG_WARN_UNREACHABLE_CODE = YES;
194 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
195 | CODE_SIGN_IDENTITY = "iPhone Developer";
196 | COPY_PHASE_STRIP = NO;
197 | DEBUG_INFORMATION_FORMAT = dwarf;
198 | ENABLE_STRICT_OBJC_MSGSEND = YES;
199 | ENABLE_TESTABILITY = YES;
200 | GCC_C_LANGUAGE_STANDARD = gnu11;
201 | GCC_DYNAMIC_NO_PIC = NO;
202 | GCC_NO_COMMON_BLOCKS = YES;
203 | GCC_OPTIMIZATION_LEVEL = 0;
204 | GCC_PREPROCESSOR_DEFINITIONS = (
205 | "DEBUG=1",
206 | "$(inherited)",
207 | );
208 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
209 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
210 | GCC_WARN_UNDECLARED_SELECTOR = YES;
211 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
212 | GCC_WARN_UNUSED_FUNCTION = YES;
213 | GCC_WARN_UNUSED_VARIABLE = YES;
214 | IPHONEOS_DEPLOYMENT_TARGET = 11.2;
215 | MTL_ENABLE_DEBUG_INFO = YES;
216 | ONLY_ACTIVE_ARCH = YES;
217 | SDKROOT = iphoneos;
218 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
219 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
220 | };
221 | name = Debug;
222 | };
223 | 839992672029114B00C76A1E /* Release */ = {
224 | isa = XCBuildConfiguration;
225 | buildSettings = {
226 | ALWAYS_SEARCH_USER_PATHS = NO;
227 | CLANG_ANALYZER_NONNULL = YES;
228 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
229 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
230 | CLANG_CXX_LIBRARY = "libc++";
231 | CLANG_ENABLE_MODULES = YES;
232 | CLANG_ENABLE_OBJC_ARC = YES;
233 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
234 | CLANG_WARN_BOOL_CONVERSION = YES;
235 | CLANG_WARN_COMMA = YES;
236 | CLANG_WARN_CONSTANT_CONVERSION = YES;
237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
238 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
239 | CLANG_WARN_EMPTY_BODY = YES;
240 | CLANG_WARN_ENUM_CONVERSION = YES;
241 | CLANG_WARN_INFINITE_RECURSION = YES;
242 | CLANG_WARN_INT_CONVERSION = YES;
243 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
244 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
245 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
246 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
247 | CLANG_WARN_STRICT_PROTOTYPES = YES;
248 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
249 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
250 | CLANG_WARN_UNREACHABLE_CODE = YES;
251 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
252 | CODE_SIGN_IDENTITY = "iPhone Developer";
253 | COPY_PHASE_STRIP = NO;
254 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
255 | ENABLE_NS_ASSERTIONS = NO;
256 | ENABLE_STRICT_OBJC_MSGSEND = YES;
257 | GCC_C_LANGUAGE_STANDARD = gnu11;
258 | GCC_NO_COMMON_BLOCKS = YES;
259 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
260 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
261 | GCC_WARN_UNDECLARED_SELECTOR = YES;
262 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
263 | GCC_WARN_UNUSED_FUNCTION = YES;
264 | GCC_WARN_UNUSED_VARIABLE = YES;
265 | IPHONEOS_DEPLOYMENT_TARGET = 11.2;
266 | MTL_ENABLE_DEBUG_INFO = NO;
267 | SDKROOT = iphoneos;
268 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
269 | VALIDATE_PRODUCT = YES;
270 | };
271 | name = Release;
272 | };
273 | 839992692029114B00C76A1E /* Debug */ = {
274 | isa = XCBuildConfiguration;
275 | buildSettings = {
276 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
277 | CODE_SIGN_STYLE = Automatic;
278 | DEVELOPMENT_TEAM = 3K82E7YE87;
279 | INFOPLIST_FILE = ObjectPool/Info.plist;
280 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
281 | PRODUCT_BUNDLE_IDENTIFIER = udacity.ObjectPool;
282 | PRODUCT_NAME = "$(TARGET_NAME)";
283 | SWIFT_VERSION = 4.0;
284 | TARGETED_DEVICE_FAMILY = "1,2";
285 | };
286 | name = Debug;
287 | };
288 | 8399926A2029114B00C76A1E /* Release */ = {
289 | isa = XCBuildConfiguration;
290 | buildSettings = {
291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
292 | CODE_SIGN_STYLE = Automatic;
293 | DEVELOPMENT_TEAM = 3K82E7YE87;
294 | INFOPLIST_FILE = ObjectPool/Info.plist;
295 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
296 | PRODUCT_BUNDLE_IDENTIFIER = udacity.ObjectPool;
297 | PRODUCT_NAME = "$(TARGET_NAME)";
298 | SWIFT_VERSION = 4.0;
299 | TARGETED_DEVICE_FAMILY = "1,2";
300 | };
301 | name = Release;
302 | };
303 | /* End XCBuildConfiguration section */
304 |
305 | /* Begin XCConfigurationList section */
306 | 839992512029114B00C76A1E /* Build configuration list for PBXProject "ObjectPool" */ = {
307 | isa = XCConfigurationList;
308 | buildConfigurations = (
309 | 839992662029114B00C76A1E /* Debug */,
310 | 839992672029114B00C76A1E /* Release */,
311 | );
312 | defaultConfigurationIsVisible = 0;
313 | defaultConfigurationName = Release;
314 | };
315 | 839992682029114B00C76A1E /* Build configuration list for PBXNativeTarget "ObjectPool" */ = {
316 | isa = XCConfigurationList;
317 | buildConfigurations = (
318 | 839992692029114B00C76A1E /* Debug */,
319 | 8399926A2029114B00C76A1E /* Release */,
320 | );
321 | defaultConfigurationIsVisible = 0;
322 | defaultConfigurationName = Release;
323 | };
324 | /* End XCConfigurationList section */
325 | };
326 | rootObject = 8399924E2029114B00C76A1E /* Project object */;
327 | }
328 |
--------------------------------------------------------------------------------