├── .github └── workflows │ └── manual.yml ├── .gitignore ├── AssociatedValues ├── AssociatedValues.playground │ ├── Pages │ │ ├── Associated Values.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── timeline.xctimeline │ │ ├── Enums within Enums.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Extract with If.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── timeline.xctimeline │ │ ├── Extract with Switch.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ └── Raw Values.xcplaygroundpage │ │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Exercises.playground │ ├── Pages │ │ ├── Associated Values.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Enums within Enums.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ │ ├── model3.png │ │ │ │ ├── modelS.png │ │ │ │ └── modelX.png │ │ ├── Extract with If.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Extract with Switch.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ └── Raw Values.xcplaygroundpage │ │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── ExercisesSolutions.playground │ ├── Pages │ ├── Associated Values.xcplaygroundpage │ │ └── Contents.swift │ ├── Enums within Enums.xcplaygroundpage │ │ ├── Contents.swift │ │ └── Resources │ │ │ ├── model3.png │ │ │ ├── modelS.png │ │ │ └── modelX.png │ ├── Extract with If.xcplaygroundpage │ │ └── Contents.swift │ ├── Extract with Switch.xcplaygroundpage │ │ └── Contents.swift │ ├── Intro.xcplaygroundpage │ │ └── Contents.swift │ └── Raw Values.xcplaygroundpage │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── CODEOWNERS ├── ClassesPropertiesMethods ├── ClassesPropertiesMethods.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ │ └── contents.xcworkspacedata │ └── timeline.xctimeline ├── Exercises.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Resources │ ├── fluffyDog.jpg │ └── fluffyDog.png │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Closures ├── Closures.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Exercises.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Collections ├── Collections.playground │ ├── Contents.swift │ ├── Resources │ │ ├── flatware-set.JPG │ │ └── flatware-set_200x200.JPG │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Exercises.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ │ └── contents.xcworkspacedata │ └── timeline.xctimeline └── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ └── contents.xcworkspacedata │ └── timeline.xctimeline ├── ControlFlow ├── ControlFlow.playground │ ├── Contents.swift │ ├── Resources │ │ ├── goat.jpg │ │ └── monkey.jpg │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Exercises.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── EnumsStructs ├── EnumsStructs.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Exercises.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Errors ├── Errors.playground │ ├── Pages │ │ ├── Cleanup with Defer.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Create Custom Errors.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Describe Custom Errors.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Error Handling Summary.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ │ ├── swift.png │ │ │ │ └── swift.txt │ │ ├── Handle Errors.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ │ ├── swift.png │ │ │ │ └── swift.txt │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Propagate Errors.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ │ ├── swift.png │ │ │ │ └── swift.txt │ │ └── The Many Faces of Try.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ ├── swift.png │ │ │ └── swift.txt │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Exercises.playground │ ├── Pages │ │ ├── Cleanup with Defer.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Create Custom Errors.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Describe Custom Errors.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Error Handling Summary.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ │ ├── swift.png │ │ │ │ └── swift.txt │ │ ├── Handle Errors.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ │ ├── swift.png │ │ │ │ └── swift.txt │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Propagate Errors.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ │ ├── swift.png │ │ │ │ └── swift.txt │ │ └── The Many Faces of Try.xcplaygroundpage │ │ │ ├── Contents.swift │ │ │ └── Resources │ │ │ ├── swift.png │ │ │ └── swift.txt │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── ExercisesSolutions.playground │ ├── Pages │ ├── Cleanup with Defer.xcplaygroundpage │ │ └── Contents.swift │ ├── Create Custom Errors.xcplaygroundpage │ │ └── Contents.swift │ ├── Describe Custom Errors.xcplaygroundpage │ │ └── Contents.swift │ ├── Error Handling Summary.xcplaygroundpage │ │ ├── Contents.swift │ │ └── Resources │ │ │ ├── swift.png │ │ │ └── swift.txt │ ├── Handle Errors.xcplaygroundpage │ │ ├── Contents.swift │ │ └── Resources │ │ │ ├── swift.png │ │ │ └── swift.txt │ ├── Intro.xcplaygroundpage │ │ └── Contents.swift │ ├── Propagate Errors.xcplaygroundpage │ │ ├── Contents.swift │ │ └── Resources │ │ │ ├── swift.png │ │ │ └── swift.txt │ └── The Many Faces of Try.xcplaygroundpage │ │ ├── Contents.swift │ │ └── Resources │ │ ├── swift.png │ │ └── swift.txt │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Functions ├── Exercises.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ │ └── contents.xcworkspacedata │ └── timeline.xctimeline ├── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── Functions.playground │ ├── Contents.swift │ ├── Resources │ └── nestedDolls.jpg │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Generics ├── Exercises.playground │ ├── Pages │ │ ├── A Generic Function.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── A Generic Type.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Arrays are Generic.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Multiple Generic Types.xcplaygroundpage │ │ │ └── Contents.swift │ │ └── Subclass a Generic Type.xcplaygroundpage │ │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── ExercisesSolutions.playground │ ├── Pages │ │ ├── A Generic Function.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── A Generic Type.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Arrays are Generic.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Multiple Generic Types.xcplaygroundpage │ │ │ └── Contents.swift │ │ └── Subclass a Generic Type.xcplaygroundpage │ │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── Generics.playground │ ├── Pages │ ├── A Generic Function.xcplaygroundpage │ │ └── Contents.swift │ ├── A Generic Type.xcplaygroundpage │ │ └── Contents.swift │ ├── Arrays are Generic.xcplaygroundpage │ │ ├── Contents.swift │ │ └── timeline.xctimeline │ ├── Intro.xcplaygroundpage │ │ └── Contents.swift │ ├── Multiple Generic Types.xcplaygroundpage │ │ └── Contents.swift │ └── Subclass a Generic Type.xcplaygroundpage │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Guards ├── Exercises.playground │ ├── Pages │ │ ├── Guard Let Versus If Let.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Guard Versus If.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Guard with Optionals.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ └── The Guard Statement.xcplaygroundpage │ │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── ExercisesSolutions.playground │ ├── Pages │ │ ├── Guard Let Versus If Let.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Guard Versus If.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Guard with Optionals.xcplaygroundpage │ │ │ └── Contents.swift │ │ ├── Intro.xcplaygroundpage │ │ │ └── Contents.swift │ │ └── The Guard Statement.xcplaygroundpage │ │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── Guards.playground │ ├── Pages │ ├── Guard Let Versus If Let.xcplaygroundpage │ │ └── Contents.swift │ ├── Guard Versus If.xcplaygroundpage │ │ └── Contents.swift │ ├── Guard with Optionals.xcplaygroundpage │ │ └── Contents.swift │ ├── Intro.xcplaygroundpage │ │ └── Contents.swift │ └── The Guard Statement.xcplaygroundpage │ │ └── Contents.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── LICENSE ├── Optionals ├── DowncastingWithOptionals.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ │ └── contents.xcworkspacedata │ └── timeline.xctimeline ├── Exercises.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ ├── playground.xcworkspace │ │ └── contents.xcworkspacedata │ └── timeline.xctimeline ├── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata └── Optionals.playground │ ├── Contents.swift │ ├── Resources │ ├── puppy_in_box.jpg │ ├── puppy_in_box.png │ └── yorkshire-terrier-puppy_small.png │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── ProtocolsExtensions ├── CalmTheCompiler.playground │ ├── Contents.swift │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── Exercises.playground │ ├── Contents.swift │ ├── Resources │ │ ├── frolick.jpg │ │ └── mouseBall.png │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── ExercisesSolutions.playground │ ├── Contents.swift │ ├── Resources │ │ ├── dogInABall.png │ │ ├── frolick.jpg │ │ └── mouseBall.png │ ├── Sources │ │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ │ └── contents.xcworkspacedata ├── FadeExtensionDemo │ ├── FadeExtensionDemo.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── FadeExtensionDemo │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-1024.png │ │ │ ├── Icon-20.png │ │ │ ├── Icon-40-2.png │ │ │ ├── Icon-40-3.png │ │ │ ├── Icon-40.png │ │ │ ├── Icon-40@2x.png │ │ │ ├── Icon-40@3x.png │ │ │ ├── Icon-60@2x-2.png │ │ │ ├── Icon-60@2x.png │ │ │ ├── Icon-60@3x.png │ │ │ ├── Icon-76.png │ │ │ ├── Icon-76@2x.png │ │ │ ├── Icon-83.5@2x.png │ │ │ ├── Icon-Small.png │ │ │ ├── Icon-Small@2x.png │ │ │ └── Icon-Small@3x.png │ │ ├── LaunchLogo.imageset │ │ │ ├── Contents.json │ │ │ └── LaunchLogo.pdf │ │ ├── sunrise.imageset │ │ │ ├── 6776635-beautiful-sunrise-wallpaper.jpg │ │ │ └── Contents.json │ │ └── sunset.imageset │ │ │ ├── Contents.json │ │ │ └── mountain-sunset.jpg │ │ ├── Info.plist │ │ ├── UIViewExtensions.swift │ │ └── ViewController.swift ├── FadeExtensionDemo_Completed │ ├── FadeExtensionDemo_Completed.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── FadeExtensionDemo_Completed │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-1024.png │ │ │ ├── Icon-20.png │ │ │ ├── Icon-40-2.png │ │ │ ├── Icon-40-3.png │ │ │ ├── Icon-40.png │ │ │ ├── Icon-40@2x.png │ │ │ ├── Icon-40@3x.png │ │ │ ├── Icon-60@2x-2.png │ │ │ ├── Icon-60@2x.png │ │ │ ├── Icon-60@3x.png │ │ │ ├── Icon-76.png │ │ │ ├── Icon-76@2x.png │ │ │ ├── Icon-83.5@2x.png │ │ │ ├── Icon-Small.png │ │ │ ├── Icon-Small@2x.png │ │ │ └── Icon-Small@3x.png │ │ ├── LaunchLogo.imageset │ │ │ ├── Contents.json │ │ │ └── LaunchLogo.pdf │ │ ├── sunrise.imageset │ │ │ ├── 6776635-beautiful-sunrise-wallpaper.jpg │ │ │ └── Contents.json │ │ └── sunset.imageset │ │ │ ├── Contents.json │ │ │ └── mountain-sunset.jpg │ │ ├── Info.plist │ │ ├── UIViewExtensions.swift │ │ └── ViewController.swift └── Protocols.playground │ ├── Contents.swift │ ├── Sources │ └── SupportCode.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ └── contents.xcworkspacedata ├── README.md └── SwiftBasics ├── ConstantsVariables.playground ├── Contents.swift ├── Resources │ ├── Chinese-New-Year-3 copy.jpg │ ├── Chinese-New-Year-3.jpg │ ├── Chinese-New-Year-goat.jpg │ ├── chubby-baby-picture.jpg │ ├── chubby_baby_with_dog.jpeg │ └── cute_baby_and_dog.jpg ├── Sources │ └── SupportCode.swift ├── contents.xcplayground └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Exercises.playground ├── Contents.swift ├── Sources │ └── SupportCode.swift ├── contents.xcplayground ├── playground.xcworkspace │ └── contents.xcworkspacedata └── timeline.xctimeline ├── ExercisesSolution.playground ├── Contents.swift ├── Sources │ └── SupportCode.swift ├── contents.xcplayground └── playground.xcworkspace │ └── contents.xcworkspacedata ├── Strings.playground ├── Contents.swift ├── Resources │ ├── SpringerdoodleFerris.jpg │ ├── frankie.jpeg │ ├── frankie_small.jpg │ └── yorkshire-terrier-puppy-Max_small.jpg ├── Sources │ └── SupportCode.swift ├── contents.xcplayground └── playground.xcworkspace │ └── contents.xcworkspacedata └── TypesOperators.playground ├── Contents.swift ├── Resources └── Chloe.png ├── Sources └── SupportCode.swift ├── contents.xcplayground ├── playground.xcworkspace └── contents.xcworkspacedata └── timeline.xctimeline /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | 28 | # Carthage 29 | # 30 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 31 | # Carthage/Checkouts 32 | 33 | Carthage/Build 34 | 35 | # Ignore those pesky DS_Store files! 36 | .DS_Store 37 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/Pages/Associated Values.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Associated Values 3 | //: Associated values are defined alongside enum cases. Associated values are not required; some enum cases may have an associated value while others do not. In the example below, `LibraryFee` has three cases with associated values and a case without an associated value. 4 | //: 5 | enum LibraryFee { 6 | case overdueBook(Int) 7 | case lostBook(Double) 8 | case lostLibraryCard(Int) 9 | case annualDues 10 | } 11 | 12 | let fee = LibraryFee.overdueBook(4) 13 | //: It can be very helpful to name associated values so that their intent is easily understood. 14 | //: 15 | enum DescriptiveLibraryFee { 16 | case overdueBook(days: Int) 17 | case lostBook(price: Double) 18 | case lostLibraryCard(timesLost: Int) 19 | case annualDues 20 | } 21 | 22 | let weekLateFee = DescriptiveLibraryFee.overdueBook(days: 7) 23 | //: Associated values are actually tuples. Therefore, an associated value can contain mutliple values. Recall from [Apple's documentation](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID329) that tuples are multiple values grouped into a single compound value. 24 | //: 25 | import UIKit 26 | 27 | enum ImageFilter { 28 | case sepia 29 | case verticalGradient(from: UIColor, to: UIColor) 30 | case horizontalGradient(from: UIColor, to: UIColor) 31 | case sketch(penThickness: Double?) 32 | } 33 | 34 | let fadeToBlack = ImageFilter.horizontalGradient(from: .gray, to: .black) 35 | //: - Callout(Watch Out!): 36 | //: If all enum cases have an associated value of the same type, and it is static, then you might consider using a raw value instead. 37 | //: 38 | // the associated values for `AudioRateAssociated` should be raw values 39 | enum AudioRateAssociated { 40 | case slow(value: Int) 41 | case normal(value: Int) 42 | case fast(value: Int) 43 | case custom(value: Int) 44 | } 45 | 46 | enum AudioRateRaw: Int { 47 | case slow, normal, fast, custom 48 | } 49 | //: [Next](@next) 50 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/Pages/Associated Values.xcplaygroundpage/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/Pages/Enums within Enums.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Enums within Enums 3 | //: An associated value can be an enum that defines more associated values. This makes for some interesting combinations — enums within enums within enums... 4 | //: 5 | import UIKit 6 | 7 | enum Thickness: Double { 8 | case light = 2.0, normal = 5.0, heavy = 8.0 9 | } 10 | 11 | enum ImageFilter { 12 | case sepia 13 | case verticalGradient(from: UIColor, to: UIColor) 14 | case horizontalGradient(from: UIColor, to: UIColor) 15 | case sketch(penThickness: Thickness) 16 | } 17 | 18 | let normalSketch = ImageFilter.sketch(penThickness: .normal) 19 | //: While enums within enums may feel extraneous, it can map nicely to real-world situations. Imagine a clothing app that needs a simple search feature. It could be implemented using enums within enums. 20 | //: 21 | enum ShirtSize { 22 | case extraSmall 23 | case small 24 | case medium 25 | case large 26 | case extraLarge 27 | } 28 | 29 | enum Search { 30 | case forShirts(sizes: [ShirtSize]) 31 | case forName(name: String) 32 | } 33 | 34 | let searchForBigShirts = Search.forShirts(sizes: [.large, .extraLarge]) 35 | let searchForHenleys = Search.forName(name: "henley") 36 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/Pages/Extract with If.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Extract with If 3 | //: Using a switch statement can be cumbersome if only a single case needs to be checked and extracted. To extract the associated value for a single case, use `if case`. 4 | //: 5 | import UIKit 6 | 7 | enum ImageFilter { 8 | case sepia 9 | case verticalGradient(from: UIColor, to: UIColor) 10 | case horizontalGradient(from: UIColor, to: UIColor) 11 | case sketch(penThickness: Double?) 12 | } 13 | 14 | let filter1 = ImageFilter.horizontalGradient(from: .gray, to: .black) 15 | let filter2 = ImageFilter.horizontalGradient(from: .white, to: .black) 16 | //: `if case` works alongside the equals operator (=) to check and extract an associated value from an enum. While the syntax may look strange, the equals operator still behaves in an intuitive way; that is, the associated value on the left-hand side (containing `color1` and `color2`) is set equal to the associated value for the enum on the right-hand side (`filter1`). 17 | //: 18 | if case ImageFilter.horizontalGradient(let color1, var color2) = filter1 { 19 | color2 = .red 20 | print("horizontal gradient with \(color1) and \(color2)") 21 | } 22 | //: To extract all values as constants use `if case let`. 23 | //: 24 | if case let ImageFilter.horizontalGradient(color1, color2) = filter1 { 25 | print("horizontal gradient with \(color1) and \(color2)") 26 | } 27 | //: Complex conditionals can be formed using `if case` and conditional statements separated by commas. If the conditional statements are held true, then the values are extracted and usable from within the `if case` block. 28 | //: 29 | if case let ImageFilter.horizontalGradient(_, color2) = filter1, color2 == .black { 30 | print("the horizontal gradient's second color is \(color2)") 31 | } 32 | //: A single associated value can also be extracted as a computed property. By using a computed property, you may avoid duplicate `if case` statements. 33 | //: 34 | extension ImageFilter { 35 | var hasHeavyPenThickness: Bool { 36 | if case let ImageFilter.sketch(penThickness) = self, let thickness = penThickness, thickness > 5.0 { 37 | return true 38 | } else { 39 | return false 40 | } 41 | } 42 | } 43 | 44 | filter1.hasHeavyPenThickness 45 | //: To learn more about extraction techniques, read [Pattern Matching, Part 4: if case, guard case, for case](http://alisoftware.github.io/swift/pattern-matching/2016/05/16/pattern-matching-4/) on Crunchy Development. 46 | //: 47 | //: [Next](@next) 48 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/Pages/Extract with If.xcplaygroundpage/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Associated Values 2 | //: Associated values are values that can be attached to enum cases. They allow developers to add additional information to a case, improving readability and conciseness. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/Pages/Raw Values.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Raw Values 3 | //: Before looking at associated values, remember that enums can have raw values which are applied to every case. In the example below, each play speed has a raw integer value. Because explicit raw values have not been specified, the raw values begin at 0 (slow) and end with 3 (custom). 4 | //: 5 | enum PlaySpeed: Int { 6 | case slow, normal, fast, custom 7 | } 8 | 9 | print(PlaySpeed.slow.rawValue) 10 | print(PlaySpeed.custom.rawValue) 11 | //: - Callout(Watch Out!): 12 | //: Recall, raw values are immutable (constant) and cannot be changed. 13 | let mySpeed = PlaySpeed.slow 14 | // mySpeed.rawValue = 3 /* causes an error */ 15 | //: If an enum uses raw string values, then each case is implicitly assigned a raw string value equal to the case's name. 16 | //: 17 | enum AudioRate: String { 18 | case slow, normal, fast, custom 19 | } 20 | 21 | print(AudioRate.slow.rawValue) 22 | print(AudioRate.custom.rawValue) 23 | //: Raw values can be set explicitly. 24 | //: 25 | enum Power: Int { 26 | case poor = 10, medium = 20, strong = 30 27 | } 28 | 29 | print(Power.poor.rawValue) 30 | print(Power.strong.rawValue) 31 | //: If some raw integer values are explicitly provided, but others are not, then implicit values are assigned as one greater than the previous raw integer value. 32 | //: 33 | enum Endurance: Int { 34 | case worst, abysmal = 10, poor, medium, strong = 30 35 | } 36 | 37 | print(Endurance.worst.rawValue) 38 | print(Endurance.poor.rawValue) 39 | print(Endurance.strong.rawValue) 40 | //: - Callout(Watch Out!): 41 | //: Avoid specifying explicit raw values out of increasing order. It can be confusing to read and cause errors if Xcode tries to use a raw value more than once. 42 | //: 43 | /* uncomment `case g` to see error. */ 44 | enum LetterToInt: Int { 45 | case a = 4, b, c, d, e = 2, f 46 | // case g /* compiler tries to implicitly set `g = 4` which fails */ 47 | } 48 | //: It is possible to create an enum from a raw value. This is useful when a value is generated, and it should represent an enum. 49 | //: 50 | let moderateStrength = Power(rawValue: 20) 51 | //: - Callout(Watch Out!): 52 | //: Since there is no guarantee that a random value has a corresponding raw value, initialize enums from raw values in a safe way. 53 | //: 54 | if let myPace = AudioRate(rawValue: "custom") { 55 | print(myPace) 56 | } 57 | //: Otherwise, initializing an enum from a raw value will return nil. 58 | //: 59 | let myPace = AudioRate(rawValue: "not a real pace") 60 | //: [Next](@next) 61 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AssociatedValues/AssociatedValues.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Associated Values.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Associated Values 3 | //: - Callout(Exercise): 4 | //: Create an array of `LunchFruit`. The array should contain seedless grapes, 4 clementines, and a whole (not sliced) apple. 5 | //: 6 | enum LunchFruit { 7 | case grapes(seedless: Bool) 8 | case clementines(count: Int) 9 | case apple(sliced: Bool) 10 | } 11 | //: - Callout(Exercise): 12 | //: Define an enum called `Prize` with cases representing a coffee mug, business cards, or lanyard. For business cards, the prize includes associated values for a name (`String`) and image (`UIImage`). For the lanyard, the prize includes an associated value for color (`UIColor`). 13 | //: 14 | import UIKit 15 | //: [Next](@next) 16 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Enums within Enums.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Enums within Enums 3 | //: - Callout(Exercise): 4 | //: Define an enum called `SConfig` representing the different configurations for the 2017 Tesla Model S vehicle. Use a raw type (Double) to represent its starting price in USD. The following image contains the possible configurations: 5 | //: 6 | //: ![model-s](/modelS.png) 7 | //: 8 | 9 | //: - Callout(Exercise): 10 | //: Define an enum called `XConfig` representing the different configurations for the 2017 Tesla Model X vehicle. Use a raw type (Double) to represent its starting price in USD. The following image contains the possible configurations: 11 | //: 12 | //: ![model-s](/modelX.png) 13 | //: 14 | 15 | //: - Callout(Exercise): 16 | //: Define an enum called `ThreeType` representing the different types for the 2017 Tesla 3 vehicle. Use a raw type (Double) to represent its starting price in USD. The following image contains the possible types: 17 | //: 18 | //: ![model-s](/model3.png) 19 | //: 20 | 21 | //: - Callout(Exercise): 22 | //: Define an enum called `Tesla2017` representing Tesla's cars for 2017 — the Model S, Model X, and Model 3. Each case (car) should have an associated value for the different configuration or type for that model. Create a constant called `newCar` that is a Standard Tesla 2017 Model 3. 23 | //: 24 | 25 | //: - Callout(Exercise): 26 | //: Use a switch statement to extract and print the starting the value for `newCar`. The switch statement should be able to handle any type of Tesla 2017 model. 27 | //: 28 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/model3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/AssociatedValues/Exercises.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/model3.png -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/AssociatedValues/Exercises.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelS.png -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/AssociatedValues/Exercises.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelX.png -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Extract with If.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Extract with If 3 | //: The following exercises will use `AudioEffect`. 4 | //: 5 | enum AudioEffect { 6 | case rate(value: Double) 7 | case pitch(value: Double) 8 | case echo 9 | case reverb 10 | } 11 | 12 | let effect = AudioEffect.pitch(value: 0.5) 13 | //: - Callout(Exercise): 14 | //: Write an if statement that extracts and prints the associated value for `effect` when the case is equal to `.pitch`. 15 | //: 16 | 17 | //: - Callout(Exercise): 18 | //: Write an if statement that extracts and prints the associated value for `effect` when the case is equal to `.pitch` and the associated value is greater than or equal to 0.5. 19 | //: 20 | 21 | //: [Next](@next) 22 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Extract with Switch.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Extract with Switch 3 | //: The following exercises will use `AudioEffect`. 4 | //: 5 | enum AudioEffect { 6 | case rate(value: Double) 7 | case pitch(value: Double) 8 | case echo 9 | case reverb 10 | } 11 | 12 | let effect = AudioEffect.pitch(value: 0.5) 13 | //: - Callout(Exercise): 14 | //: Write a switch statement using the `effect` constant that extracts all possible associated values as constants. Print any extracted associated values. 15 | //: 16 | 17 | //: - Callout(Exercise): 18 | //: Write a switch statement using the `effect` constant that ignores associated values. 19 | //: 20 | 21 | //: - Callout(Exercise): 22 | //: Write a switch statement using the `effect` constant that extracts the associated value for `.rate` or `.pitch` into a variable. Then, divide the variable by half and print the resulting value. All other cases can be ignored using the default case. 23 | //: 24 | 25 | //: - Callout(Exercise): 26 | //: Write a switch statement using the `effect` constant that prints the associated value for `.pitch` only when it is greater than 0.4. Use the `where` keyword to complete this exercise (i.e. don't use an if statement). All other cases can be ignored using the default case. 27 | //: 28 | 29 | //: [Next](@next) 30 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Associated Values: Exercises 2 | //: The following pages contain exercises for associated values. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/Pages/Raw Values.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Raw Values 3 | //: - Callout(Exercise): 4 | //: What's the raw value for `SecretLetters.g`? 5 | //: 6 | enum SecretLetters: Int { 7 | case a, b = 6, c, d, e, f = 2, g 8 | } 9 | //: - Callout(Exercise): 10 | //: Define an enum called `Rotation` with cases for `quarter`, `half`, `threeQuarter`, and `full` rotations. Each case should specify a raw value that represents the number of degrees for the rotation. For example, an eighth (1/8 * 360) turn would be 45 degrees. 11 | //: 12 | 13 | //: [Next](@next) 14 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AssociatedValues/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Associated Values.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Associated Values 3 | //: - Callout(Exercise): 4 | //: Create an array of `LunchFruit`. The array should contain seedless grapes, 4 clementines, and a whole (not sliced) apple. 5 | //: 6 | enum LunchFruit { 7 | case grapes(seedless: Bool) 8 | case clementines(count: Int) 9 | case apple(sliced: Bool) 10 | } 11 | 12 | let lunchOrder: [LunchFruit] = [.grapes(seedless: true), .clementines(count: 4), .apple(sliced: false)] 13 | //: - Callout(Exercise): 14 | //: Define an enum called `Prize` with cases representing a coffee mug, business cards, or lanyard. For business cards, the prize includes associated values for a name (`String`) and image (`UIImage`). For the lanyard, the prize includes an associated value for color (`UIColor`). 15 | //: 16 | import UIKit 17 | 18 | enum Prize { 19 | case coffeeMug 20 | case businessCards(name: String, image: UIImage) 21 | case lanyard(color: UIColor) 22 | } 23 | //: [Next](@next) 24 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Enums within Enums.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Enums within Enums 3 | //: - Callout(Exercise): 4 | //: Define an enum called `SConfig` representing the different configurations for the 2017 Tesla Model S vehicle. Use a raw type (Double) to represent its starting price in USD. The following image contains the possible configurations: 5 | //: 6 | //: ![model-s](/modelS.png) 7 | //: 8 | enum SConfig: Double { 9 | case sixty = 68000, sixtyD = 73000 10 | case seventyFive = 69500, seventyFiveD = 74500 11 | case ninetyD = 87500 12 | case oneHundredD = 94000, pOneHundredD = 135000 13 | } 14 | //: - Callout(Exercise): 15 | //: Define an enum called `XConfig` representing the different configurations for the 2017 Tesla Model X vehicle. Use a raw type (Double) to represent its starting price in USD. The following image contains the possible configurations: 16 | //: 17 | //: ![model-s](/modelX.png) 18 | //: 19 | enum XConfig: Double { 20 | case seventyFiveD = 79500 21 | case ninetyD = 93500 22 | case oneHundredD = 96000, pOneHundredD = 140000 23 | } 24 | //: - Callout(Exercise): 25 | //: Define an enum called `ThreeType` representing the different types for the 2017 Tesla 3 vehicle. Use a raw type (Double) to represent its starting price in USD. The following image contains the possible types: 26 | //: 27 | //: ![model-s](/model3.png) 28 | //: 29 | enum ThreeType: Double { 30 | case standard = 35000, longRange = 44000 31 | } 32 | //: - Callout(Exercise): 33 | //: Define an enum called `Tesla2017` representing Tesla's cars for 2017 — the Model S, Model X, and Model 3. Each case (car) should have an associated value for the different configuration or type for that model. Create a constant called `newCar` that is a Standard Tesla 2017 Model 3. 34 | //: 35 | enum Tesla2017 { 36 | case modelS(config: SConfig) 37 | case modelX(config: XConfig) 38 | case model3(type: ThreeType) 39 | } 40 | 41 | let newCar = Tesla2017.model3(type: .standard) 42 | //: - Callout(Exercise): 43 | //: Use a switch statement to extract and print the starting the value for `newCar`. The switch statement should be able to handle any type of Tesla 2017 model. 44 | //: 45 | switch newCar { 46 | case .modelS(let config): 47 | print(config.rawValue) 48 | case .modelX(let config): 49 | print(config.rawValue) 50 | case .model3(let type): 51 | print(type.rawValue) 52 | } 53 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/model3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/AssociatedValues/ExercisesSolutions.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/model3.png -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/AssociatedValues/ExercisesSolutions.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelS.png -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/AssociatedValues/ExercisesSolutions.playground/Pages/Enums within Enums.xcplaygroundpage/Resources/modelX.png -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Extract with If.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Extract with If 3 | //: The following exercises will use `AudioEffect`. 4 | //: 5 | enum AudioEffect { 6 | case rate(value: Double) 7 | case pitch(value: Double) 8 | case echo 9 | case reverb 10 | } 11 | 12 | let effect = AudioEffect.pitch(value: 0.5) 13 | //: - Callout(Exercise): 14 | //: Write an if statement that extracts and prints the associated value for `effect` when the case is equal to `.pitch`. 15 | //: 16 | if case let .pitch(value) = effect { 17 | print("\(value)") 18 | } 19 | //: - Callout(Exercise): 20 | //: Write an if statement that extracts and prints the associated value for `effect` when the case is equal to `.pitch` and the associated value is greater than or equal to 0.5. 21 | //: 22 | if case let .pitch(value) = effect, value >= 0.5 { 23 | print("\(value)") 24 | } 25 | //: [Next](@next) 26 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Extract with Switch.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Extract with Switch 3 | //: The following exercises will use `AudioEffect`. 4 | //: 5 | enum AudioEffect { 6 | case rate(value: Double) 7 | case pitch(value: Double) 8 | case echo 9 | case reverb 10 | } 11 | 12 | let effect = AudioEffect.pitch(value: 0.5) 13 | //: - Callout(Exercise): 14 | //: Write a switch statement using the `effect` constant that extracts all possible associated values as constants. Print any extracted associated values. 15 | //: 16 | switch effect { 17 | case let .rate(value): 18 | print("play audio with rate of: \(value)") 19 | case let .pitch(value): 20 | print("play audio with pitch of: \(value)") 21 | case .echo: 22 | print("play audio with echo effect") 23 | case .reverb: 24 | print("play audio with reverb effect") 25 | } 26 | //: - Callout(Exercise): 27 | //: Write a switch statement using the `effect` constant that ignores associated values. 28 | //: 29 | switch effect { 30 | case .rate: 31 | print("rate effect") 32 | case .pitch: 33 | print("pitch effect") 34 | case .echo: 35 | print("echo effect") 36 | case .reverb: 37 | print("reverb effect") 38 | } 39 | //: - Callout(Exercise): 40 | //: Write a switch statement using the `effect` constant that extracts the associated value for `.rate` or `.pitch` into a variable. Then, divide the variable by half and print the resulting value. All other cases can be ignored using the default case. 41 | //: 42 | switch effect { 43 | case .rate(var value), .pitch(var value): 44 | value *= 0.5 45 | print("\(value)") 46 | default: 47 | break 48 | } 49 | //: - Callout(Exercise): 50 | //: Write a switch statement using the `effect` constant that prints the associated value for `.pitch` only when it is greater than 0.4. Use the `where` keyword to complete this exercise (i.e. don't use an if statement). All other cases can be ignored using the default case. 51 | //: 52 | switch effect { 53 | case let .pitch(value) where value > 0.4: 54 | print("\(value)") 55 | default: 56 | break 57 | } 58 | //: [Next](@next) 59 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Associated Values: Exercises Solutions 2 | //: The following pages contain solutions for the associated values exercises. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/Pages/Raw Values.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Raw Values 3 | //: - Callout(Exercise): 4 | //: What's the raw value for `SecretLetters.g`? 5 | //: 6 | enum SecretLetters: Int { 7 | case a, b = 6, c, d, e, f = 2, g 8 | } 9 | 10 | print(SecretLetters.g.rawValue) 11 | //: - Callout(Exercise): 12 | //: Define an enum called `Rotation` with cases for `quarter`, `half`, `threeQuarter`, and `full` rotations. Each case should specify a raw value that represents the number of degrees for the rotation. For example, an eighth (1/8 * 360) turn would be 45 degrees. 13 | //: 14 | enum Rotation: Int { 15 | case quarter = 90 16 | case half = 180 17 | case threeQuarter = 270 18 | case full = 360 19 | } 20 | //: [Next](@next) 21 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AssociatedValues/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @batmanimal 2 | 3 | * @udacity/active-public-content -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ClassesPropertiesMethods.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Classes, Properties, and Methods 2 | 3 | import UIKit 4 | 5 | class Movie { 6 | let title: String 7 | let director: String 8 | let releaseYear: Int 9 | 10 | init(title: String, director: String, releaseYear: Int) { 11 | self.title = title 12 | self.director = director 13 | self.releaseYear = releaseYear 14 | } 15 | } 16 | 17 | class MovieArchive { 18 | var movies:[Movie] 19 | 20 | func filterByYear(_ year:Int) -> [Movie] { 21 | var filteredArray = [Movie]() 22 | for movie in self.movies { 23 | if movie.releaseYear == year { 24 | filteredArray.append(movie) 25 | } 26 | } 27 | return filteredArray 28 | } 29 | 30 | init(movies:[Movie]) { 31 | self.movies = movies 32 | } 33 | } 34 | //: ### Stored properties & Initialization 35 | // Scroll up to see the Movie class! 36 | 37 | var thursdayNightMovie = Movie(title:"Point Break", director:"Kathryn Bigelow", releaseYear: 1991) 38 | 39 | //: ### Type properties & Computed Properties 40 | 41 | class KidsMovie { 42 | let title: String 43 | let director: String 44 | let releaseYear: Int 45 | var mpaaRating: String 46 | static let permittedRatings = ["G", "PG"] 47 | let reviewScores:[Double] 48 | 49 | var metaScore: Double { 50 | get { 51 | let value = reviewScores.reduce(0) { $0 + $1 } / Double(reviewScores.count) 52 | return value 53 | } 54 | } 55 | 56 | init(title: String, director: String, releaseYear: Int, mpaaRating:String, reviewScores: [Double]) { 57 | self.mpaaRating = mpaaRating 58 | self.title = title 59 | self.director = director 60 | self.releaseYear = releaseYear 61 | self.reviewScores = reviewScores 62 | } 63 | } 64 | 65 | var fridayNightMovie = KidsMovie(title:"Princess Bride", director:"Rob Reiner", releaseYear: 1987, mpaaRating:"PG", reviewScores:[9, 9.5, 10, 9.5]) 66 | 67 | //: ### Calling Instance Methods 68 | // Make an array filled with Rob Reiner movies 69 | var princessBride = Movie(title: "The Princess Bride", director: "Rob Reiner", releaseYear: 1987) 70 | var spinalTap = Movie(title: "This is Spinal Tap", director: "Rob Reiner", releaseYear: 1984) 71 | var standByMe = Movie(title: "Stand By Me", director: "Rob Reiner", releaseYear:1986) 72 | var robReinerMovies = [princessBride, spinalTap, standByMe] 73 | 74 | // Initialize an instance of the class, MovieArchive 75 | var myArchive = MovieArchive(movies: robReinerMovies) 76 | 77 | var movie = myArchive.filterByYear(1986) 78 | var firstMovie = movie[0] 79 | print("\(firstMovie.title)") 80 | 81 | //: ### Calling Type methods 82 | UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ClassesPropertiesMethods.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Classes_Properties_Methods.playground. 3 | // 4 | 5 | 6 | import UIKit 7 | 8 | class Movie { 9 | let title: String 10 | let director: String 11 | let releaseYear: Int 12 | 13 | init(title: String, director:String, releaseYear: Int) { 14 | self.title = title 15 | self.director = director 16 | self.releaseYear = releaseYear 17 | } 18 | } 19 | 20 | class MovieArchive { 21 | var movies:[Movie] 22 | 23 | func filterByYear(_ year:Int, movies: [Movie]) -> [Movie] { 24 | var filteredArray = [Movie]() 25 | for movie in movies { 26 | if movie.releaseYear == year { 27 | filteredArray.append(movie) 28 | } 29 | } 30 | return filteredArray 31 | } 32 | 33 | init(movies:[Movie]) { 34 | self.movies = movies 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ClassesPropertiesMethods.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ClassesPropertiesMethods.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ClassesPropertiesMethods.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson6_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ExercisesSolutions.playground/Resources/fluffyDog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ClassesPropertiesMethods/ExercisesSolutions.playground/Resources/fluffyDog.jpg -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ExercisesSolutions.playground/Resources/fluffyDog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ClassesPropertiesMethods/ExercisesSolutions.playground/Resources/fluffyDog.png -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson6_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ClassesPropertiesMethods/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Closures/Closures.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Closures 2 | 3 | //: ### Closures include: 4 | //: __global functions, nested functions, and closure expressions__ 5 | 6 | //: ### What is a closure expression? 7 | //: closure expression - __an unnamed, self contained block of code that can be passed as an argument to a function__ 8 | 9 | //: ### What are closure expressions used for? 10 | //: Closure expressions are used to __specify an action to be executed some time in the future.__ 11 | 12 | //: ## Sorted 13 | 14 | var bids = [48.1, 75.4, 63.7, 52.4, 68.2] 15 | var orderedBids = bids.sorted(by: { (bid1: Double, bid2:Double) -> Bool in 16 | return bid2 > bid1 17 | }) 18 | print(orderedBids) 19 | 20 | //: Closures typically take the form: 21 | //: 22 | //: { (parameters) -> return type **in** 23 | //: 24 | //: statements to execute 25 | //: 26 | //:} 27 | 28 | var birthYears = [2004, 2011, 2007, 2005, 2002] 29 | var youngestToOldest = birthYears.sorted(by: { (year1: Int, year2: Int) -> Bool in 30 | return year1 > year2 31 | }) 32 | 33 | youngestToOldest 34 | 35 | //: ### Quiz: Choose the correct type for this closure 36 | var soup = ["tomato", "hot and sour", "french onion", "vegetable"] 37 | var alphabeticalSoup = soup.sorted(by: { (soup1: String, soup2: String) -> Bool in 38 | return soup2 > soup1 39 | }) 40 | 41 | alphabeticalSoup 42 | //: ### Tricks to make your closures more concise: filter 43 | var examGrades = [81, 99, 54, 84, 98] 44 | var passingGrades = examGrades.filter({(grade: Int) -> Bool in 45 | return grade > 70 46 | }) 47 | passingGrades 48 | 49 | //: Inferring closure expression type 50 | var grades = [81, 99, 54, 84, 98] 51 | var failingGrades = examGrades.filter({grade in 52 | return grade < 70 53 | }) 54 | 55 | failingGrades 56 | 57 | //: Implicit returns 58 | var moreGrades = [81, 99, 54, 84, 98] 59 | var morePassingGrades = examGrades.filter({grade in 60 | grade > 70 61 | }) 62 | morePassingGrades 63 | 64 | //: Shorthand argument names: $0, $1, $2 ... 65 | // Example 1 66 | var myGrades = [81, 99, 54, 84, 98] 67 | var myFailingGrades = examGrades.filter({ 68 | $0 < 70 69 | }) 70 | myFailingGrades 71 | 72 | // Example 2 73 | var soups = ["tomato", "hot and sour", "french onion", "vegetable"] 74 | var alphabeticalSoups = soups.sorted(by: {(soup1: String, soup2: String) -> Bool in 75 | return soup2 > soup1 76 | }) 77 | 78 | 79 | alphabeticalSoups 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Closures/Closures.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson9_Closures_TakeTwo.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Closures/Closures.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Closures/Closures.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Closures/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson9_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Closures/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Closures/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Closures/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson9_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Closures/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Closures/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Collections/Collections.playground/Resources/flatware-set.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Collections/Collections.playground/Resources/flatware-set.JPG -------------------------------------------------------------------------------- /Collections/Collections.playground/Resources/flatware-set_200x200.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Collections/Collections.playground/Resources/flatware-set_200x200.JPG -------------------------------------------------------------------------------- /Collections/Collections.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Collections.playground. 3 | // 4 | 5 | public class LightSwitch { 6 | 7 | public var on: Bool = true 8 | } 9 | 10 | public var livingRoomSwitch = LightSwitch() 11 | public var kitchenSwitch = LightSwitch() 12 | public var bathroomSwitch = LightSwitch() -------------------------------------------------------------------------------- /Collections/Collections.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Collections/Collections.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Collections/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson3_Exercises.playground. 3 | // 4 | 5 | public class CuddlyCreature { 6 | public var softFur = true 7 | } -------------------------------------------------------------------------------- /Collections/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Collections/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Collections/Exercises.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Collections/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson3_Exercises_withSolutions.playground. 3 | // 4 | 5 | public class CuddlyCreature { 6 | public var softFur = true 7 | } -------------------------------------------------------------------------------- /Collections/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Collections/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Collections/ExercisesSolutions.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ControlFlow/ControlFlow.playground/Resources/goat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ControlFlow/ControlFlow.playground/Resources/goat.jpg -------------------------------------------------------------------------------- /ControlFlow/ControlFlow.playground/Resources/monkey.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ControlFlow/ControlFlow.playground/Resources/monkey.jpg -------------------------------------------------------------------------------- /ControlFlow/ControlFlow.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson4_ControlFlow.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ControlFlow/ControlFlow.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ControlFlow/ControlFlow.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ControlFlow/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson4_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ControlFlow/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ControlFlow/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ControlFlow/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson4_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ControlFlow/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ControlFlow/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EnumsStructs/EnumsStructs.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Enums_Structs_Classes.playground. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /EnumsStructs/EnumsStructs.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /EnumsStructs/EnumsStructs.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EnumsStructs/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson7_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /EnumsStructs/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /EnumsStructs/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EnumsStructs/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson7_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /EnumsStructs/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /EnumsStructs/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Cleanup with Defer.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Cleanup with Defer 3 | //: The `defer` keyword is often coupled with error handling because it can be used to execute a block of code before an error-generating scope is exited. 4 | //: 5 | import Foundation 6 | 7 | enum PurchaseError: Error { 8 | case invalidAddress 9 | case cardRejected 10 | case cartWeightLimitExceeded(Double) 11 | case insufficientStock(String) 12 | } 13 | 14 | func processOrder() throws { 15 | throw PurchaseError.cardRejected 16 | } 17 | 18 | func attemptPurchase() { 19 | // before this function exits, execute this defer block 20 | defer { 21 | print("close the secure purchase session") 22 | } 23 | 24 | do { 25 | try processOrder() 26 | } catch { 27 | print(error) 28 | } 29 | } 30 | 31 | attemptPurchase() 32 | //: - Callout(Watch Out!): 33 | //: A defer block cannot contain code that changes the flow of control, like a break or return statement, or throwing an error. 34 | func attemptPurchaseBadDefer() { 35 | // before this function exits, execute this defer block 36 | defer { 37 | print("close the secure purchase session") 38 | // uncomment this break to see Xcode complain about flow of control 39 | //break 40 | } 41 | 42 | do { 43 | try processOrder() 44 | } catch { 45 | print(error) 46 | } 47 | } 48 | //: Multiple defer blocks may be defined, but are executed in reverse order of when they appear. 49 | func attemptPurchaseWithMultipleDefers() { 50 | // before this function exits, execute this defer block 51 | defer { print("then, close the secure purchase session") } 52 | defer { print("first, clear order") } 53 | 54 | do { 55 | try processOrder() 56 | } catch { 57 | print(error) 58 | } 59 | } 60 | 61 | attemptPurchaseWithMultipleDefers() 62 | -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Create Custom Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Create Custom Errors 3 | //: To create a custom error, define a type that inherits from the `Error` protocol. Often, enums are used for this purpose. 4 | //: 5 | enum SimplePurchaseError: Error { 6 | case invalidAddress 7 | case cardRejected 8 | case cartWeightLimitExceeded 9 | case insufficientStock 10 | } 11 | 12 | func makeBadPurchase() throws { 13 | throw SimplePurchaseError.cardRejected // throw a custom error 14 | } 15 | 16 | do { 17 | try makeBadPurchase() 18 | } catch { 19 | print(error) 20 | } 21 | //: When using an enum to define a custom error, use associated values to add helpful debugging information. 22 | //: 23 | enum ComplexPurchaseError: Error { 24 | case invalidAddress 25 | case cardRejected 26 | case cartWeightLimitExceeded(Double) 27 | case insufficientStock(String) 28 | } 29 | 30 | func attemptPurchase(withWeight weight: Double) throws { 31 | if weight > 100 { 32 | // throw a custom error with an associated value 33 | throw ComplexPurchaseError.cartWeightLimitExceeded(-1 * (100 - weight)) 34 | } else { 35 | print("purchase succeeded!") 36 | } 37 | } 38 | 39 | do { 40 | try attemptPurchase(withWeight: 125.6) 41 | } catch let error as ComplexPurchaseError { 42 | switch error { 43 | case let .cartWeightLimitExceeded(weight): /* extract the associated value */ 44 | print("purchase failed. weight exceeds limit by: \(weight)") 45 | default: 46 | print(error) 47 | break 48 | } 49 | } catch { 50 | print(error) 51 | } 52 | //: [Next](@next) 53 | -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Error Handling Summary.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Error Handling Summary 3 | //: Below, options for handling errors are summarized. 4 | //: 5 | //: **1. Handle Error with `Do`-`Catch`** 6 | //: 7 | import Foundation 8 | 9 | func readFileIntoStringDoCatch(fileName: String, fileExtension: String) { 10 | if let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension) { 11 | do { 12 | let content = try String(contentsOf: fileURL, encoding: .utf8) 13 | print(content) 14 | } catch { 15 | print("error handled immediately!") 16 | } 17 | } 18 | } 19 | 20 | readFileIntoStringDoCatch(fileName: "swift", fileExtension: "png") 21 | //: **2. Convert Error to Optional with `try?`** 22 | //: 23 | func readFileIntoStringOptional(fileName: String, fileExtension: String) { 24 | if let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension) { 25 | if let content = try? String(contentsOf: fileURL, encoding: .utf8) { 26 | print(content) 27 | } else { 28 | print("could not read contents of file into string") 29 | } 30 | } 31 | } 32 | 33 | readFileIntoStringDoCatch(fileName: "swift", fileExtension: "png") 34 | //: **3. Ignore Error with `try!`** 35 | //: 36 | func readFileIntoStringOrCrash(fileName: String, fileExtension: String) { 37 | if let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension) { 38 | let content = try! String(contentsOf: fileURL, encoding: .utf8) 39 | print(content) 40 | } 41 | } 42 | 43 | readFileIntoStringOrCrash(fileName: "swift", fileExtension: "txt") 44 | //: **4. Propagate the Error** 45 | //: 46 | func readFileIntoStringOrPropagate(fileName: String, fileExtension: String) throws { 47 | if let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension) { 48 | let content = try String(contentsOf: fileURL, encoding: .utf8) 49 | print(content) 50 | } 51 | } 52 | 53 | do { 54 | try readFileIntoStringOrPropagate(fileName: "swift", fileExtension: "png") 55 | } catch { 56 | print("the error was propagated to me, and I handled it!") 57 | } 58 | //: [Next](@next) 59 | -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Errors.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Errors.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Errors 2 | //: Errors, or error handling, gives developers the ability to safely execute error-prone code. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Errors.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/The Many Faces of Try.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### The Many Faces of Try 3 | //: The `try` keyword is used to execute error-prone code. If an error is generated while using the `try` keyword, it must be handled immediately or propagated. 4 | //: 5 | import Foundation 6 | 7 | func printFileContents() { 8 | if let fileURL = Bundle.main.url(forResource: "swift", withExtension: "txt") { 9 | do { 10 | let content = try String(contentsOf: fileURL, encoding: .utf8) 11 | print(content) 12 | } catch { 13 | print("\(error)") 14 | } 15 | } 16 | } 17 | 18 | printFileContents() 19 | //: Try comes in two other forms: `try?` and `try!`. `try?` executes error-prone code, and if any error is generated, then it is converted into an optional where the underlying value has the same type as the error-prone function or intializer's return type. This can simplify code, but the ability to analyze errors is lost. 20 | //: 21 | func printFileContentsTry() { 22 | if let fileURL = Bundle.main.url(forResource: "swift", withExtension: "png") { 23 | let content = try? String(contentsOf: fileURL, encoding: .utf8) 24 | print(content ?? "content is nil") 25 | 26 | // preferably, combine `if let` with `try?`; it's easier to read 27 | if let content = try? String(contentsOf: fileURL, encoding: .utf8) { 28 | print(content) 29 | } else { 30 | print("could not read contents of file into string") 31 | } 32 | } 33 | } 34 | 35 | printFileContentsTry() 36 | //: - Callout(Watch Out!): 37 | //: If `try?` is used to set an optional value, but the function that throws but doesn't return a type (returns `Void`), then Xcode will generate a warning. 38 | //: 39 | func readFileIntoString(fileName: String, fileExtension: String) throws { 40 | if let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileExtension) { 41 | let content = try String(contentsOf: fileURL, encoding: .utf8) 42 | print(content) 43 | } 44 | } 45 | 46 | // uncomment the following line to see Xcode generate a warning 47 | // let unknownType = try? readFileIntoString(fileName: "swift", fileExtension: "png") 48 | //: `try!` executes error-prone code while foregoing any opportunity to safely handle an error. If an error-prone function is called using `try!` and it fails, then the entire app or playground crashes. 49 | //: 50 | // try! should only be used if there is no risk of error; generally, this is not advised 51 | if let fileURL = Bundle.main.url(forResource: "swift", withExtension: "txt") { 52 | let content = try! String(contentsOf: fileURL, encoding: .utf8) 53 | print(content) 54 | } 55 | 56 | // when try! is used and an error occurs, the executable (here, a playground) crashes 57 | if let fileURL = Bundle.main.url(forResource: "swift", withExtension: "png") { 58 | print("try! reading \(fileURL.lastPathComponent) at your own risk") 59 | // uncommenting the following lines will crash the playground 60 | /* 61 | let content = try! String(contentsOf: fileURL, encoding: .utf8) 62 | print(content) 63 | */ 64 | } 65 | //: [Next](@next) 66 | -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Errors.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Errors.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Errors.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Errors/Errors.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Cleanup with Defer.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Cleanup with Defer 3 | //: The following exercises will use the `GrammarError` enum and the `analyzeSentenceGrammar` and `checkSentence` functions. 4 | //: 5 | import Foundation 6 | 7 | enum GrammarError: Error { 8 | case passiveVoice(String) 9 | case improperTense(String) 10 | } 11 | 12 | func analyzeSentenceGrammar() throws { 13 | throw GrammarError.passiveVoice("The test was taken by the student.") 14 | } 15 | 16 | func checkSentence() { 17 | defer { print("play editing sound") } 18 | defer { print("reformat sentence for display") } 19 | defer { print("highlight any problems") } 20 | 21 | do { 22 | try analyzeSentenceGrammar() 23 | } catch { 24 | print(error) 25 | } 26 | } 27 | 28 | //: - Callout(Exercise): 29 | //: In what order are the print statements in `checkSentence` executed? 30 | //: 31 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Create Custom Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Create Custom Errors 3 | //: - Callout(Exercise): 4 | //: Define a enum called `GrammarError` that implements the `Error` protocol and has two cases `passiveVoice` and `improperTense`. Each case should have an associated `String` value. 5 | //: 6 | 7 | //: - Callout(Exercise): 8 | //: Define a function called `throwGrammarError` that immediately throws the error `GrammarError.passiveVoice`. (Optional) For the error's associated value, pass a string that contains an example of passive voice. 9 | //: 10 | 11 | //: [Next](@next) 12 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Describe Custom Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Describe Custom Errors 3 | //: The following exercises will use the `GrammarError` enum and `throwGrammarError` function. 4 | //: 5 | import Foundation 6 | 7 | enum GrammarError: Error { 8 | case passiveVoice(String) 9 | case improperTense(String) 10 | } 11 | 12 | func throwGrammarError() throws { 13 | throw GrammarError.passiveVoice("The test was taken by the student.") 14 | } 15 | 16 | //: - Callout(Exercise): 17 | //: Extend `GrammarError` such that it implements the `LocalizedError` protocol. (Optional) Provide creative values for all `LocalizedError` properties. 18 | //: 19 | 20 | //: - Callout(Exercise): 21 | //: Extend `GrammarError` such that it implements the `CustomNSError` protocol. (Optional) Provide creative values for all `CustomNSError` properties. 22 | //: 23 | 24 | //: - Callout(Exercise): 25 | //: Call `throwGrammarError` casting any thrown error into an `NSError`. Then, print the error's localized description and the values of all its `NSError` properties. 26 | //: 27 | 28 | //: [Next](@next) 29 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Error Handling Summary.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Error Handling Summary 3 | //: There are no exercises for this section, please click **Next** to continue. 4 | 5 | //: [Next](@next) 6 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Exercises.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Handle Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Handle Errors 3 | //: - Callout(Exercise): 4 | //: Modify the error handling for `whatsThatError` so it catches the specific error being thrown when the `url` is set to the main bundle URL. 5 | //: 6 | import Foundation 7 | 8 | func whatsThatError(url: URL) { 9 | do { 10 | let content = try String(contentsOf: url, encoding: .utf8) 11 | print(content) 12 | } catch { 13 | print(error) 14 | } 15 | } 16 | 17 | whatsThatError(url: Bundle.main.bundleURL) 18 | //: [Next](@next) 19 | 20 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Exercises.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Errors: Exercises 2 | //: The following pages contain exercises for errors. 3 | //: 4 | //: [Next](@next) 5 | 6 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Propagate Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Propagate Errors 3 | //: - Callout(Exercise): 4 | //: Modify `readFileContents` so that it propagates any errors thrown by the String initializer. 5 | //: 6 | import Foundation 7 | 8 | func readFileContents(url: URL) { 9 | do { 10 | let content = try String(contentsOf: url, encoding: .utf8) 11 | print(content) 12 | } catch { 13 | print(error) 14 | } 15 | } 16 | 17 | readFileContents(url: Bundle.main.bundleURL) 18 | 19 | //: [Next](@next) 20 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Exercises.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/The Many Faces of Try.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### The Many Faces of Try 3 | //: There are no exercises for this section, please click **Next** to continue. 4 | 5 | //: [Next](@next) 6 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/Exercises.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/Exercises.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Errors/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Cleanup with Defer.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Cleanup with Defer 3 | //: The following exercises will use the `GrammarError` enum and the `analyzeSentenceGrammar` and `checkSentence` functions. 4 | //: 5 | import Foundation 6 | 7 | enum GrammarError: Error { 8 | case passiveVoice(String) 9 | case improperTense(String) 10 | } 11 | 12 | func analyzeSentenceGrammar() throws { 13 | throw GrammarError.passiveVoice("The test was taken by the student.") 14 | } 15 | 16 | func checkSentence() { 17 | defer { print("play editing sound") } 18 | defer { print("reformat sentence for display") } 19 | defer { print("highlight any problems") } 20 | 21 | do { 22 | try analyzeSentenceGrammar() 23 | } catch { 24 | print(error) 25 | } 26 | } 27 | 28 | //: - Callout(Exercise): 29 | //: In what order are the print statements in `checkSentence` executed? 30 | //: 31 | checkSentence() 32 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Create Custom Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Create Custom Errors 3 | //: - Callout(Exercise): 4 | //: Define a enum called `GrammarError` that implements the `Error` protocol and has two cases `passiveVoice` and `improperTense`. Each case should have an associated `String` value. 5 | //: 6 | enum GrammarError: Error { 7 | case passiveVoice(String) 8 | case improperTense(String) 9 | } 10 | 11 | //: - Callout(Exercise): 12 | //: Define a function called `throwGrammarError` that immediately throws the error `GrammarError.passiveVoice`. (Optional) For the error's associated value, pass a string that contains an example of passive voice. 13 | //: 14 | func throwGrammarError() throws { 15 | throw GrammarError.passiveVoice("The test was taken by the student.") 16 | } 17 | 18 | do { 19 | try throwGrammarError() 20 | } catch { 21 | print(error) 22 | } 23 | 24 | //: [Next](@next) 25 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Error Handling Summary.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Error Handling Summary 3 | //: There are no exercises for this section, please click **Next** to continue. 4 | 5 | //: [Next](@next) 6 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/ExercisesSolutions.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Error Handling Summary.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Handle Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Handle Errors 3 | //: - Callout(Exercise): 4 | //: Modify the error handling for `whatsThatError` so it catches the specific error being thrown when the `url` is set to the main bundle URL. 5 | //: 6 | import Foundation 7 | 8 | func whatsThatError(url: URL) { 9 | do { 10 | let content = try String(contentsOf: url, encoding: .utf8) 11 | print(content) 12 | } catch CocoaError.fileReadNoPermission { 13 | print("found the error! fileReadNoPermission!") 14 | } catch { 15 | print(error) 16 | } 17 | } 18 | 19 | whatsThatError(url: Bundle.main.bundleURL) 20 | //: [Next](@next) 21 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/ExercisesSolutions.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Handle Errors.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Errors: Exercises Solutions 2 | //: The following pages contain solutions for the errors exercises. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Propagate Errors.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Propagate Errors 3 | //: - Callout(Exercise): 4 | //: Modify `readFileContents` so that it propagates any errors thrown by the String initializer. 5 | //: 6 | import Foundation 7 | 8 | func readFileContents(url: URL) throws { 9 | let content = try String(contentsOf: url, encoding: .utf8) 10 | print(content) 11 | } 12 | 13 | do { 14 | try readFileContents(url: Bundle.main.bundleURL) 15 | } catch { 16 | print(error) 17 | } 18 | 19 | //: [Next](@next) 20 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/ExercisesSolutions.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/Propagate Errors.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/The Many Faces of Try.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### The Many Faces of Try 3 | //: There are no exercises for this section, please click **Next** to continue. 4 | 5 | //: [Next](@next) 6 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Errors/ExercisesSolutions.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.png -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/Pages/The Many Faces of Try.xcplaygroundpage/Resources/swift.txt: -------------------------------------------------------------------------------- 1 | We love Swift! -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Errors/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Functions/Exercises.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Lesson 5 Exercises - Defining and Calling Functions 2 | 3 | import UIKit 4 | 5 | //: __Problem 1.__ 6 | //: 7 | //:Earlier we used the method, removeAtIndex() to remove the first letter of a string. This method belongs to the String class. See if you can use this same method to return the last letter of a string. 8 | 9 | //:Test out your discovery below by returning the last letter of the String, "bologna". 10 | var word = "bologna" 11 | 12 | //: __Problem 2__ 13 | //: 14 | //: Write a function called combineLastCharacters. It should take in an array of strings, collect the last character of each string and combine those characters to make a new string to return. Use the strategy you discovered in Problem 1 along with a for-in loop to write combineLastCharacters. Then try it on the nonsenseArray below. 15 | var nonsenseArray = ["bungalow", "buffalo", "indigo", "although", "Ontario", "albino", "%$&#!"] 16 | 17 | //: __Problem 3__ 18 | //: 19 | //: Imagine you are writing an app that keeps track of what you spend during the week. Prices of items purchased are entered into a "price" textfield. The "price" field should only allow numbers, no letters. 20 | 21 | //: NSCharacterSet.decimalDigitCharacterSet() is used below to define a set that is only digits. Using that set, write a function that takes in a String and returns true if that string is numeric and false if it contains any characters that are not numbers. 22 | 23 | //: __3a.__ Write a signature for a function that takes in a String and returns a Bool 24 | 25 | //: __3b.__ Write a for-in loop that checks each character of a string to see if it is a member of the "digits" set. Use the .unicodeScalars property to access all the characters in a string. Hint: the method longCharacterIsMember may come in handy. 26 | 27 | let digits = CharacterSet.decimalDigits 28 | 29 | //: __Problem 4__ 30 | //: 31 | //: Write a function that takes in an array of dirtyWord strings, removes all of the four-letter words, and returns a clean array. 32 | let dirtyWordsArray = ["phooey", "darn", "drat", "blurgh", "jupiters", "argh", "fudge"] 33 | 34 | //: __Problem 5__ 35 | //: 36 | //: Write a method, filterByDirector, that belongs to the MovieArchive class. This method should take in a dictionary of movie titles and a string representing the name of a director and return an array of movies created by that director. You can use the movie dictionary below. To test your method, instantiate an instance of the MovieArchive class and call filterByDirector from that instance. 37 | 38 | var movies:Dictionary = [ "Boyhood":"Richard Linklater","Inception":"Christopher Nolan", "The Hurt Locker":"Kathryn Bigelow", "Selma":"Ava Du Vernay", "Interstellar":"Christopher Nolan"] 39 | 40 | class MovieArchive { 41 | 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Functions/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson5_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Functions/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Functions/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Functions/Exercises.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Functions/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson5_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Functions/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Functions/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Functions/Functions.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Functions 2 | 3 | //: ## Global Functions 4 | //: The functions __print__, __min__, __max__, and __abs__ are a few examples of global functions. Check out a complete list of Swift's global functions [here](http://swiftdoc.org/swift-2/func/). 5 | //print 6 | print("I'm a global function!") 7 | 8 | //min and max 9 | var initialPrice = 50 10 | var bestOffer = 45 11 | var finalPrice = min(bestOffer, initialPrice) 12 | 13 | //abs 14 | var negativeSeven = -7 15 | abs(negativeSeven) 16 | 17 | 18 | //: ## Methods 19 | 20 | //: ## Anatomy of a function 21 | 22 | let array = ["A", "13", "B","5","87", "t", "41"] 23 | 24 | class Arithmetic { 25 | func sumOfStrings(_ aBunchOfStrings: [String]) -> Int { 26 | let array = aBunchOfStrings 27 | var sum = 0 28 | for string in array { 29 | if Int(string) != nil { 30 | let intToAdd = Int(string)! 31 | sum += intToAdd 32 | } 33 | } 34 | return sum 35 | } 36 | } 37 | 38 | //: func functionName (parameterName: parameterType) -> returnType { 39 | //: statements to execute 40 | //: return object 41 | //: } 42 | 43 | let stringToReverse = "Mutable or Immutable? That is the question." 44 | 45 | func reverseString(_ stringToReverse: String) { 46 | var reversedString = "" 47 | for character in stringToReverse { 48 | reversedString = "\(character)" + reversedString 49 | } 50 | print(reversedString) 51 | } 52 | 53 | //: func functionName (externalParameterName localParameterName: parameterType) -> returnType { 54 | //: statements to execute 55 | //: return object 56 | //: } 57 | 58 | //: ## Practice writing function definitions 59 | //: Example 1 - firstCharacterOf 60 | // TODO: Write the firstCharacterOf function here. 61 | func firstCharacterOf(word: String)-> Character { 62 | return word[word.startIndex] 63 | } 64 | 65 | firstCharacterOf(word: "Mom") 66 | 67 | 68 | //: Example 2 - placeFirstLetterLast 69 | // TODO: Write placeFirstLetterLast function here. 70 | func placeFirstLetterLast(_ myString: String) -> String { 71 | var newString = myString 72 | newString.append(firstCharacterOf(word: myString)) 73 | newString.remove(at: myString.startIndex) 74 | return newString 75 | } 76 | 77 | placeFirstLetterLast("Mom") 78 | 79 | 80 | //: Example 3 - filterByYear 81 | 82 | class MovieArchive { 83 | } 84 | 85 | var aiThemedMovies = ["Metropolis":1927, "2001: A Space Odyssey":1968, "Blade Runner":1982, "War Games" : 1983, "Terminator": 1984, "The Matrix":1999, "A.I.":2001, "Her": 2013, "Ex Machina":2015] 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /Functions/Functions.playground/Resources/nestedDolls.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Functions/Functions.playground/Resources/nestedDolls.jpg -------------------------------------------------------------------------------- /Functions/Functions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson5_Functions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Functions/Functions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Functions/Functions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/Pages/A Generic Function.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### A Generic Function 3 | //: The following exercises will use the `printIfUIResponder` function. 4 | //: 5 | func printIfUIResponder(_ argument: Type) { 6 | print(type(of: argument)) 7 | } 8 | 9 | //: - Callout(Exercise): 10 | //: Which of the following invocations will cause a compiler error? Make an educated guess before removing the comment annotations! 11 | //: 12 | import UIKit 13 | 14 | /* 15 | printIfUIResponder(UIView()) 16 | printIfUIResponder(UIFont()) 17 | printIfUIResponder(UILabel()) 18 | */ 19 | 20 | //: [Next](@next) 21 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/Pages/A Generic Type.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### A Generic Type 3 | //: - Callout(Exercise): 4 | //: Define a generic type (a class) called `IntAnalyzer` that specifies a single generic type parameter that must implement the `BinaryInteger` protocol. The generic type parameter should be used to define a property called `value`. You must also define an initializer which sets the `value` property. 5 | //: 6 | 7 | //: - Callout(Exercise): 8 | //: Extend `IntAnalyzer` so that it includes a function called `analyze` which prints the value property, its bit width (`value.bitWidth`), and its sign (`value.signum()`). 9 | //: 10 | 11 | //: - Callout(Exercise): 12 | //: Create an instance of `IntAnalyzer`, then call the `analyze` function. 13 | //: 14 | 15 | //: [Next](@next) 16 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/Pages/Arrays are Generic.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Arrays are Generic 3 | //: - Callout(Exercise): 4 | //: Create an array of bools called `boolArray` that uses the longhand initialization syntax for its generic parameter. 5 | //: 6 | 7 | //: [Next](@next) 8 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Generics: Exercises 2 | //: The following pages contain exercises for generics. 3 | //: 4 | //: [Next](@next) 5 | 6 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/Pages/Multiple Generic Types.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Multiple Generic Types 3 | //: There are no exercises for this section. 4 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/Pages/Subclass a Generic Type.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Subclass a Generic Type 3 | //: The following exercises will use the `IntAnalyzer` struct. Notice the name of the property has changed from previous examples. It is now called `value1`. 4 | //: 5 | class IntAnalyzer { 6 | let value1: T 7 | 8 | init(value1: T) { 9 | self.value1 = value1 10 | } 11 | } 12 | 13 | //: - Callout(Exercise): 14 | //: Subclass `IntAnalyzer` to create a new struct called `IntsAnalyzer`. `IntsAnalyzer` will include a new property called `value2` which should use the generic type inherited from `IntAnalyzer`. 15 | //: 16 | 17 | //: - Callout(Exercise): 18 | //: Extend `IntsAnalyzer` so that it includes a function called `analyzeInts` which prints if `value1` and `value2` are equal, if they share the same sign, and if they have the same number of trailing zero bits (e.g. `value1.trailingZeroBitCount`). 19 | //: 20 | 21 | //: - Callout(Exercise): 22 | //: Create an instance of `IntsAnalyzer`, then call the `analyzeInts` function. 23 | //: 24 | 25 | //: [Next](@next) 26 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Generics/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/Pages/A Generic Function.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### A Generic Function 3 | //: The following exercises will use the `printIfUIResponder` function. 4 | //: 5 | func printIfUIResponder(_ argument: Type) { 6 | print(type(of: argument)) 7 | } 8 | 9 | //: - Callout(Exercise): 10 | //: Which of the following invocations will cause a compiler error? Make an educated guess before removing the comment annotations! 11 | //: 12 | import UIKit 13 | 14 | printIfUIResponder(UIView()) 15 | // printIfUIResponder(UIFont()) 16 | printIfUIResponder(UILabel()) 17 | 18 | //: [Next](@next) 19 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/Pages/A Generic Type.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### A Generic Type 3 | //: - Callout(Exercise): 4 | //: Define a generic type (a class) called `IntAnalyzer` that specifies a single generic type parameter that must implement the `BinaryInteger` protocol. The generic type parameter should be used to define a property called `value`. You must also define an initializer which sets the `value` property. 5 | //: 6 | class IntAnalyzer { 7 | let value: T 8 | 9 | init(value: T) { 10 | self.value = value 11 | } 12 | } 13 | 14 | //: - Callout(Exercise): 15 | //: Extend `IntAnalyzer` so that it includes a function called `analyze` which prints the value property, its bit width (`value.bitWidth`), and its sign (`value.signum()`). 16 | //: 17 | extension IntAnalyzer { 18 | func analyze() { 19 | print(value) 20 | print(value.bitWidth) 21 | print(value.signum()) 22 | } 23 | } 24 | 25 | //: - Callout(Exercise): 26 | //: Create an instance of `IntAnalyzer`, then call the `analyze` function. 27 | //: 28 | let analyzer = IntAnalyzer(value: 5) 29 | analyzer.analyze() 30 | 31 | //: [Next](@next) 32 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/Pages/Arrays are Generic.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Arrays are Generic 3 | //: - Callout(Exercise): 4 | //: Create an array of bools called `boolArray` that uses the longhand initialization syntax for its generic parameter. 5 | //: 6 | var boolArray = Array() 7 | boolArray.append(true) 8 | boolArray.append(false) 9 | boolArray.append(true) 10 | boolArray.append(true) 11 | print(boolArray) 12 | 13 | //: [Next](@next) 14 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Generics: Exercises Solutions 2 | //: The following pages contain solutions for the generics exercises. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/Pages/Multiple Generic Types.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Multiple Generic Types 3 | //: There are no exercises for this section. 4 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/Pages/Subclass a Generic Type.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Subclass a Generic Type 3 | //: The following exercises will use the `IntAnalyzer` struct. Notice the name of the property has changed from previous examples. It is now called `value1`. 4 | //: 5 | class IntAnalyzer { 6 | let value1: T 7 | 8 | init(value1: T) { 9 | self.value1 = value1 10 | } 11 | } 12 | 13 | //: - Callout(Exercise): 14 | //: Subclass `IntAnalyzer` to create a new struct called `IntsAnalyzer`. `IntsAnalyzer` will include a new property called `value2` which should use the generic type inherited from `IntAnalyzer`. 15 | //: 16 | class IntsAnalyzer: IntAnalyzer { 17 | let value2: T 18 | 19 | init(value1: T, value2: T) { 20 | self.value2 = value2 21 | super.init(value1: value1) 22 | } 23 | } 24 | 25 | //: - Callout(Exercise): 26 | //: Extend `IntsAnalyzer` so that it includes a function called `analyzeInts` which prints if `value1` and `value2` are equal, if they share the same sign, and if they have the same number of trailing zero bits (e.g. `value1.trailingZeroBitCount`). 27 | //: 28 | extension IntsAnalyzer { 29 | func analyzeInts() { 30 | print(value1 == value2) 31 | print(value1.signum() == value2.signum()) 32 | print(value1.trailingZeroBitCount == value2.trailingZeroBitCount) 33 | } 34 | } 35 | 36 | //: - Callout(Exercise): 37 | //: Create an instance of `IntsAnalyzer`, then call the `analyzeInts` function. 38 | //: 39 | let analyzer = IntsAnalyzer(value1: 3, value2: 5) 40 | analyzer.analyzeInts() 41 | 42 | //: [Next](@next) 43 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Generics/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Generics/Generics.playground/Pages/A Generic Function.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### A Generic Function 3 | //: Generics can be applied to functions and types. To write a generic function, specify a generic type after the function name using the bracket notation (ex. `func myFunction`). Then, for any arguments that should be generic, use the generic type instead of a concrete type. Below, the generic type is called `T`; `T` can represent any type. 4 | //: 5 | // argument is of type `T`, it can be anything 6 | func printType(_ argument: T) { 7 | print(type(of: argument)) 8 | } 9 | 10 | printType(4) 11 | printType("udacity") 12 | printType(4.5) 13 | printType(false) 14 | //: For readability, give a generic type a more descriptive name. 15 | //: 16 | func printTypeWithNamedGenericType(_ argument: Type) { 17 | print(type(of: argument)) 18 | } 19 | 20 | printTypeWithNamedGenericType(4) 21 | printTypeWithNamedGenericType("udacity") 22 | printTypeWithNamedGenericType(4.5) 23 | printTypeWithNamedGenericType(false) 24 | //: Without generics, a developer would have to duplicate code to handle differing types — even if the types are being used the same way! 25 | //: 26 | func printIntType(_ int: Int) { 27 | print(type(of: int)) 28 | } 29 | 30 | func printStringType(_ string: String) { 31 | print(type(of: string)) 32 | } 33 | 34 | printIntType(4) 35 | printStringType("udacity") 36 | //: A generic type can be bound or constrained such that it can only represent concrete types which adhere to some protocol or inherit from a certain class. In the example below, the generic type is constrained such that it can only represent types which implement the `UnsignedInteger` protocol — essentially, non-negative integers. 37 | //: 38 | func printUIntTypes(_ argument: Type) { 39 | print(type(of: argument)) 40 | } 41 | 42 | let unsignedInt: UInt = 4 43 | let unsignedInt8: UInt8 = 4 44 | let unsignedInt16: UInt16 = 4 45 | 46 | printUIntTypes(unsignedInt) 47 | printUIntTypes(unsignedInt8) 48 | printUIntTypes(unsignedInt16) 49 | //: - Callout(Watch Out!): 50 | //: When a generic type is constrained, any concrete types that do not adhere to the constraint will cause Xcode to complain. 51 | //: 52 | // uncomment the lines below to see Xcode complain that 4 (Int), -4 (Int), and "abc" (String) do not implement the `UnsignedInteger` protocol, and cannot be used in place of the generic type 53 | //printUIntTypes(4) /* `Int` is not unsigned because it can store negative values */ 54 | //printUIntTypes(-4) 55 | //printUIntTypes("abc") 56 | //: [Next](@next) 57 | -------------------------------------------------------------------------------- /Generics/Generics.playground/Pages/Arrays are Generic.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Arrays are Generic 3 | //: Upon first glance, many do not realize that Swift arrays use generics. Specifically, the type that a Swift array stores is generic — it can be anything. When declaring an array using its more longhand syntax, this becomes apparent. 4 | //: 5 | var intArray = Array() 6 | intArray.append(4) 7 | intArray.append(2) 8 | print(intArray) 9 | //: The type specified in the brackets (ex. "") is called a "concrete type". When specified, the concrete type takes the place of a generic type. 10 | //: 11 | var stringArray: Array = ["one", "two", "three"] 12 | print(stringArray) 13 | //: Because Swift arrays use generics, they behave the same, regardless of the concrete type. 14 | print(intArray.count) 15 | print(stringArray.count) 16 | 17 | intArray.append(6) 18 | stringArray.append("six") 19 | 20 | intArray.removeAll() 21 | stringArray.removeAll() 22 | 23 | print(intArray.count) 24 | print(stringArray.count) 25 | //: [Next](@next) 26 | -------------------------------------------------------------------------------- /Generics/Generics.playground/Pages/Arrays are Generic.xcplaygroundpage/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Generics/Generics.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Generics 2 | //: Generics gives developers the ability to specify functionality that can be applied to any type or specific types like those that implement a certain protocol. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /Generics/Generics.playground/Pages/Subclass a Generic Type.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Subclass a Generic Type 3 | //: A generic type can be subclassed, assuming it is a class and not a struct. To setup the following example, the `Animal`, `Whale`, and `ZooExhibit` types are defined. 4 | //: 5 | protocol Animal { 6 | var name: String { get } 7 | static var commonName: String { get } 8 | static var emoji: String { get } 9 | } 10 | 11 | struct Whale: Animal { 12 | let name: String 13 | static let commonName = "Whale" 14 | static let emoji = "🐳" 15 | } 16 | 17 | class ZooExhibit { 18 | let animals: [AnimalType] 19 | 20 | init(animals: [AnimalType]) { 21 | self.animals = animals 22 | } 23 | 24 | func tourTheExhibit() { 25 | print("Welcome to the \(AnimalType.commonName) Exhibit \(AnimalType.emoji)!") 26 | for animal in animals { 27 | print("Say hello to \(animal.name) \(AnimalType.emoji).") 28 | } 29 | } 30 | } 31 | //: To subclass the generic type `ZooExhibit`, one must define a new class with a generic type that can be substituted for `AnimalType` (any type that implements the `Animal` protocol). In the subclass below, the generic type `A` is constrained such that it must implement the `Animal` protocol. Hence, when `ZooExhibit` is specified as the superclass, the type `A` can be used without error. 32 | //: 33 | class TravelingExhibit: ZooExhibit { 34 | var location: String 35 | 36 | init(location: String, animals: [A]) { 37 | self.location = location 38 | super.init(animals: animals) 39 | } 40 | 41 | override func tourTheExhibit() { 42 | print("Welcome to the \(A.commonName) Exhibit \(A.emoji) at \(location)!") 43 | for animal in animals { 44 | print("Say hello to \(animal.name) \(A.emoji).") 45 | } 46 | } 47 | } 48 | 49 | let exhibit1 = TravelingExhibit(location: "Oakland Zoo", animals: [Whale(name: "Watson"), Whale(name: "Wren")]) 50 | exhibit1.tourTheExhibit() 51 | 52 | // change exhibit location 53 | exhibit1.location = "San Francisco Zoo" 54 | exhibit1.tourTheExhibit() 55 | //: - Callout(Watch Out!): 56 | //: If a generic type constraint is not fulfilled when subclassing a generic type, then Xcode will complain. 57 | //: 58 | // uncomment the class definition below to see Xcode complain that `TankExhibit`'s generic type `A` does not confirm to the `Animal` protocol. 59 | /* 60 | class TankExhibit: ZooExhibit { 61 | let volume: Double 62 | 63 | init(volume: Double, animals: [B]) { 64 | self.volume = volume 65 | super.init(animals: animals) 66 | } 67 | } 68 | */ 69 | //: [Next](@next) 70 | -------------------------------------------------------------------------------- /Generics/Generics.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Generics/Generics.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Guards/Exercises.playground/Pages/Guard Let Versus If Let.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guard Let Versus If Let 3 | //: The following exercises will use `Card`, `User`, and the `checkout(withUser:forCharge:)` function. 4 | //: 5 | struct Card { 6 | let token: String 7 | let brand: String 8 | let lastFourDigits: String 9 | let validCCV: Bool 10 | } 11 | 12 | class User { 13 | var cards = [String: Card]() 14 | var accountCredit: Double = 0.0 15 | 16 | init(cards: [String: Card], accountCredit: Double) { 17 | self.cards = cards 18 | self.accountCredit = accountCredit 19 | } 20 | 21 | func reduceCreditBy(_ amount: Double) { 22 | accountCredit -= amount 23 | } 24 | } 25 | 26 | func checkout(withUser user: User, forCharge charge: Double) { 27 | let cards = user.cards 28 | 29 | if cards.count > 0 { 30 | guard let card = cards["Personal Card"], card.validCCV, card.brand != "Discover" else { 31 | print("ERROR: must use personal card; discover cards are not accepted") 32 | return 33 | } 34 | 35 | print("CHECKOUT: \(card.brand) \(card.lastFourDigits)") 36 | } else { 37 | guard user.accountCredit >= charge else { 38 | print("ERROR: \(charge) exceeds account credit \(user.accountCredit)") 39 | return 40 | } 41 | 42 | user.reduceCreditBy(charge) 43 | 44 | print("CHECKOUT: used account credit. remaining credit \(user.accountCredit)") 45 | } 46 | } 47 | //: - Callout(Exercise): 48 | //: What will be printed when `checkout(withUser:forCharge:)` is invoked with `user1`, `user2`, `user3`, `user4`, or `user5`? 49 | //: 50 | let user1 = User(cards: [ 51 | "Personal Card": Card(token: "token_00001", brand: "Visa", lastFourDigits: "0123", validCCV: true), 52 | "Business Card": Card(token: "token_00002", brand: "Mastercard", lastFourDigits: "9876", validCCV: true) 53 | ], accountCredit: 32.0) 54 | 55 | 56 | let user2 = User(cards: [ 57 | "Business Card": Card(token: "token_00003", brand: "Visa", lastFourDigits: "2222", validCCV: true) 58 | ], accountCredit: 1043.40) 59 | 60 | let user3 = User(cards: [ 61 | "Personal Card": Card(token: "token_00004", brand: "Discover", lastFourDigits: "4444", validCCV: true), 62 | "Business Card": Card(token: "token_00005", brand: "Mastercard", lastFourDigits: "5555", validCCV: true) 63 | ], accountCredit: 100.00) 64 | 65 | let user4 = User(cards: [:], accountCredit: 10.20) 66 | 67 | let user5 = User(cards: [:], accountCredit: 100.00) 68 | -------------------------------------------------------------------------------- /Guards/Exercises.playground/Pages/Guard Versus If.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guard Versus If 3 | //: There are no exercises for this section, please click **Next** to continue. 4 | 5 | //: [Next](@next) 6 | -------------------------------------------------------------------------------- /Guards/Exercises.playground/Pages/Guard with Optionals.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guards with Optionals 3 | //: - Callout(Exercise): 4 | //: If `checkout(card:)` is invoked using `testCard`, will it exit early? 5 | //: 6 | struct Card { 7 | let token: String 8 | let brand: String 9 | let lastFourDigits: String 10 | let validCCV: Bool 11 | } 12 | 13 | func checkout(card: Card?) { 14 | guard let card = card, card.validCCV, card.brand != "Discover" else { return } 15 | 16 | print("CHECKOUT: \(card.brand) \(card.lastFourDigits)") 17 | } 18 | 19 | let testCard = Card(token: "token1234", brand: "Visa", lastFourDigits: "0123", validCCV: true) 20 | 21 | //: [Next](@next) 22 | -------------------------------------------------------------------------------- /Guards/Exercises.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Guards: Exercises 2 | //: The following pages contain exercises for guards. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /Guards/Exercises.playground/Pages/The Guard Statement.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### The Guard Statement 3 | //: - Callout(Exercise): 4 | //: If `downloadComplete` is false and `pageInitialized` is true, then will `showStory(downloadComplete:pageInitialized:)` exit early? 5 | //: 6 | func showStory(downloadComplete: Bool, pageInitialized: Bool) { 7 | guard downloadComplete else { return } 8 | guard pageInitialized else { return } 9 | 10 | print("story time!") 11 | } 12 | 13 | //: - Callout(Exercise): 14 | //: If `downloadComplete` is true and `panelsLoaded` is false, then what is printed when `showComic(downloadComplete:panelsLoaded:)` is invoked? 15 | //: 16 | func showComic(downloadComplete: Bool, panelsLoaded: Bool) { 17 | guard downloadComplete else { 18 | print("download not complete") 19 | return 20 | } 21 | 22 | guard panelsLoaded else { 23 | print("panels not loaded") 24 | return 25 | } 26 | 27 | print("comic time!") 28 | } 29 | 30 | //: [Next](@next) 31 | -------------------------------------------------------------------------------- /Guards/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Guards/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Guards/ExercisesSolutions.playground/Pages/Guard Let Versus If Let.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guard Let Versus If Let 3 | //: The following exercises will use `Card`, `User`, and the `checkout(withUser:forCharge:)` function. 4 | //: 5 | struct Card { 6 | let token: String 7 | let brand: String 8 | let lastFourDigits: String 9 | let validCCV: Bool 10 | } 11 | 12 | class User { 13 | var cards = [String: Card]() 14 | var accountCredit: Double = 0.0 15 | 16 | init(cards: [String: Card], accountCredit: Double) { 17 | self.cards = cards 18 | self.accountCredit = accountCredit 19 | } 20 | 21 | func reduceCreditBy(_ amount: Double) { 22 | accountCredit -= amount 23 | } 24 | } 25 | 26 | func checkout(withUser user: User, forCharge charge: Double) { 27 | let cards = user.cards 28 | 29 | if cards.count > 0 { 30 | guard let card = cards["Personal Card"], card.validCCV, card.brand != "Discover" else { 31 | print("ERROR: must use personal card; discover cards are not accepted") 32 | return 33 | } 34 | 35 | print("CHECKOUT: \(card.brand) \(card.lastFourDigits)") 36 | } else { 37 | guard user.accountCredit >= charge else { 38 | print("ERROR: \(charge) exceeds account credit \(user.accountCredit)") 39 | return 40 | } 41 | 42 | user.reduceCreditBy(charge) 43 | 44 | print("CHECKOUT: used account credit. remaining credit \(user.accountCredit)") 45 | } 46 | } 47 | //: - Callout(Exercise): 48 | //: What will be printed when `checkout(withUser:forCharge:)` is invoked with `user1`, `user2`, `user3`, `user4`, or `user5`? 49 | //: 50 | let user1 = User(cards: [ 51 | "Personal Card": Card(token: "token_00001", brand: "Visa", lastFourDigits: "0123", validCCV: true), 52 | "Business Card": Card(token: "token_00002", brand: "Mastercard", lastFourDigits: "9876", validCCV: true) 53 | ], accountCredit: 32.0) 54 | 55 | 56 | let user2 = User(cards: [ 57 | "Business Card": Card(token: "token_00003", brand: "Visa", lastFourDigits: "2222", validCCV: true) 58 | ], accountCredit: 1043.40) 59 | 60 | let user3 = User(cards: [ 61 | "Personal Card": Card(token: "token_00004", brand: "Discover", lastFourDigits: "4444", validCCV: true), 62 | "Business Card": Card(token: "token_00005", brand: "Mastercard", lastFourDigits: "5555", validCCV: true) 63 | ], accountCredit: 100.00) 64 | 65 | let user4 = User(cards: [:], accountCredit: 10.20) 66 | 67 | let user5 = User(cards: [:], accountCredit: 100.00) 68 | 69 | checkout(withUser: user1, forCharge: 59.99) 70 | checkout(withUser: user2, forCharge: 59.99) 71 | checkout(withUser: user3, forCharge: 59.99) 72 | checkout(withUser: user4, forCharge: 59.99) 73 | checkout(withUser: user5, forCharge: 59.99) 74 | -------------------------------------------------------------------------------- /Guards/ExercisesSolutions.playground/Pages/Guard Versus If.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guard Versus If 3 | //: There are no exercises for this section, please click **Next** to continue. 4 | 5 | //: [Next](@next) 6 | -------------------------------------------------------------------------------- /Guards/ExercisesSolutions.playground/Pages/Guard with Optionals.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guards with Optionals 3 | //: - Callout(Exercise): 4 | //: If `checkout(card:)` is invoked using `testCard`, will it exit early? 5 | //: 6 | struct Card { 7 | let token: String 8 | let brand: String 9 | let lastFourDigits: String 10 | let validCCV: Bool 11 | } 12 | 13 | func checkout(card: Card?) { 14 | guard let card = card, card.validCCV, card.brand != "Discover" else { return } 15 | 16 | print("CHECKOUT: \(card.brand) \(card.lastFourDigits)") 17 | } 18 | 19 | let testCard = Card(token: "token1234", brand: "Visa", lastFourDigits: "0123", validCCV: true) 20 | 21 | checkout(card: testCard) 22 | //: [Next](@next) 23 | -------------------------------------------------------------------------------- /Guards/ExercisesSolutions.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Guards: Exercises Solutions 2 | //: The following pages contain solutions for the guards exercises. 3 | //: 4 | //: [Next](@next) 5 | 6 | -------------------------------------------------------------------------------- /Guards/ExercisesSolutions.playground/Pages/The Guard Statement.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### The Guard Statement 3 | //: - Callout(Exercise): 4 | //: If `downloadComplete` is false and `pageInitialized` is true, then will `showStory(downloadComplete:pageInitialized:)` exit early? 5 | //: 6 | func showStory(downloadComplete: Bool, pageInitialized: Bool) { 7 | guard downloadComplete else { return } 8 | guard pageInitialized else { return } 9 | 10 | print("story time!") 11 | } 12 | 13 | showStory(downloadComplete: false, pageInitialized: true) 14 | //: - Callout(Exercise): 15 | //: If `downloadComplete` is true and `panelsLoaded` is false, then what is printed when `showComic(downloadComplete:panelsLoaded:)` is invoked? 16 | //: 17 | func showComic(downloadComplete: Bool, panelsLoaded: Bool) { 18 | guard downloadComplete else { 19 | print("download not complete") 20 | return 21 | } 22 | 23 | guard panelsLoaded else { 24 | print("panels not loaded") 25 | return 26 | } 27 | 28 | print("comic time!") 29 | } 30 | 31 | showComic(downloadComplete: true, panelsLoaded: false) 32 | //: [Next](@next) 33 | -------------------------------------------------------------------------------- /Guards/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Guards/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Guards/Guards.playground/Pages/Guard Let Versus If Let.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guard Let Versus If Let 3 | //: When optional values are used with `guard let` (or `guard var`) they are bound as non-optional values and available in the rest of the scope where the guard statement appears. This differs from how optionals work with `if let`. With `if let`, optionals are bound as non-optional constants, and they are only available in the body of the `if let` statement. 4 | //: 5 | func takeOff(passengersSeated: Bool, crewReady: Bool, runwayClear: Bool, crewLeader: String?, greeting: String?) { 6 | guard passengersSeated, crewReady, runwayClear else { return } 7 | guard let crewLeader = crewLeader else { return } 8 | 9 | // the crew leader is available throughout this function 10 | print("\(crewLeader): \"Takeoff checks complete!\"") 11 | 12 | if let greeting = greeting { 13 | // the greeting is only available as a constant in the body of the if statement 14 | print("\(crewLeader): \"\(greeting)\"") 15 | } 16 | 17 | // here, the greeting is optional 18 | if greeting != nil { 19 | print("greeting = \(greeting!)") 20 | } 21 | 22 | print("✈️ Lifts off runway") 23 | } 24 | 25 | takeOff(passengersSeated: true, crewReady: true, runwayClear: true, crewLeader: "👩🏻‍✈️ Natasha", greeting: "Taking off in 3...2...1!") 26 | -------------------------------------------------------------------------------- /Guards/Guards.playground/Pages/Guard Versus If.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: [Previous](@previous) 2 | //: ### Guard Versus If 3 | //: While `guard` and `if` are similar, they should not be used interchangeably. Instead, it is recommended that **guard is used for preconditions (and early exit)** and **if is used for changing the execution path**. Using the flight example from before, notice the difference in how `guard` and `if` are used. 4 | //: 5 | func takeOff(passengersSeated: Bool, crewReady: Bool, runwayClear: Bool, runwayShort: Bool) { 6 | // are all preconditions met? 7 | guard passengersSeated, crewReady, runwayClear else { return } 8 | 9 | // (optional) if the runway is short, then enable high speed takeoff mode 10 | if runwayShort { 11 | print("💥 High speed takeoff enabled") 12 | } 13 | 14 | print("✈️ Lifts off runway") 15 | } 16 | 17 | takeOff(passengersSeated: true, crewReady: true, runwayClear: true, runwayShort: true) 18 | //: Of course, there are situations where using `guard` or `if` may be less clear, and that's ok — this isn't an exact science. The best rule of thumb is to make sure code is readable and concise! 19 | //: 20 | enum Experience { 21 | case novice, expert 22 | } 23 | 24 | struct Pilot { 25 | var name: String 26 | var formerExperience: Experience 27 | var completedFlights: Int 28 | } 29 | 30 | func checkPilot1(_ pilot: Pilot) { 31 | // here, checking for experience creates multiple code paths 32 | if pilot.formerExperience == .novice { 33 | // guard is a precondition to check if the pilot is ready, otherwise early exit! 34 | guard pilot.completedFlights > 20 else { return } 35 | print("ready to fly, rookie?") 36 | } else if pilot.formerExperience == .expert { 37 | guard pilot.completedFlights > 5 else { return } 38 | print("you're up chief") 39 | } 40 | } 41 | 42 | func checkPilot2(_ pilot: Pilot) { 43 | // for conciseness, experience and completed flights could be checked at the same time 44 | if pilot.formerExperience == .novice && pilot.completedFlights > 20 { 45 | print("ready to fly, rookie?") 46 | } else if pilot.formerExperience == .expert && pilot.completedFlights > 5 { 47 | print("you're up chief") 48 | } 49 | } 50 | 51 | func checkPilot3(_ pilot: Pilot) { 52 | // a switch statement could also be used 53 | switch pilot.formerExperience { 54 | case .novice: 55 | guard pilot.completedFlights > 20 else { return } 56 | print("ready to fly, rookie?") 57 | case .expert: 58 | guard pilot.completedFlights > 5 else { return } 59 | print("you're up chief") 60 | } 61 | } 62 | 63 | let teddy = Pilot(name: "Teddy", formerExperience: .novice, completedFlights: 22) 64 | 65 | checkPilot1(teddy) 66 | checkPilot2(teddy) 67 | checkPilot3(teddy) 68 | //: [Next](@next) 69 | -------------------------------------------------------------------------------- /Guards/Guards.playground/Pages/Intro.xcplaygroundpage/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Guards 2 | //: Guards, or guard statements, allow developers to specify conditions that must be true for execution to continue. If any condition is false, then a developer should early exit or take some other comperable action. 3 | //: 4 | //: [Next](@next) 5 | -------------------------------------------------------------------------------- /Guards/Guards.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Guards/Guards.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Udacity 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Optionals/DowncastingWithOptionals.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: ## Downcasting with as? and as! 2 | 3 | import UIKit 4 | 5 | //: ### Downcasting 6 | class Beverage { 7 | var category:String 8 | init (category: String) { 9 | self.category = category 10 | } 11 | } 12 | 13 | class HotDrink: Beverage { 14 | var pairing:String 15 | 16 | init (category: String, pairing: String) { 17 | self.pairing = pairing 18 | super.init(category: category) 19 | } 20 | } 21 | 22 | class ColdDrink: Beverage { 23 | var vessel:String 24 | 25 | init (category: String, vessel: String) { 26 | self.vessel = vessel 27 | super.init(category: category) 28 | } 29 | } 30 | 31 | var drinkChoices = [ 32 | HotDrink(category: "coffee", pairing: "biscotti"), 33 | HotDrink(category: "tea", pairing: "crumpets"), 34 | ColdDrink(category: "lemonade", vessel: "glass"), 35 | ColdDrink(category: "beer", vessel: "frosty mug") 36 | ] 37 | 38 | // Generic drink offer 39 | for beverage in drinkChoices { 40 | print ("Can I get you a \(beverage.category)") 41 | } 42 | //: Type cast operators: __as?__ and __as!__ 43 | // Specific drink offer 44 | for beverage in drinkChoices { 45 | if let coldDrink = beverage as? ColdDrink { 46 | print ("Can I offer you a \(coldDrink.vessel) of \(coldDrink.category)?") 47 | } else if let hotDrink = beverage as? HotDrink { 48 | print ("Can I get you some \(hotDrink.category) with \(hotDrink.pairing)?") 49 | } 50 | } 51 | //: ### Downcasting with as! 52 | var coffeeArray: [Beverage] = [ 53 | HotDrink(category: "coffee", pairing: "biscotti"), 54 | HotDrink(category: "coffee", pairing: "scones"), 55 | HotDrink(category: "coffee", pairing: "biscotti"), 56 | ] 57 | 58 | for beverage in coffeeArray { 59 | let hotDrink = beverage as! HotDrink 60 | print ("Can I get you some \(hotDrink.category) with \(hotDrink.pairing)?") 61 | } 62 | -------------------------------------------------------------------------------- /Optionals/DowncastingWithOptionals.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to DowncastingWithOptionals.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Optionals/DowncastingWithOptionals.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Optionals/DowncastingWithOptionals.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Optionals/DowncastingWithOptionals.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Optionals/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to L2_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Optionals/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Optionals/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Optionals/Exercises.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Optionals/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson2_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /Optionals/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Optionals/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Optionals/Optionals.playground/Resources/puppy_in_box.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Optionals/Optionals.playground/Resources/puppy_in_box.jpg -------------------------------------------------------------------------------- /Optionals/Optionals.playground/Resources/puppy_in_box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Optionals/Optionals.playground/Resources/puppy_in_box.png -------------------------------------------------------------------------------- /Optionals/Optionals.playground/Resources/yorkshire-terrier-puppy_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/Optionals/Optionals.playground/Resources/yorkshire-terrier-puppy_small.png -------------------------------------------------------------------------------- /Optionals/Optionals.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Optionals.playground. 3 | // 4 | 5 | 6 | public struct Tail { 7 | public var length: String 8 | 9 | public init(length:Int) { 10 | self.length = "\(length) cm" 11 | } 12 | } 13 | 14 | public class Animal { 15 | public var name:String 16 | public var species: String = "homo sapiens" 17 | public var tail: Tail? 18 | 19 | public init(name: String, species: String, tailLength:Int?) { 20 | self.name = name 21 | self.species = species 22 | if let tailLength = tailLength { 23 | self.tail = Tail(length: tailLength) 24 | } else { 25 | self.tail = nil 26 | } 27 | 28 | } 29 | } 30 | 31 | public class Car { 32 | public var make:String 33 | public var model: String 34 | 35 | public init(make: String, model: String) { 36 | self.make = make 37 | self.model = model 38 | } 39 | } 40 | 41 | public class Room { 42 | public var name:String 43 | public var occupied: Bool 44 | 45 | public init(name: String, occupied: Bool) { 46 | self.name = name 47 | self.occupied = occupied 48 | } 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /Optionals/Optionals.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Optionals/Optionals.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ProtocolsExtensions/CalmTheCompiler.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: ### Calm the compiler 2 | // Problem 1 3 | protocol DirtyDeeds { 4 | func cheat() 5 | func steal() 6 | } 7 | 8 | class Minion: DirtyDeeds { 9 | var name: String 10 | 11 | init(name:String) { 12 | self.name = name 13 | } 14 | } 15 | 16 | // Problem 2 17 | class DinnerCrew { 18 | var members: [Souschef] 19 | 20 | init(members: [Souschef]) { 21 | self.members = members 22 | } 23 | } 24 | 25 | protocol Souschef { 26 | func chop(_ vegetable: String) -> String 27 | func rinse(_ vegetable:String) -> String 28 | } 29 | 30 | var deviousDinnerCrew = DinnerCrew(members: [Minion]()) 31 | 32 | // Problem 3 33 | protocol DogWalker { 34 | func throwBall(_ numberOfTimes:Int) -> Int 35 | func rubBelly() 36 | } 37 | 38 | class Neighbor: DogWalker { 39 | 40 | func throwBall(_ numberOfTimes:Int) { 41 | var count = 0 42 | while count < numberOfTimes { 43 | print("Go get it!") 44 | count += 1 45 | } 46 | } 47 | 48 | func rubBelly() { 49 | print("Rub rub") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ProtocolsExtensions/CalmTheCompiler.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson8_CalmTheCompiler.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ProtocolsExtensions/CalmTheCompiler.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ProtocolsExtensions/CalmTheCompiler.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ProtocolsExtensions/Exercises.playground/Resources/frolick.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/Exercises.playground/Resources/frolick.jpg -------------------------------------------------------------------------------- /ProtocolsExtensions/Exercises.playground/Resources/mouseBall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/Exercises.playground/Resources/mouseBall.png -------------------------------------------------------------------------------- /ProtocolsExtensions/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson8_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ProtocolsExtensions/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ProtocolsExtensions/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ProtocolsExtensions/ExercisesSolutions.playground/Resources/dogInABall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/ExercisesSolutions.playground/Resources/dogInABall.png -------------------------------------------------------------------------------- /ProtocolsExtensions/ExercisesSolutions.playground/Resources/frolick.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/ExercisesSolutions.playground/Resources/frolick.jpg -------------------------------------------------------------------------------- /ProtocolsExtensions/ExercisesSolutions.playground/Resources/mouseBall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/ExercisesSolutions.playground/Resources/mouseBall.png -------------------------------------------------------------------------------- /ProtocolsExtensions/ExercisesSolutions.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson8_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /ProtocolsExtensions/ExercisesSolutions.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /ProtocolsExtensions/ExercisesSolutions.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // FadeExtensionDemo 4 | // 5 | // Created by Gabrielle Miller-Messner on 6/26/15. 6 | // Copyright (c) 2015 Gabrielle Miller-Messner. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: - AppDelegate: UIResponder, UIApplicationDelegate 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | // MARK: Properties 17 | 18 | var window: UIWindow? 19 | 20 | // MARK: UIApplicationDelegate 21 | 22 | private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 23 | // Override point for customization after application launch. 24 | return true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 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 | 27 | 28 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-40-2.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-60@2x-2.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Small@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Small@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-20.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-40-3.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-Small.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-Small@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-40.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-40@2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-76.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-76@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "Icon-1024.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-20.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40-2.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40-3.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x-2.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/LaunchLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchLogo.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/LaunchLogo.imageset/LaunchLogo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/LaunchLogo.imageset/LaunchLogo.pdf -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/sunrise.imageset/6776635-beautiful-sunrise-wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/sunrise.imageset/6776635-beautiful-sunrise-wallpaper.jpg -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/sunrise.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "6776635-beautiful-sunrise-wallpaper.jpg" 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 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/sunset.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "mountain-sunset.jpg" 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 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/sunset.imageset/mountain-sunset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Images.xcassets/sunset.imageset/mountain-sunset.jpg -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/UIViewExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewExtensions.swift 3 | // FadeExtensionDemo 4 | // 5 | // Created by Gabrielle Miller-Messner on 6/26/15. 6 | // Copyright (c) 2015 Gabrielle Miller-Messner. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | // MARK: - UIView (Extensions) 13 | 14 | extension UIView { 15 | 16 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo/FadeExtensionDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // FadeExtensionDemo 4 | // 5 | // Created by Gabrielle Miller-Messner on 6/26/15. 6 | // Copyright (c) 2015 Gabrielle Miller-Messner. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: - ViewController: UIViewController 12 | 13 | class ViewController: UIViewController { 14 | 15 | // MARK: Outlets 16 | 17 | @IBOutlet weak var imageView: UIImageView! 18 | 19 | // MARK: Actions 20 | 21 | @IBAction func sunRiseAndSet(sender: AnyObject) { 22 | // Fade out 23 | UIView.animate(withDuration: 1.0, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: { 24 | self.imageView.alpha = 0.0 25 | }, completion: { 26 | (finished: Bool) -> Void in 27 | 28 | //Once the label is completely invisible, set the text and fade it back in 29 | if (self.imageView.image == UIImage(named: "sunrise")) { 30 | self.imageView.image = UIImage(named:"sunset")! 31 | } else { 32 | self.imageView.image = UIImage(named:"sunrise")! 33 | } 34 | 35 | // Fade in 36 | UIView.animate(withDuration: 1.0, delay:0.0, options:UIViewAnimationOptions.curveEaseIn, animations: { 37 | self.imageView.alpha = 1.0 38 | }, completion: nil) 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // FadeExtensionDemo 4 | // 5 | // Created by Gabrielle Miller-Messner on 6/26/15. 6 | // Copyright (c) 2015 Gabrielle Miller-Messner. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: - AppDelegate: UIResponder, UIApplicationDelegate 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | // MARK: Properties 17 | 18 | var window: UIWindow? 19 | 20 | // MARK: UIApplicationDelegate 21 | 22 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool { 23 | // Override point for customization after application launch. 24 | return true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 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 | 27 | 28 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-40-2.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-60@2x-2.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-Small@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Small@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "Icon-20.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-40-3.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-Small.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-Small@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-40.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-40@2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-76.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-76@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "Icon-1024.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-1024.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-20.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40-2.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40-3.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-40@3x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-60@2x-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-60@2x-2.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/LaunchLogo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchLogo.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/LaunchLogo.imageset/LaunchLogo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/LaunchLogo.imageset/LaunchLogo.pdf -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/sunrise.imageset/6776635-beautiful-sunrise-wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/sunrise.imageset/6776635-beautiful-sunrise-wallpaper.jpg -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/sunrise.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "6776635-beautiful-sunrise-wallpaper.jpg" 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 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/sunset.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "mountain-sunset.jpg" 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 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/sunset.imageset/mountain-sunset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Images.xcassets/sunset.imageset/mountain-sunset.jpg -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/UIViewExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewExtensions.swift 3 | // FadeExtensionDemo_Completed 4 | // 5 | // Created by Gabrielle Miller-Messner on 7/14/15. 6 | // Copyright (c) 2015 Gabrielle Miller-Messner. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | // MARK: - UIView (Extensions) 13 | 14 | extension UIView { 15 | 16 | func fadeOut(duration: TimeInterval, delay: TimeInterval, completion: ((Bool) -> Void)?) { 17 | UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: { 18 | self.alpha = 0.0 19 | }, completion: completion) 20 | } 21 | 22 | func fadeIn(duration: TimeInterval, delay: TimeInterval, completion:((Bool) -> Void)?) { 23 | UIView.animate(withDuration: duration, delay:delay, options: UIViewAnimationOptions.curveEaseIn, animations: { 24 | self.alpha = 1.0 25 | }, completion: completion) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ProtocolsExtensions/FadeExtensionDemo_Completed/FadeExtensionDemo_Completed/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // FadeExtensionDemo_Completed 4 | // 5 | // Created by Gabrielle Miller-Messner on 7/14/15. 6 | // Copyright (c) 2015 Gabrielle Miller-Messner. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: - ViewController: UIViewController 12 | 13 | class ViewController: UIViewController { 14 | 15 | // MARK: Outlets 16 | 17 | @IBOutlet weak var imageView: UIImageView! 18 | 19 | // MARK: Actions 20 | 21 | @IBAction func sunRiseAndSet(sender: AnyObject) { 22 | // Fade out 23 | imageView.fadeOut(duration: 1.0, delay: 0.0, completion: { 24 | (finished: Bool) -> Void in 25 | 26 | //Once the imageView is invisible, set the image property to a new value 27 | if (self.imageView.image == UIImage(named: "sunrise")) { 28 | self.imageView.image = UIImage(named:"sunset")! 29 | } else { 30 | self.imageView.image = UIImage(named:"sunrise")! 31 | } 32 | 33 | // Then fade the image back in 34 | self.imageView.fadeIn(duration: 1.0, delay: 0.0, completion: nil) 35 | }) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ProtocolsExtensions/Protocols.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Protocols 2 | 3 | import UIKit 4 | 5 | //: ### Protocol Syntax 6 | // Example 1 7 | protocol Souschef { 8 | func chop(vegetable: String) -> String 9 | func rinse(vegetable: String) -> String 10 | } 11 | 12 | class Roommate: Souschef, Equatable { 13 | var hungry = true 14 | var name: String 15 | 16 | init(hungry: Bool, name: String) { 17 | self.hungry = hungry 18 | self.name = name 19 | } 20 | 21 | func chop(vegetable: String) -> String { 22 | return "She's choppin' \(vegetable)!" 23 | } 24 | 25 | func rinse(vegetable: String) -> String { 26 | return "The \(vegetable) is so fresh and so clean" 27 | } 28 | } 29 | 30 | // Example 2 31 | func ==(lhs: Roommate, rhs: Roommate) -> Bool { 32 | return lhs.name == rhs.name && lhs.hungry == rhs.hungry 33 | } 34 | 35 | var roomie = Roommate(hungry: true, name: "Jennifer") 36 | var theBestRoomie = Roommate(hungry: true, name: "Jennifer") 37 | 38 | roomie == theBestRoomie 39 | 40 | //: ### A protocol is also a type 41 | 42 | class DinnerCrew { 43 | var members: [Souschef] 44 | 45 | init(members: [Souschef]) { 46 | self.members = members 47 | } 48 | } 49 | 50 | class RandomPasserby: Souschef { 51 | var name: String 52 | 53 | init(name: String){ 54 | self.name = name 55 | } 56 | 57 | func chop(vegetable: String) -> String { 58 | return "She's choppin' \(vegetable)!" 59 | } 60 | 61 | func rinse(vegetable: String) -> String { 62 | return "The \(vegetable) is so fresh and so clean" 63 | } 64 | } 65 | 66 | var newFriend = RandomPasserby(name: "Dave") 67 | var motleyDinnerCrew = DinnerCrew(members:[newFriend, roomie]) 68 | 69 | -------------------------------------------------------------------------------- /ProtocolsExtensions/Protocols.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson8_Protocols.playground. 3 | // 4 | 5 | public class Person { 6 | 7 | 8 | } -------------------------------------------------------------------------------- /ProtocolsExtensions/Protocols.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ProtocolsExtensions/Protocols.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | iOS Developer Nanodegree logo 2 | 3 | # Swift Syntax 4 | 5 | ![Platform iOS](https://img.shields.io/badge/nanodegree-iOS-blue.svg) 6 | 7 | This repository contains resources for Udacity's Swift Syntax course. 8 | 9 | ## Overview 10 | 11 | Swift Syntax is a course designed for developers transitioning into Swift. It surveys the language's main features and provides lesson-by-lesson examples for you to follow. 12 | 13 | ## Setup 14 | 15 | Generally speaking, most projects can run without any additional setup. However, consult the Swift Syntax course for more information. 16 | 17 | ## Maintainers 18 | 19 | @OwenLaRosa 20 | -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Constants and Variables 2 | 3 | import UIKit 4 | 5 | //: ### Example 1 6 | //: ### Use let when you know the value will stay constant 7 | let encouragement = "You can do it!" 8 | //: ### Use var when you expect the value to change 9 | var personalizedEncouragement = "You can do it, Lauren!" 10 | personalizedEncouragement = personalizedEncouragement.replacingOccurrences(of: "Lauren", with: "Cameron") 11 | //: ### Example 2a 12 | let birthYear = 2008 13 | var currentYear = 2015 14 | var age = currentYear - birthYear 15 | //: ### Example 2b - What if age only needs to be calculated once? 16 | 17 | //: ### Example 3 18 | let birthweight = "6 lbs 7 ounces" 19 | var currentWeight = "22lbs" 20 | var chubbyBaby = UIImage(named:"chubby-baby-picture.jpg")! 21 | 22 | //: ### Two ways of being immutable - #1 Assignment 23 | var goat = UIImage(named:"Chinese-New-Year-3.jpg")! 24 | let yearsOfTheGoat = [1967, 1979, 1991, 2003, 2015] 25 | let yearsOfTheSheep = [1967, 1979, 1991, 2003, 2015] 26 | //yearsOfTheGoat = yearsOfTheSheep 27 | //: ### Two ways of being immutable - #2 Value alteration 28 | //yearsOfTheGoat.append(2027) 29 | 30 | 31 | -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Resources/Chinese-New-Year-3 copy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/ConstantsVariables.playground/Resources/Chinese-New-Year-3 copy.jpg -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Resources/Chinese-New-Year-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/ConstantsVariables.playground/Resources/Chinese-New-Year-3.jpg -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Resources/Chinese-New-Year-goat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/ConstantsVariables.playground/Resources/Chinese-New-Year-goat.jpg -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Resources/chubby-baby-picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/ConstantsVariables.playground/Resources/chubby-baby-picture.jpg -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Resources/chubby_baby_with_dog.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/ConstantsVariables.playground/Resources/chubby_baby_with_dog.jpeg -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Resources/cute_baby_and_dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/ConstantsVariables.playground/Resources/cute_baby_and_dog.jpg -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Constants&Variables.playground. 3 | // 4 | -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SwiftBasics/ConstantsVariables.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftBasics/Exercises.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson1_Exercises.playground. 3 | // 4 | -------------------------------------------------------------------------------- /SwiftBasics/Exercises.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SwiftBasics/Exercises.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftBasics/Exercises.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /SwiftBasics/ExercisesSolution.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson1_Exercises_withSolutions.playground. 3 | // 4 | -------------------------------------------------------------------------------- /SwiftBasics/ExercisesSolution.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SwiftBasics/ExercisesSolution.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Strings 2 | 3 | import UIKit 4 | import Foundation 5 | 6 | //: ## Defining Strings using string literals 7 | let myFirstString = "mo 💰" 8 | let mySecondString = "mo problems" 9 | 10 | //: ## String concatenation 11 | //let theTruth = myFirstString + ", " + mySecondString 12 | 13 | let theTruth = "💰 can't buy me 💖." 14 | 15 | let theBaseballTeamInAtlanta = "Atlanta Braves" 16 | var jamesFavoriteBaseballTeam = "Atlanta Braves" 17 | 18 | var nWithTilde = "\u{006E}\u{0303}" 19 | nWithTilde.unicodeScalars.count 20 | nWithTilde.characters.count 21 | 22 | //: ## Emoji characters 23 | let similarTruth = "💰can't buy me 💖" 24 | 25 | // Here's one way to initialize an empty Swift string 26 | var characterPoorString = "" 27 | 28 | // And here's another 29 | let potentialRichString = String() 30 | characterPoorString.characters 31 | 32 | //: ## String interpolation 33 | 34 | //: ### Plain string 35 | 36 | var doggyDiet = "Lulu eats 25lbs of dog food per month" 37 | //: ### String with variables 38 | var dogName = "Ferris" 39 | var ferrisPic = UIImage(named:"SpringerdoodleFerris.jpg")! 40 | doggyDiet = "\(dogName) eats 25lbs of dog food per month" 41 | 42 | //: ### String with variables and expression 43 | var lbsPerDay = 0.75 44 | var daysPerMonth:Double = 30.0 45 | doggyDiet = "\(dogName) eats ?lbs of dog food per month" 46 | 47 | var frankiePic = UIImage(named:"frankie.jpeg")! 48 | lbsPerDay = 0.25 49 | dogName = "Lil Frankie" 50 | doggyDiet = "\(dogName) eats ?lbs of dog food per month" 51 | //: ## A String isn't just a String 52 | 53 | //: ### Through the .characters property we can access an array of characters 54 | var password = "Meet me in St. Louis" 55 | for character in password.characters { 56 | if character == "e" { 57 | print("found an e!") 58 | } else { 59 | } 60 | } 61 | 62 | //: ### A String can be treated as an NSString 63 | let newPassword = password.replacingOccurrences(of: "e", with: "3") 64 | 65 | -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/Resources/SpringerdoodleFerris.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/Strings.playground/Resources/SpringerdoodleFerris.jpg -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/Resources/frankie.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/Strings.playground/Resources/frankie.jpeg -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/Resources/frankie_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/Strings.playground/Resources/frankie_small.jpg -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/Resources/yorkshire-terrier-puppy-Max_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/Strings.playground/Resources/yorkshire-terrier-puppy-Max_small.jpg -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Strings.playground. 3 | // 4 | -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SwiftBasics/Strings.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftBasics/TypesOperators.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | //: # Types 2 | 3 | import UIKit 4 | import Foundation 5 | 6 | //: ### Example 1: Bool, Int, Float, Double 7 | class LightSwitch { 8 | 9 | var on: Bool = true 10 | } 11 | 12 | var livingRoomSwitch = LightSwitch() 13 | livingRoomSwitch.on 14 | //: ### Example 2: Strings and Characters 15 | var dollarSign: Character = "$" 16 | var myFirstSwiftString: String = "mo' money" 17 | var mySecondSwiftString: String = "mo' problems" 18 | var concatenatedString:String = myFirstSwiftString + ", " + mySecondSwiftString 19 | 20 | //: ### Stay tuned for more on Optionals and Tuples in the upcoming lessons! 21 | 22 | //: # Operators 23 | 24 | //: ### Example 1 - Comparison operators 25 | let ticketPrice = 7.5 26 | let allowance = 10.0 27 | var iceCreamPrice = 3.0 28 | 29 | var pic = UIImage(named:"Chloe.png")! 30 | 31 | if allowance >= ticketPrice + iceCreamPrice { 32 | print("Let's go to the movies!") 33 | } else { 34 | print("Let's watch a movie at home and eat ice cream") 35 | } 36 | //: ### Example 2 Logical operators 37 | var hungry = true 38 | var vegetarian = false 39 | 40 | if hungry { 41 | print("Let's eat!") 42 | } else { 43 | print("Let's wait.") 44 | } 45 | 46 | if hungry && !vegetarian { 47 | print("Let's eat steak!") 48 | } else if hungry && vegetarian { 49 | print("How about pumpkin curry?") 50 | } else { 51 | print("nevermind") 52 | } 53 | 54 | var thereIsPie = true 55 | if hungry || thereIsPie { 56 | print("Let's eat!") 57 | } else { 58 | print("Let's wait.") 59 | } 60 | 61 | //: ### Example 3 - Ternary conditional 62 | //: A theoretical example from Apple's Swift Programming Language. These two statements are equivalent: 63 | /*: 64 | if question { 65 | answer1 66 | } else { 67 | answer2 68 | } 69 | */ 70 | /*: 71 | question ? answer1 : answer2 72 | */ 73 | // This statement ... 74 | //if hungry { 75 | // print("Let's eat!") 76 | //} else { 77 | // print("Let's wait.") 78 | //} 79 | 80 | // Could be rewritten like so ... 81 | hungry ? print("Let's eat!") : print("Let's wait.") 82 | 83 | // This statement... 84 | //if hungry || thereIsPie { 85 | // print("Let's eat!") 86 | //} else { 87 | // print("Let's wait.") 88 | //} 89 | 90 | // Could be rewritten like so ... 91 | hungry || thereIsPie ? print("Let's eat!") : print("Let's wait.") 92 | 93 | 94 | // Ternary statements can also be used as expressions. 95 | let sandwichPrice = 5.0 96 | var tax = true 97 | var lunchPrice = sandwichPrice + (tax ? 0.50 : 0) 98 | 99 | //: ### Extra Example - Comparison operators 100 | let birthYear = 1984 101 | if birthYear <= 1989 { 102 | print("I will understand Gabrielle's 90s references.") 103 | } 104 | else { 105 | print("I think that Salt n' Peppa are essential seasonings.") 106 | } 107 | 108 | 109 | -------------------------------------------------------------------------------- /SwiftBasics/TypesOperators.playground/Resources/Chloe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/ios-nd-swift-syntax/fa30c738d449d07ce44a1448653483644502df8c/SwiftBasics/TypesOperators.playground/Resources/Chloe.png -------------------------------------------------------------------------------- /SwiftBasics/TypesOperators.playground/Sources/SupportCode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to Lesson1_Types.playground. 3 | // 4 | -------------------------------------------------------------------------------- /SwiftBasics/TypesOperators.playground/contents.xcplayground: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /SwiftBasics/TypesOperators.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftBasics/TypesOperators.playground/timeline.xctimeline: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | --------------------------------------------------------------------------------