feat: experimenting with 00 in playgrounds
This commit is contained in:
parent
6023b7c911
commit
11735e8817
|
@ -0,0 +1,81 @@
|
|||
# Xcode
|
||||
#
|
||||
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData/
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata/
|
||||
|
||||
## Other
|
||||
*.moved-aside
|
||||
*.xccheckout
|
||||
*.xcscmblueprint
|
||||
|
||||
## Obj-C/Swift specific
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.dSYM.zip
|
||||
*.dSYM
|
||||
|
||||
## Playgrounds
|
||||
timeline.xctimeline
|
||||
playground.xcworkspace
|
||||
|
||||
# Swift Package Manager
|
||||
#
|
||||
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
|
||||
# Packages/
|
||||
# Package.pins
|
||||
# Package.resolved
|
||||
.build/
|
||||
|
||||
# CocoaPods
|
||||
#
|
||||
# We recommend against adding the Pods directory to your .gitignore. However
|
||||
# you should judge for yourself, the pros and cons are mentioned at:
|
||||
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||
#
|
||||
# Pods/
|
||||
#
|
||||
# Add this line if you want to avoid checking in source code from the Xcode workspace
|
||||
# *.xcworkspace
|
||||
|
||||
# Carthage
|
||||
#
|
||||
# Add this line if you want to avoid checking in source code from Carthage dependencies.
|
||||
# Carthage/Checkouts
|
||||
|
||||
Carthage/Build
|
||||
|
||||
# fastlane
|
||||
#
|
||||
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||
# screenshots whenever they are needed.
|
||||
# For more information about the recommended setup visit:
|
||||
# https://docs.fastlane.tools/best-practices/source-control/#source-control
|
||||
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots/**/*.png
|
||||
fastlane/test_output
|
||||
|
||||
# Code Injection
|
||||
#
|
||||
# After new code Injection tools there's a generated folder /iOSInjectionProject
|
||||
# https://github.com/johnno1962/injectionforxcode
|
||||
|
||||
iOSInjectionProject/
|
||||
|
||||
|
||||
private/
|
Binary file not shown.
|
@ -2,6 +2,56 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
var str = "Hello, playground"
|
||||
|
||||
func arrayTypes() {
|
||||
let songs: [String] = [
|
||||
"Shake It Off",
|
||||
"Welcome to New York",
|
||||
"You Belong with Me",
|
||||
]
|
||||
|
||||
type(of: songs)
|
||||
|
||||
|
||||
let items: [Any] = [
|
||||
"This array contains items of",
|
||||
2,
|
||||
"different data types"
|
||||
]
|
||||
|
||||
type(of: items)
|
||||
}
|
||||
|
||||
|
||||
func arrayInitialization() {
|
||||
// var awards: [String]
|
||||
//
|
||||
// awards[0] = "Grammy"
|
||||
let awards: [String] = []
|
||||
|
||||
type(of: awards)
|
||||
}
|
||||
|
||||
|
||||
func arrayOperators() {
|
||||
var awards: [String] = []
|
||||
|
||||
awards += ["Grammy", "Oscar"]
|
||||
awards.append("Tony")
|
||||
|
||||
print(awards)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func main() {
|
||||
arrayTypes()
|
||||
arrayInitialization()
|
||||
arrayOperators()
|
||||
}
|
||||
|
||||
|
||||
main()
|
||||
|
||||
|
||||
//: [Next](@next)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
//: [Previous](@previous)
|
||||
|
||||
import Foundation
|
||||
|
||||
struct Person {
|
||||
static var species: String = "Homo Sapien"
|
||||
var age: Int
|
||||
|
||||
var clothes: String {
|
||||
willSet {
|
||||
updateUI(msg: "I'm changing from \(clothes) to \(newValue)")
|
||||
}
|
||||
didSet {
|
||||
updateUI(msg: "I just changed from \(oldValue) to \(clothes)")
|
||||
}
|
||||
}
|
||||
|
||||
var ageInDogYears: Int {
|
||||
return age * 7
|
||||
}
|
||||
|
||||
func updateUI(msg: String) {
|
||||
print(msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func demo1() {
|
||||
var taylor = Person(clothes: "T-Shirt", age: 29)
|
||||
|
||||
taylor.clothes = "T-Shirt and Jeans"
|
||||
}
|
||||
|
||||
|
||||
demo1()
|
||||
//: [Next](@next)
|
|
@ -0,0 +1,65 @@
|
|||
//: [Previous](@previous)
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
class Singer {
|
||||
var name: String
|
||||
var age: Int
|
||||
|
||||
init(name: String, age: Int) {
|
||||
self.name = name
|
||||
self.age = age
|
||||
}
|
||||
|
||||
func sing() {
|
||||
print("La la la")
|
||||
}
|
||||
}
|
||||
|
||||
class RockSinger: Singer {
|
||||
override func sing() {
|
||||
print("Yeah yeah yeah")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class HeavyMetalSinger: Singer {
|
||||
var noiseLevel: Int
|
||||
|
||||
init(name: String, age: Int, noiseLevel: Int) {
|
||||
self.noiseLevel = noiseLevel
|
||||
|
||||
super.init(name: name, age: age)
|
||||
}
|
||||
|
||||
override func sing() {
|
||||
print("Grrrrrr rrr")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func demo1() {
|
||||
let taylor = Singer(name: "Taylor Swift", age: 29)
|
||||
let bono = RockSinger(name: "Bono", age: 100)
|
||||
let metalSinger = HeavyMetalSinger(name: "Rage", age: 10, noiseLevel: 2)
|
||||
|
||||
bono.sing()
|
||||
metalSinger.sing()
|
||||
}
|
||||
|
||||
|
||||
func instancesAreCopiedByReference() {
|
||||
let taylor = Singer(name: "Taylor Swift", age: 29)
|
||||
let imposter = taylor
|
||||
|
||||
imposter.age = 33
|
||||
|
||||
print(taylor.age)
|
||||
}
|
||||
|
||||
|
||||
|
||||
demo1()
|
||||
instancesAreCopiedByReference()
|
||||
//: [Next](@next)
|
|
@ -2,6 +2,20 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
var str = "Hello, playground"
|
||||
var latitude: Double = 42.111234
|
||||
var longitude: Float = -122.9283233
|
||||
|
||||
// Floats preserve accuracy of the most significant digits first
|
||||
longitude = -11.232323
|
||||
longitude = -112.32323
|
||||
longitude = -1123.2323
|
||||
longitude = -11232.323
|
||||
|
||||
// Doubles have twice the accuracy of Floats, and can preserve twice as many digits
|
||||
latitude = -11.232323
|
||||
latitude = -112.32323
|
||||
latitude = -1123.2323
|
||||
latitude = -11232.323
|
||||
latitude = -11232.32323423909109
|
||||
|
||||
//: [Next](@next)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
//: [Previous](@previous)
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
enum WeatherType {
|
||||
case sun
|
||||
case cloud
|
||||
case rain
|
||||
case wind(speed: Double)
|
||||
case snow
|
||||
}
|
||||
|
||||
|
||||
func getHaterStatus(when weatherType: WeatherType) -> String? {
|
||||
switch weatherType {
|
||||
case .wind(let speed) where speed < 10:
|
||||
return "Calm"
|
||||
case .sun, .wind:
|
||||
return "Hate"
|
||||
case .rain:
|
||||
return "Prickly"
|
||||
case .cloud, .snow:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func demo1() {
|
||||
print(getHaterStatus(when: .sun))
|
||||
print(getHaterStatus(when: .wind(speed: 4.0)))
|
||||
print(getHaterStatus(when: .wind(speed: 100.0)))
|
||||
}
|
||||
|
||||
|
||||
demo1()
|
||||
//: [Next](@next)
|
|
@ -2,6 +2,101 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
var str = "Hello, playground"
|
||||
|
||||
func logLetters(string: String) {
|
||||
print("The string \"\(string)\" has \(string.count) letters")
|
||||
}
|
||||
|
||||
|
||||
func logLetters(in string: String) {
|
||||
print("The string \"\(string)\" has \(string.count) letters")
|
||||
}
|
||||
|
||||
func logLetters(_ str: String) {
|
||||
print("The string \"\(str)\" has \(str.count) letters")
|
||||
}
|
||||
|
||||
func isAlbumTaylors(name: String) -> Bool {
|
||||
return [
|
||||
"Taylor Swift",
|
||||
"Fearless",
|
||||
"Speak Now",
|
||||
"1989",
|
||||
"Red",
|
||||
"Reputation"
|
||||
].contains(name)
|
||||
}
|
||||
|
||||
|
||||
func getHaterStatus(weather: String) -> String? {
|
||||
if weather == "Sunny" {
|
||||
return nil
|
||||
} else {
|
||||
return "Hate"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func getAlbumReleaseYear(name: String) -> Int? {
|
||||
if name == "Taylor Swift" { return 2006 }
|
||||
if name == "Fearless" { return 2008 }
|
||||
if name == "Speak Now" { return 2010 }
|
||||
if name == "Red" { return 2012 }
|
||||
if name == "1989" { return 2014 }
|
||||
if name == "Reputation" { return 2017 }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
func externalAndInternalParameters() {
|
||||
logLetters(string: "Fearless")
|
||||
logLetters(in: "Hide")
|
||||
logLetters("Solo")
|
||||
}
|
||||
|
||||
func returnTypes() {
|
||||
print(isAlbumTaylors(name: "A Better Tomorrow"))
|
||||
print(isAlbumTaylors(name: "1989"))
|
||||
}
|
||||
|
||||
|
||||
func optionals() {
|
||||
// var status: String
|
||||
var status: String?
|
||||
|
||||
status = getHaterStatus(weather: "Stormy")
|
||||
status = getHaterStatus(weather: "Sunny")
|
||||
|
||||
if let unwrappedStatus = status {
|
||||
print("Hater status confirmed")
|
||||
} else {
|
||||
print("No hater status")
|
||||
}
|
||||
|
||||
if let newStatus = getHaterStatus(weather: "Hot") {
|
||||
print("Hater status confirmed")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func forceUnwrapping() {
|
||||
let year = getAlbumReleaseYear(name: "Red")
|
||||
|
||||
|
||||
if (year == nil) {
|
||||
print("No release year found")
|
||||
} else {
|
||||
print("Release Year: \(year!)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
externalAndInternalParameters()
|
||||
returnTypes()
|
||||
optionals()
|
||||
forceUnwrapping()
|
||||
|
||||
//: [Next](@next)
|
||||
|
|
|
@ -2,9 +2,28 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
func ranges() {
|
||||
for i in 1...3 {
|
||||
print("Closed Range: Step \(i)")
|
||||
}
|
||||
|
||||
print()
|
||||
|
||||
for i in 1..<3 {
|
||||
print("Half-Open Range: Step \(i)")
|
||||
}
|
||||
|
||||
print()
|
||||
|
||||
print("Haters gonna ")
|
||||
for _ in 1...5 {
|
||||
print("hate")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
ranges()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,19 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
var str = "Hello, playground"
|
||||
|
||||
func stringConcatenation() {
|
||||
let firstName = "Taylor"
|
||||
let lastName = "Swift"
|
||||
|
||||
let fullName = firstName + " " + lastName
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
stringConcatenation()
|
||||
}
|
||||
|
||||
|
||||
main()
|
||||
//: [Next](@next)
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
//: [Previous](@previous)
|
||||
|
||||
import Foundation
|
||||
|
||||
func getAlbumReleaseYear(for name: String) -> Int? {
|
||||
if name == "Taylor Swift" { return 2006 }
|
||||
if name == "Fearless" { return 2008 }
|
||||
if name == "Speak Now" { return 2010 }
|
||||
if name == "Red" { return 2012 }
|
||||
if name == "1989" { return 2014 }
|
||||
if name == "Reputation" { return 2017 }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAlbumReleased(in year: Int) -> String? {
|
||||
if year == 2006 { return "Taylor Swift" }
|
||||
if year == 2008 { return "Fearless" }
|
||||
if year == 2010 { return "Speak Now" }
|
||||
if year == 2012 { return "Red" }
|
||||
if year == 2014 { return "1989" }
|
||||
if year == 2017 { return "Reputation" }
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func demo1() {
|
||||
let album = getAlbumReleased(in: 2006)
|
||||
|
||||
print("\(album?.uppercased()) was released in 2006")
|
||||
}
|
||||
|
||||
|
||||
func nilCoalescingDemo() {
|
||||
let album = getAlbumReleased(in: 2006)
|
||||
|
||||
print("\(album ?? "Nothing that we know of") was released in 2006")
|
||||
}
|
||||
|
||||
|
||||
demo1()
|
||||
nilCoalescingDemo()
|
||||
|
||||
//: [Next](@next)
|
|
@ -0,0 +1,86 @@
|
|||
//: [Previous](@previous)
|
||||
|
||||
import Foundation
|
||||
|
||||
class Album {
|
||||
var name: String
|
||||
|
||||
var salesPerformance: String {
|
||||
return "The album \"\(name)\" sold lots"
|
||||
}
|
||||
|
||||
init(name: String) {
|
||||
self.name = name
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class StudioAlbum: Album {
|
||||
var studio: String
|
||||
|
||||
override var salesPerformance: String {
|
||||
return "The studio album \"\(name)\" sold lots"
|
||||
}
|
||||
|
||||
init(name: String, studio: String) {
|
||||
self.studio = studio
|
||||
super.init(name: name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LiveAlbum: Album {
|
||||
var location: String
|
||||
|
||||
override var salesPerformance: String {
|
||||
return "The live album \"\(name)\" sold lots"
|
||||
}
|
||||
|
||||
init(name: String, location: String) {
|
||||
self.location = location
|
||||
super.init(name: name)
|
||||
}
|
||||
}
|
||||
|
||||
let taylorSwift = StudioAlbum(name: "Taylor Swift", studio: "The Castles Studio")
|
||||
let fearless = StudioAlbum(name: "Fearless", studio: "Aimeeland Studio")
|
||||
let iTunesLive = LiveAlbum(name: "iTunes Live from SoHo", location: "NYC")
|
||||
|
||||
|
||||
func optionalDowncasting() {
|
||||
let allAlbums: [Album] = [taylorSwift, fearless, iTunesLive]
|
||||
|
||||
print(allAlbums)
|
||||
|
||||
for album in allAlbums {
|
||||
print(album.salesPerformance)
|
||||
|
||||
if let studioAlbum = album as? StudioAlbum {
|
||||
print(studioAlbum.studio)
|
||||
} else if let liveAlbum = album as? LiveAlbum {
|
||||
print(liveAlbum.location)
|
||||
}
|
||||
}
|
||||
|
||||
for album in allAlbums as? [LiveAlbum] ?? [LiveAlbum]() {
|
||||
print(album.location)
|
||||
}
|
||||
}
|
||||
|
||||
func forcedDowncasting() {
|
||||
let allAlbums: [Album] = [taylorSwift, fearless]
|
||||
|
||||
for album in allAlbums {
|
||||
let studioAlbum = album as! StudioAlbum
|
||||
print(studioAlbum.studio)
|
||||
}
|
||||
|
||||
for album in allAlbums as! [StudioAlbum] {
|
||||
print(album.studio)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
optionalDowncasting()
|
||||
forcedDowncasting()
|
||||
//: [Next](@next)
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='6.0' target-platform='ios' executeOnSourceChanges='false'>
|
||||
<pages>
|
||||
<page name='Data Types'/>
|
||||
<page name='Operators'/>
|
||||
<page name='Arrays'/>
|
||||
<page name='Loops'/>
|
||||
<page name='Functions'/>
|
||||
<page name='Optional Chaining'/>
|
||||
<page name='Enumerations'/>
|
||||
<page name='Classes'/>
|
||||
<page name='Class Properties'/>
|
||||
<page name='Polymorphism'/>
|
||||
</pages>
|
||||
</playground>
|
|
@ -1,3 +0,0 @@
|
|||
import UIKit
|
||||
|
||||
var str = "Hello, playground"
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='ios' executeOnSourceChanges='false'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
|
@ -0,0 +1,91 @@
|
|||
<img src="/logo.png" width="1000">
|
||||
|
||||
#### My project portfolio from following along with the book [Hacking With Swift](https://www.hackingwithswift.com/read).
|
||||
|
||||

|
||||
|
||||
|
||||
### Beginner 📕
|
||||
|
||||
| # | Project | Topics Learned | Progress |
|
||||
| :--: | :--------------------------: | :--------------: | :--------: |
|
||||
| 0 | 🛠<br>[Introduction to Swift](/00-Introduction-to-Swift) | Playgrounds, Constants & Variables, Data Types, Operators, String Interpolation, Arrays & Dictionaries, Conditional Statements, Control Flow, Functions & Methods, Optionals, Enumerations, Classes & Structures, Property Observers, Access Control, Typecasting, Closures | 🔴 |
|
||||
| 1 | 📱<br>[Storm Viewer](/01-Storm-Viewer) | Xcode, UIKit, UIViewController, `super`, viewDidLoad(), FileManager, Bundle, `try-catch` Blocks, print(), Storyboards & Interface Builder, UITableView, UITableViewDelegate, UITableViewDataSource, UIImageView, UIImage, UIButton, Auto Layout, Outlets & Actions, UINavigationController | 🔴 |
|
||||
| 2 | 🕹<br>[Guess the Flag](/02-Guess-the-Flag) | UIButton, Asset Catalogs, Retina displays & @2x and @3x images, UIControlState, CALayer, UIView, UIColor, CGColor, Random Numbers, UIAlertController, UIAlertAction, UILabel | 🔴 |
|
||||
| 3 | 🛠 [Social Media](/03-Social-Media) | UIActivityViewController, UINavigationBar, UIBarButtonItem, `#selector` & `@objc`, Info.plist, Privacy & Permissions | 🔴 |
|
||||
| 4 | 📱<br>[Easy Browser](/04-Easy-Browser) | WKWebView, URL, URLRequest, UIToolbar, UIProgressView, KVO Design Pattern, WKNavigationDelegate | 🔴 |
|
||||
| 5 | 🕹<br>[Word Scramble](/05-Word-Scramble) | String Methods, NSRange, UITextChecker, lowercased(), IndexPath | 🔴 |
|
||||
| 6 | 🛠<br>[Auto Layout](/06-Auto-Layout) | Ctrl-drag, Visual Format Language | 🔴 |
|
||||
| 7 | 📱<br>[WH Petitions](/07-White-House-Petitions) | UITabBarController, Parsing JSON, SwiftyJSON didFinishLaunchingWithOptions | 🔴 |
|
||||
| 8 | 🕹<br>[Seven Swifty Words](/08-Seven-Swifty-Words) | addTarget(), enumerated(), index(of:), joined(), replacingOccurrences(), Property Observers, Range Operators | 🔴 |
|
||||
| 9 | 🛠<br>[Grand Central Dispatch](/09-Grand-Central-Dispatch) | async(), DispatchQueue.main, Quality of Service, global(), performSelector(inBackground:) | 🔴 |
|
||||
| 10 | 📱<br>[Names to Faces](/10-Names-to-Faces) | UICollectionView, UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UIImagePickerController, UUID, Custom NSObject Classes | 🔴 |
|
||||
| 11 | 🕹<br>[Peggle](/11-Peggle) | CGFloat, SKSpriteNode, UITouch, SKPhysicsBody, circleOfRadius, SKPhysicsContactDelegate, SKLabelNode, SKEmitterNode | 🔴 |
|
||||
| 12 | 🛠<br>[User Defaults](/12-User-Defaults) | NSCoding, Codable | 🔴 |
|
||||
| 13 | 📱<br>[Instafilter](/13-Instafilter) | UISlider, CIContext, CIFilter | 🔴 |
|
||||
| 14 | 🕹<br>[Whack-a-Penguin](/14-Whack-a-Penguin) | SKCropNode, SKTexture, SKActions, asyncAfter() | 🔴 |
|
||||
| 15 | 🛠<br>[Core Animation](/15-Animation) | `switch`, `case`, animate(withDuration:), CGAffineTransform, CGFloat.pi | 🔴 |
|
||||
|
||||
### Intermediate 📗
|
||||
|
||||
| # | Project Name | Topics Learned | Progress |
|
||||
| :--: | :-------------------------: | :------------: | :------: |
|
||||
| 16 | 📱<br>[JavaScript Injection](/16-JavaScript-Injection) | NSExtensionItem, plists, NSDictionary, UITextView, NSItemProvider, kUTTypePropertyList, Keyboard Notifications, NSValue, CGRect, CGPoint, CGSize, UIEdgeInsets | 🔴 |
|
||||
| 17 | 🕹<br>[Fruity Penguins](/17-Fruity-Penguins) | SKShapeNode, CGPath, UIBezierPath, AVAudioPlayer, CaseIterable & Custom Enums, Default Method Parameters | 🔴 |
|
||||
| 18 | 🛠<br>[Debugging](/18-Debugging) | `print`, `assert`, breakpoints, Visual Debugging | 🔴 |
|
||||
| 19 | 📱<br>[Capital Cities](/19-Capital-Cities) | MKMapView, MKAnnotation, MKPinAnnotationView, CLLocationCoordinate2D, dequeueReusableAnnotationView() | 🔴 |
|
||||
| 20 | 🕹<br>[Fireworks Night](/20-Fireworks-Night) | Timer, SKNode, follow(), motionBegan(), prefersStatusBarHidden, Timer.invalidate() | 🔴 |
|
||||
| 21 | 🛠<br>[Local Notifications](/21-Local-Notifications) | UNUserNotificationCenter, UNNotificationRequest, UNNotificationAction, UNNotificationCategory, UNUserNotificationCenterDelegate, UNNotificationDefaultActionIdentifier | 🔴 |
|
||||
| 22 | 📱<br>[Detect-A-Beacon](/22-Detect-A-Beacon) | Core Location, CLBeaconRegion, CLLocationManager, startMonitoring(for:), startRangingBeacons(in:), `uuidgen`, CLBeaconRegion, CLProximity | 🔴 |
|
||||
| 23 | 🕹<br>[Space Race](/23-Space-Race) | Per-Pixel Collision Detection, Advancing Particle Systems, Adjust Linear & Angular Damping, touchesEnded(), touchesMoved(), touchesBegan() | 🔴 |
|
||||
| 24 | 🛠<br>[Swift Extensions](/24-Swift-Extensions/SwiftExtensions.playground) | `mutating`, Protocol-Oriented Programming, Methods as Verbs, Properties as State, ExSwift | 🔴 |
|
||||
| 25 | 📱<br>[Selfie Share](/25-Selfie-Share) | MCSession, MCBrowswerViewController, showConnectionPrompt(), MCPeerID, MCAdvertiserAssistant, MCSessionDelegate, MCBrowserViewControllerDelegate, Data, data(using:), String.Encoding.utf8 | 🔴 |
|
||||
| 26 | 🕹<br>[Marble Maze](/26-Marble-Maze) | categoryBitMask, collisionBitMask, contactTestBitMask, CMMotionManager, update() | 🔴 |
|
||||
| 27 | 🛠<br>[Core Graphics](/27-Core-Graphics) | UIGraphicsImageRenderer, UIGraphicsImageRendererContext, CGContext, addRect(), addEllipse(), String.draw(with:), UIFont, NSMutableParagraphStyle() | 🔴 |
|
||||
| 28 | 📱<br>[Secret Swift](/28-Secret-Swift) | KeychainWrapper, resignFirstResponder(), NotificationCenter, UIApplication.willResignActiveNotification, LocalAuthentication, LAContext, canEvaluatePolicy(), .deviceOwnerAuthenticationWithBiometrics, evaluatePolicy(), `[unowned self]`, `self`, Privacy for Touch ID & Face ID | 🔴 |
|
||||
| 29 | 🕹<br>[Exploding Monkeys](/29-Exploding-Monkeys) | UIKit + SpriteKit, Texture Atlases, Scene Transitions, Destructable Terrain | 🔴 |
|
||||
| 30 | 🛠<br>[Instruments](/30-Instruments) | TimeProfiler, Color Blended Layers, Color Offscreen-Rendered Yellow, Color Hits Green and Misses Red | 🔴 |
|
||||
|
||||
## Advanced 📘
|
||||
|
||||
| # | Project Name | Topics Learned | Progress |
|
||||
| :--: | :-------------------------: | :--------------: | :--------: |
|
||||
| 31 | 📱<br>[Multibrowser](/31-Multibrowser) | UIStackView, iPad Multitasking, addArrangedSubview(), WKNavigationDelegate, UITextFieldDelegate, UIGestureRecognizerDelegate, App Transport Security | 🔴 |
|
||||
| 32 | 📱<br>[Swift Searcher](/32-Swift-Searcher) | Dynamic Type, NSAttributedString, SFSafariViewController, SFSafariViewControllerDelegate, Core Spotlight, UIContentSizeCategoryDidChange | 🔴 |
|
||||
| 33 | 📱<br>[Name That Tune](/33-Name-that-Tune) | AVAudioRecorder, AVAudioSession, requestRecordPermission(), CloudKit, CKRecord, CKAsset, CloudKit Dashboard, CKQueryOperation, NSPredicate, CKRecord.Reference, fetch(withRecordID:), save(), CKQuerySubscription, NSSortDescriptor | 🔴 |
|
||||
| 34 | 🕹<br>[Four in a Row](/34-Connect-Four) | GameplayKit AI, GKGameModel, GKGameModelPlayer, GKGameModelUpdate, AI Heuristics, NSCopying, GKMinmaxStrategist | 🔴 |
|
||||
| 35 | 🛠<br>[Random Numbers](/35-Random-Numbers) | Int.random(in:), Float.random(in:), Double.random(in:), CGFloat.random(in:), Bool.random(), arc4random(), GKRandomSource.sharedRandom(), GKLinearCongruentialRandomSource, GKMersenneTwisterRandomSource, GKARC4RandomSource, GKRandomDistribution, GKShuffledDistribution, GKGaussianDistribution, Fisher-Yates Algorithm, arrayByShufflingObjects(in:) | 🔴 |
|
||||
| 36 | 🕹<br>[Crashy Plane](/36-Crashy-Plane) | Composed Methods, Scale Modes, Parallax Scrolling, SpriteKit Physics, SKPhysicsContactDelegate, SKPhysicsBody, SKAudioNode, Managing Game State | 🔴 |
|
||||
| 37 | 🕹<br>[Psychic Tester](/37-Psychic-Tester) | WatchKit Extensions, 3D Touch, CAEmitterLayer, CAGradientLayer, @IBDesignable, @IBInspectable, transition(with:), WCSession, WKInterfaceLabel, WKInterfaceButton | 🔴 |
|
||||
| 38 | 🛠<br>[Github Commits (Core Data)](/38-GitHubCommits) | NSFetchRequest, NSManagedObject, NSPredicate, NSSortDescriptor, NSFetchedResultsController, ISO8601DateFormatter | 🔴 |
|
||||
| 39 | 🛠<br>[Unit testing with XCTest](/39-Swift-Unit-Tests) | XCTest, `filter()`, Test-Driven Development, Functional Programming, XCTestCase, Setting a Baseline, NSCountedSet, XCUIApplication(), XCUIElementQuery, UI Test Recording | 🔴 |
|
||||
|
||||
## Challenges 📙
|
||||
|
||||
| # | Project Name | Progress |
|
||||
| :--: | :--------------------------: | :------: |
|
||||
| 0 | 🛠<br>[Fizz Buzz](/C00-Fizz-Buzz-Test) | 🔴 |
|
||||
| 1 | 📱<br>[Shopping List](/C01-Shopping-List) | 🔴 |
|
||||
| 2 | 📱<br>[World Flags](/C02-World-Flags) | 🔴 |
|
||||
| 3 | 🕹<br>[Hangman](/C03-Hangman) | 🔴 |
|
||||
| 4 | 🛠<br>[Storm Viewer v2.0](/C04-Storm-Viewer-v2.0) | 🔴 |
|
||||
| 5 | 📱<br>[World Facts](/C05-World-Facts) | 🔴 |
|
||||
| 6 | 📱<br>[Apple Notes Clone](/C06-Apple-Notes-Clone) | 🔴 |
|
||||
| 7 | 🕹<br>[Target Practice](/C07-Target-Practice) | 🔴 |
|
||||
| 8 | 🛠<br>[Swift Extensions](/C08-Swift-Extensions) | 🔴 |
|
||||
| 9 | 🛠<br>[Core Graphics Rainbow](/C09-Core-Graphics-Rainbow) | 🔴 |
|
||||
| 10 | 📱<br>[Private Photos](/C10-Private-Photos) | 🔴 |
|
||||
|
||||
## Certificate of Completion 🎓
|
||||
|
||||
<img src="/certificate.jpg" width="500">
|
||||
|
||||
| KEY |
|
||||
| ----- |
|
||||
📱 = App
|
||||
🕹 = Game
|
||||
🛠 = Technique
|
||||
✅ = Complete
|
||||
🚧 = In Progress
|
||||
🛑 = Not Started
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 483 KiB |
Loading…
Reference in New Issue