diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5a53944
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,22 @@
+# Mac hidden files
+.DS_Store
+.Trashes
+
+# vim
+*.swp
+
+### Xcode ###
+build/
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+xcuserdata
+*.xccheckout
+*.moved-aside
+DerivedData
+*.xcuserstate
diff --git a/10. Properties.playground/section-1.swift b/10. Properties.playground/Contents.swift
similarity index 87%
rename from 10. Properties.playground/section-1.swift
rename to 10. Properties.playground/Contents.swift
index e63507f..40c9e17 100644
--- a/10. Properties.playground/section-1.swift
+++ b/10. Properties.playground/Contents.swift
@@ -4,7 +4,7 @@
// * Properties store values in classes, structures and enumerations.
// ------------------------------------------------------------------------------------------------
-// Here's a structure with a couple simple stored properties:
+// Here's a structure with a couple of simple stored properties:
struct FixedLengthRange
{
var firstValue: Int
@@ -33,39 +33,48 @@ rangeOfThreeItems.firstValue = 6
// Global and local variables are all lazy, except that they don't need the lazy attribute.
//
// Here, we'll define a couple classes to showcase Lazy Stored Properties. In this example, let's
-// assume that DataImporter is a time-consuming process, and as such, we will want to use a lazy
+// assume that DataImporter has a time-consuming process to fetch text, so we will want to use a lazy
// stored property whenever we use it. This way, if we end up never using it, we never pay the
-// penalty of instantiating it.
+// penalty of instantiating it and running the time-consuming import.
class DataImporter
{
- var filename = "data.txt"
+ init() {
+ print("importing text")
+ }
+}
+
+class Something
+{
+ init() {
+ print("doing some thing")
+ }
}
class DataManager
{
- lazy var importer = DataImporter()
- var data = [String]()
+ lazy var imported = DataImporter()
+ var data = [String]()
+ var thing = Something()
}
// Now let's instantiate the data manager and add some simple data to the class:
let manager = DataManager()
manager.data.append("Some data")
manager.data.append("Some more data")
+print("manager loaded")
-// Notice how we haven't used the importer yet, so it is nil:
-manager
+// Notice before we used the importer, "doing some thing" was printed as soon as we created the DataManager()
+// illustrating that normal variables are instantiated running all associated code. Then "manager loaded" is
+// printed before "importing text" which shows that we can use an instance of a class without causing the
+// lazy variables to evaluate
+manager.imported
-// So now let's access it:
-manager.importer.filename
-
-// And now we see the importer was created:
-manager
// ------------------------------------------------------------------------------------------------
// Computed Properties
//
// Computed properties don't store data, but rather use getters and setters for accessing values
-// that are computed up on request.
+// that are computed upon request.
//
// Computed Properties are available for global as well as local variables.
//
@@ -74,6 +83,7 @@ struct Point
{
var x = 0.0, y = 0.0
}
+
struct Size
{
var width = 0.0, height = 0.0
@@ -81,23 +91,24 @@ struct Size
// The following structure includes a computed property with a Point type named 'center'. Notice
// that 'center' is variable (not constant) which is a requirement of computed properties.
-//
-// Every computed property must have a getter, but does not need a setter. If we provide a setter,
-// we need to know the new value being assigned to the computed property. We've called this
-// value 'newCenter'. Note that this value does not have a type annotation because the computed
-// property already knows that it is a Point type. Providing a type annotation would be an error.
struct Rect
{
var origin = Point()
var size = Size()
var center: Point
{
+ // Every computed property must have a getter
get
{
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
+ // Setters are optional. In this case, we provide one.
+ // It needs to accept the new value being assigned to the computed property.
+ // We've called this value 'newCenter'.
+ // Note the missing type annotation. The computed property already knows that
+ // it is a Point type. Providing a type annotation would be an error.
set(newCenter)
{
origin.x = newCenter.x - (size.width / 2)
@@ -113,12 +124,17 @@ var square = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height:
// property, we can treat it just like any other peroperty.
let initialSquareCenter = square.center
+// We can see it has been comuputed as 5,5
+square.center.x
+square.center.y
+
// Since we provided a setter, we can also set the center point as if it is a stored property.
// This will effectively update the Rect's origin and size based on the specified center point.
square.center = Point(x: 15, y: 15)
// We can see that the origin has been updated from (0, 0) to (10, 10):
-square.origin
+square.origin.x
+square.origin.y
// Shorthand Setter Declaration
//
@@ -299,3 +315,5 @@ class SomeClass
class var computedTypeProperty: Int { return 4 }
}
+
+
diff --git a/10. Properties.playground/contents.xcplayground b/10. Properties.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/10. Properties.playground/contents.xcplayground
+++ b/10. Properties.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/10. Properties.playground/playground.xcworkspace/contents.xcworkspacedata b/10. Properties.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/10. Properties.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/10. Properties.playground/timeline.xctimeline b/10. Properties.playground/timeline.xctimeline
index 48b1d0d..6b7c0c1 100644
--- a/10. Properties.playground/timeline.xctimeline
+++ b/10. Properties.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=10655&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472690804.766552"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/11. Methods.playground/section-1.swift b/11. Methods.playground/Contents.swift
similarity index 89%
rename from 11. Methods.playground/section-1.swift
rename to 11. Methods.playground/Contents.swift
index bbe6559..4741d3b 100644
--- a/11. Methods.playground/section-1.swift
+++ b/11. Methods.playground/Contents.swift
@@ -28,14 +28,14 @@ class SomeClass
//
// For methods, the default behavior is that the caller must always specify all but the first
// external parameter name when calling the method. Member authors need not specify the external
-// names for those parameters as the default is to treat all parameters as if they had the "#"
-// specifier, which creates an external parameter name that mirrors the local parameter name.
+// names for those parameters as the default with an external parameter name that mirrors
+// the local parameter name.
//
// To override this default-external-names-for-second-and-beyond-parameters, specify an "_" as the
// external parameter name for all but the first parameter.
//
-// If you want the caller to also use external name for the first parameter, be sure to add your
-// own '#' symbol to the local name or specify the external name explicitly.
+// If you want the caller to also use external name for the first parameter, be sure to 'double up'
+// the local name specifying the external name explicitly.
//
// Here's a class that exercises the various combinations of internal and external name usages:
class Counter
@@ -77,10 +77,10 @@ class Counter
count += second
}
- // Two parameters. Using the external parameter shorthand ("#") to force caller to use
- // external parameter name on first parameter and defaulting to shared local/external names
+ // Two parameters. Require caller to use external parameter name on first parameter
+ // and default to shared local/external names on the second.
// for the rest.
- func addTwiceWithExternalSpecified2(#first: Int, second: Int)
+ func addTwiceWithExternalSpecified2(first first: Int, second: Int)
{
count += first
count += second
@@ -143,7 +143,7 @@ let fixedPoint = Point2(x: 3)
//
// fixedPoint.setX(4)
-// If you're working with a structure or enumeration (not a class), uou can assign to 'self'
+// If we're working with a structure or enumeration (not a class), we can assign to 'self'
// directly
struct Point3
{
diff --git a/11. Methods.playground/contents.xcplayground b/11. Methods.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/11. Methods.playground/contents.xcplayground
+++ b/11. Methods.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/11. Methods.playground/playground.xcworkspace/contents.xcworkspacedata b/11. Methods.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/11. Methods.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/11. Methods.playground/timeline.xctimeline b/11. Methods.playground/timeline.xctimeline
index f894cb8..07b563d 100644
--- a/11. Methods.playground/timeline.xctimeline
+++ b/11. Methods.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=6194&EndingColumnNumber=5&EndingLineNumber=8&StartingColumnNumber=4&StartingLineNumber=8&Timestamp=472691471.401266"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/12. Subscripts.playground/section-1.swift b/12. Subscripts.playground/Contents.swift
similarity index 100%
rename from 12. Subscripts.playground/section-1.swift
rename to 12. Subscripts.playground/Contents.swift
diff --git a/12. Subscripts.playground/contents.xcplayground b/12. Subscripts.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/12. Subscripts.playground/contents.xcplayground
+++ b/12. Subscripts.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/12. Subscripts.playground/playground.xcworkspace/contents.xcworkspacedata b/12. Subscripts.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/12. Subscripts.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/12. Subscripts.playground/timeline.xctimeline b/12. Subscripts.playground/timeline.xctimeline
index a9e94f0..6658b69 100644
--- a/12. Subscripts.playground/timeline.xctimeline
+++ b/12. Subscripts.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=2316&EndingColumnNumber=5&EndingLineNumber=15&StartingColumnNumber=4&StartingLineNumber=15&Timestamp=424368933.017819"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/13. Inheritance.playground/section-1.swift b/13. Inheritance.playground/Contents.swift
similarity index 98%
rename from 13. Inheritance.playground/section-1.swift
rename to 13. Inheritance.playground/Contents.swift
index b17743d..5d84e05 100644
--- a/13. Inheritance.playground/section-1.swift
+++ b/13. Inheritance.playground/Contents.swift
@@ -141,14 +141,14 @@ automaticCar.speed = 35.0
automaticCar.gear
// ------------------------------------------------------------------------------------------------
-// Preenting Overrides
+// Preventing Overrides
//
// We can prevent a subclass from overriding a particular method or property using the 'final'
// keyword.
//
// final can be applied to: class, var, func, class methods and subscripts
//
-// Here, we'll prevent an entire class from being subclassed by applying the . Because of this,
+// Here, we'll prevent an entire class from being subclassed by applying final to the class. Therefore,
// the finals inside the class are not needed, but are present for descriptive purposes. These
// additional finals may not compile in the future, but they do today:
final class AnotherAutomaticCar: Car
diff --git a/13. Inheritance.playground/contents.xcplayground b/13. Inheritance.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/13. Inheritance.playground/contents.xcplayground
+++ b/13. Inheritance.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/13. Inheritance.playground/timeline.xctimeline b/13. Inheritance.playground/timeline.xctimeline
index 23147a5..c4c8a8f 100644
--- a/13. Inheritance.playground/timeline.xctimeline
+++ b/13. Inheritance.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=4439&EndingColumnNumber=5&EndingLineNumber=7&StartingColumnNumber=4&StartingLineNumber=7&Timestamp=472755223.513943"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/14a. Initialization.playground/section-1.swift b/14a. Initialization.playground/Contents.swift
similarity index 91%
rename from 14a. Initialization.playground/section-1.swift
rename to 14a. Initialization.playground/Contents.swift
index 8638c0a..9e1f783 100644
--- a/14a. Initialization.playground/section-1.swift
+++ b/14a. Initialization.playground/Contents.swift
@@ -67,7 +67,7 @@ let freezingPointOfWater = Celsius(kelvin: 273.15)
// name generation and one that opts out:
struct Color
{
- let red = 0.0, green = 0.0, blue = 0.0
+ var red = 0.0, green = 0.0, blue = 0.0
// This initializer will make use of automatically generated exernal names
init(red: Double, green: Double, blue: Double)
@@ -116,7 +116,7 @@ class SurveyQuestion
class SurveyQuestion2
{
// Default value of "No question"
- let text: String = "No question"
+ var text: String = "No question"
var response: String?
@@ -148,14 +148,7 @@ let beetsQuestion = SurveyQuestion2(text: "Do you like beets?")
// ------------------------------------------------------------------------------------------------
// Default Initializer
//
-// If all properties have default values (including optionals defaulting to nil) AND you do not
-// create your own initlializer AND there is no superclass, Swift will create a default
-// initializer (with no parameters) for you. This initializer sets all properties to their
-// default values.
-//
-// If you create your own initializer, Swift will not create the default initializer. If you want
-// your custom initializers as well as the default initializer, then put your initializers in an
-// extension.
+// Swift sets all properties to their default values even if you don't have an initializer.
class ShoppingListItem
{
var name: String?
@@ -165,6 +158,25 @@ class ShoppingListItem
// No init(...) initializer
}
+ShoppingListItem().quantity
+
+// If you have an initializer, default values are set before your initializer executes.
+
+class ShoppingListItem2
+{
+ var name: String?
+ var quantity = 1
+ var purchased = false
+
+ init()
+ {
+ print("ShoppingListItem2: by default quantity = \(quantity)")
+ }
+}
+
+ShoppingListItem2()
+
+
// ------------------------------------------------------------------------------------------------
// Memberwise Initializers for Structure Types
//
diff --git a/14a. Initialization.playground/contents.xcplayground b/14a. Initialization.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/14a. Initialization.playground/contents.xcplayground
+++ b/14a. Initialization.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/14a. Initialization.playground/playground.xcworkspace/contents.xcworkspacedata b/14a. Initialization.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/14a. Initialization.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/14a. Initialization.playground/timeline.xctimeline b/14a. Initialization.playground/timeline.xctimeline
index 152e9b8..fbb9860 100644
--- a/14a. Initialization.playground/timeline.xctimeline
+++ b/14a. Initialization.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=7046&EndingColumnNumber=5&EndingLineNumber=9&StartingColumnNumber=4&StartingLineNumber=9&Timestamp=472756414.167895"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/14b. Initializer Chaining.playground/section-1.swift b/14b. Initializer Chaining.playground/Contents.swift
similarity index 92%
rename from 14b. Initializer Chaining.playground/section-1.swift
rename to 14b. Initializer Chaining.playground/Contents.swift
index d4ed131..9f4e058 100644
--- a/14b. Initializer Chaining.playground/section-1.swift
+++ b/14b. Initializer Chaining.playground/Contents.swift
@@ -32,20 +32,28 @@ class Food
// There can be more than one of these, but the fewer the better, usually, design-wise.
init(name: String)
{
+ print("init Food")
self.name = name
}
// Here, we'll use a convenience initializer to initialize 'name' to an unnamed Food
convenience init()
{
+ print("convenience Food")
// Must call the designated in same class
self.init(name: "[unnamed]")
}
}
// Here we make use of our two initializers
+// check out the console below to see how initializers are called
+print("-- namedMeat")
let namedMeat = Food(name: "Bacon")
+namedMeat.name
+
+print("-- mysteryMeat")
let mysteryMeat = Food()
+mysteryMeat.name
// ------------------------------------------------------------------------------------------------
// Two-Phase Initialization
@@ -81,6 +89,7 @@ class RecipeIngredient: Food
// This is a designated initializer (because it has no 'convenience' keyword)
init(name: String, quantity: Int)
{
+ print("init RecipeIngredient")
// We must initialize our new stored properties first (this is Phase 1)
self.quantity = quantity
@@ -97,14 +106,30 @@ class RecipeIngredient: Food
// initializer.
convenience override init(name: String)
{
+ print("convenience RecipeIngredient")
self.init(name: name, quantity: 1)
+ print("\(name) \(quantity)")
}
+
}
// Now we can call our various initializers to see them in action:
+print("-- oneMysteryItem")
+// this will call the convenience initializer for Food since that is the only one with
+// the matching method signature
let oneMysteryItem = RecipeIngredient()
+oneMysteryItem.name
+oneMysteryItem.quantity
+
+print("-- oneBacon")
let oneBacon = RecipeIngredient(name: "Bacon")
+oneBacon.name
+oneBacon.quantity
+
+print("-- sixEggs")
let sixEggs = RecipeIngredient(name: "Eggs", quantity: 6)
+sixEggs.name
+sixEggs.quantity
// ------------------------------------------------------------------------------------------------
// Inheriting a full set of the super's initializers
diff --git a/14b. Initializer Chaining.playground/contents.xcplayground b/14b. Initializer Chaining.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/14b. Initializer Chaining.playground/contents.xcplayground
+++ b/14b. Initializer Chaining.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/14b. Initializer Chaining.playground/playground.xcworkspace/contents.xcworkspacedata b/14b. Initializer Chaining.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/14b. Initializer Chaining.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/14b. Initializer Chaining.playground/timeline.xctimeline b/14b. Initializer Chaining.playground/timeline.xctimeline
index a497a91..806cebd 100644
--- a/14b. Initializer Chaining.playground/timeline.xctimeline
+++ b/14b. Initializer Chaining.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=7452&EndingColumnNumber=5&EndingLineNumber=26&StartingColumnNumber=4&StartingLineNumber=26&Timestamp=429121086.671912"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/15. Deinitialization.playground/section-1.swift b/15. Deinitialization.playground/Contents.swift
similarity index 85%
rename from 15. Deinitialization.playground/section-1.swift
rename to 15. Deinitialization.playground/Contents.swift
index fec04d3..9583adf 100644
--- a/15. Deinitialization.playground/section-1.swift
+++ b/15. Deinitialization.playground/Contents.swift
@@ -64,8 +64,5 @@ Bank.coinsInBank
// When we cause playerOne to be deallocated, the deinitializer is called
playerOne = nil
-// This should print 12000 coins, but the playgrounds don't appear to do
-// this correctly. If you put this code into a project and compile/run
-// it (with minor changes to print variables using println) then you
-// will see that the bank does indeed have 12000 coins.
+// and the 2000 coins are added to the bank
Bank.coinsInBank
diff --git a/15. Deinitialization.playground/contents.xcplayground b/15. Deinitialization.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/15. Deinitialization.playground/contents.xcplayground
+++ b/15. Deinitialization.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/15. Deinitialization.playground/playground.xcworkspace/contents.xcworkspacedata b/15. Deinitialization.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/15. Deinitialization.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/15. Deinitialization.playground/timeline.xctimeline b/15. Deinitialization.playground/timeline.xctimeline
index 96050ff..cc8d4fc 100644
--- a/15. Deinitialization.playground/timeline.xctimeline
+++ b/15. Deinitialization.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=1696&EndingColumnNumber=5&EndingLineNumber=1&StartingColumnNumber=4&StartingLineNumber=1&Timestamp=472848810.775579"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/16. ARC.playground/section-1.swift b/16. ARC.playground/Contents.swift
similarity index 95%
rename from 16. ARC.playground/section-1.swift
rename to 16. ARC.playground/Contents.swift
index e131215..6ba43ed 100644
--- a/16. ARC.playground/section-1.swift
+++ b/16. ARC.playground/Contents.swift
@@ -11,7 +11,7 @@
// for as long as the strong reference remains.
// ------------------------------------------------------------------------------------------------
-// We can't really see ARC in actino within a Playground, but we can still follow along what
+// We can't really see ARC in action within a Playground, but we can still follow along what
// would normally happen.
//
// We'll start by creating a class to work with
@@ -216,8 +216,8 @@ class CreditCard
class Country
{
let name: String
- let capitalCity: City!
-
+ var capitalCity: City!
+
init(name: String, capitalName: String)
{
self.name = name
@@ -255,12 +255,15 @@ var america = Country(name: "USA", capitalName: "Washington DC")
// Customer uses an optional to store a CreditCard. If we look at Country's initializer, we see
// that it initializes a capitalCity by passing 'self' to the City initializer. Normally, an
// initializer cannot reference its own 'self' until it has fully initialized the object. In this
-// case, the Country can access its own 'self' because once 'name' has been initialized, the object
-// is considered fully initialized. This is the case because 'capitalCity' is an optional.
+// case, the Country can access its own 'self' because because once 'name' has been initialized, the object
+// is considered fully initialized. This is the case because 'capitalCity' is an optional, and is
+// implicitly initialized to nil.
+//
+// By declaring 'capitalCity' to be an implicitly unwrapped optional property, we can avoid having
+// to deal with unwrapping 'capitalCity' whenever we want to access it.
//
-// We take this just a step further by declaring 'capitalCity' to be an implicitly unwrapped
-// optinoal property so that we can avoid having to deal with unwrapping 'capitalCity' whenever we
-// want to access it.
+// see detailed discussion here:
+// http://stackoverflow.com/questions/34474545/self-used-before-all-stored-properties-are-initialized
// ------------------------------------------------------------------------------------------------
// Strong Reference Cycles for Closures
@@ -328,7 +331,7 @@ paragraph = nil
// // ... code here ...
// }
//
-// Some closures can used simplified syntax if their parameters are inferred while other closures
+// Some closures can use simplified syntax if their parameters are inferred while other closures
// may not have any parameters. In both cases the method for declaring the capture list doesn't
// change much. Simply include the capture list followed by the 'in' keyword:
//
diff --git a/16. ARC.playground/contents.xcplayground b/16. ARC.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/16. ARC.playground/contents.xcplayground
+++ b/16. ARC.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/16. ARC.playground/playground.xcworkspace/contents.xcworkspacedata b/16. ARC.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/16. ARC.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/16. ARC.playground/timeline.xctimeline b/16. ARC.playground/timeline.xctimeline
index 8e09045..34f29e2 100644
--- a/16. ARC.playground/timeline.xctimeline
+++ b/16. ARC.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=14466&EndingColumnNumber=5&EndingLineNumber=17&StartingColumnNumber=4&StartingLineNumber=17&Timestamp=472854613.688914"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/17. Optional Chaining.playground/section-1.swift b/17. Optional Chaining.playground/Contents.swift
similarity index 100%
rename from 17. Optional Chaining.playground/section-1.swift
rename to 17. Optional Chaining.playground/Contents.swift
diff --git a/17. Optional Chaining.playground/contents.xcplayground b/17. Optional Chaining.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/17. Optional Chaining.playground/contents.xcplayground
+++ b/17. Optional Chaining.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/17. Optional Chaining.playground/playground.xcworkspace/contents.xcworkspacedata b/17. Optional Chaining.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/17. Optional Chaining.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/17. Optional Chaining.playground/timeline.xctimeline b/17. Optional Chaining.playground/timeline.xctimeline
index ef60d48..89e9e6c 100644
--- a/17. Optional Chaining.playground/timeline.xctimeline
+++ b/17. Optional Chaining.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=3488&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=424547375.812189"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/18. Type Casting.playground/section-1.swift b/18. Type Casting.playground/Contents.swift
similarity index 93%
rename from 18. Type Casting.playground/section-1.swift
rename to 18. Type Casting.playground/Contents.swift
index 0d8ce0d..3df9954 100644
--- a/18. Type Casting.playground/section-1.swift
+++ b/18. Type Casting.playground/Contents.swift
@@ -2,11 +2,10 @@
// Things to know:
//
// * Type casting allows us to check the type of an instance and/or treat that instance as a
-// different type from somewhere else in its own hieararchy.
+// different type from somewhere else in its own hierarchy.
//
// * Type casting also allows us to determine if a type conforms to a protocol.
//
-// * Additionally we can create
// ------------------------------------------------------------------------------------------------
// Let's start by creating a few types to work with:
@@ -115,19 +114,19 @@ let someObjects: [AnyObject] =
]
// Here, we know that someObjects[] only contains Movie instances, so we'll use our forced version
-// of the typecast operator, "as". Note, however, that if somebody modifies the code later and adds
+// of the typecast operator: "as!". Note, however, that if somebody modifies the code later and adds
// an instance of a non-Movie type (which they can do), we'll crash. This is why it's important
// to limit our use of AnyObject and Any to only those cases where we absolutely need it.
//
// Let's see how we would use the someObjects array:
for object: AnyObject in someObjects
{
- let movie = object as Movie
+ let movie = object as! Movie
"Movie: '\(movie.name)' was directed by \(movie.director)"
}
// Alternatively, we can downcast the array itself rather than each item:
-var someMovies = someObjects as [Movie]
+var someMovies = someObjects as! [Movie]
for movie in someMovies
{
"Movie: '\(movie.name)' was directed by \(movie.director)"
@@ -135,12 +134,12 @@ for movie in someMovies
// Finally, we can avoid the additional local variable and performt he downcast right inside
// the loop structure:
-for movie in someObjects as [Movie]
+for movie in someObjects as! [Movie]
{
"Movie: '\(movie.name)' was directed by \(movie.director)"
}
-// Any allows us store references to any type at all (not including functions), which can include
+// "Any" allows us store references to any type at all (not including functions), which can include
// integers, floating points, strings or objects.
//
// Let's see this in action. We'll create an array of type Any[] and fill it with random bits and
diff --git a/18. Type Casting.playground/contents.xcplayground b/18. Type Casting.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/18. Type Casting.playground/contents.xcplayground
+++ b/18. Type Casting.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/18. Type Casting.playground/playground.xcworkspace/contents.xcworkspacedata b/18. Type Casting.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/18. Type Casting.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/18. Type Casting.playground/timeline.xctimeline b/18. Type Casting.playground/timeline.xctimeline
index efb6837..72ae2c9 100644
--- a/18. Type Casting.playground/timeline.xctimeline
+++ b/18. Type Casting.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=6471&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472864168.911872"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/19. Nested Types.playground/section-1.swift b/19. Nested Types.playground/Contents.swift
similarity index 96%
rename from 19. Nested Types.playground/section-1.swift
rename to 19. Nested Types.playground/Contents.swift
index e34d5b4..5948733 100644
--- a/19. Nested Types.playground/section-1.swift
+++ b/19. Nested Types.playground/Contents.swift
@@ -83,5 +83,9 @@ struct BlackjackCard
let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)
theAceOfSpades.description
+let theQueenOfDiamonds = BlackjackCard(rank: .Queen, suit: .Diamonds)
+theQueenOfDiamonds.description
+
+
// To access the nested type, we can drill down into the type using type names:
let heartsSymbol = String( BlackjackCard.Suit.Hearts.rawValue )
diff --git a/19. Nested Types.playground/contents.xcplayground b/19. Nested Types.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/19. Nested Types.playground/contents.xcplayground
+++ b/19. Nested Types.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/19. Nested Types.playground/playground.xcworkspace/contents.xcworkspacedata b/19. Nested Types.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/19. Nested Types.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/19. Nested Types.playground/timeline.xctimeline b/19. Nested Types.playground/timeline.xctimeline
index 4d92167..5ebee61 100644
--- a/19. Nested Types.playground/timeline.xctimeline
+++ b/19. Nested Types.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=3150&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472864880.90182"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/1a. The Basics.playground/section-1.swift b/1a. The Basics.playground/Contents.swift
similarity index 91%
rename from 1a. The Basics.playground/section-1.swift
rename to 1a. The Basics.playground/Contents.swift
index 1dd68fd..4469ebd 100644
--- a/1a. The Basics.playground/section-1.swift
+++ b/1a. The Basics.playground/Contents.swift
@@ -56,11 +56,11 @@ let π = 3.14159
let 你好 = "你好世界"
let 🐶🐮 = "dogcow"
-// You can print a value using println
+// You can print a value using print
let fiveHundred = 500
-println("The current value of fiveHundred is: \(fiveHundred)")
+print("The current value of fiveHundred is: \(fiveHundred)")
-// Since we're using Playgrounds, we'll just put the raw string on the line which is an expression
+// Since we're using Playgrounds, we can also put the raw string on the line which is an expression
// that evaluates to itself, printing the result in the right-hand pane in the playground, like so:
"The current value of fiveHundred is: \(fiveHundred)"
@@ -140,11 +140,12 @@ foo1 = 1; foo2 = 2
let meaningOfLife: UInt8 = 42 // Unsigned 8-bit integer
let randomNumber: Int32 = -34 // Signed 32-bit integer
-// There is also Int and UInt, the defaults. These will default to the size of the current
+// There is also Int and UInt, which will default to the size of the current
// platform's native word size. On 32-bit platforms, Int will be equivalent to Int32/UInt32. On
// 64-bit platforms it is equivalent to Int64/UInt64.
//
-// Similarly, there is
+// Note: for interoperability with Cocoa UInt is required. For example the AVFoundation framework
+// uses unsigned integers anywhere a "count" is required
//
// Tip: For code interoperability, prefer Int over its counterparts.
let tirePressurePSI = 52
@@ -190,8 +191,9 @@ let someBool = true
// ------------------------------------------------------------------------------------------------
// Numeric literals
-//
// You can specify numbers in a few interesting ways
+// nice overview: http://www.codingexplorer.com/integers-and-numeric-literals-in-swift/
+// deep explanation: http://nshipster.com/swift-literal-convertible/
let decimalInteger = 17
let binaryInteger = 0b10001 // 17 in binary notation
let octalInteger = 0o21 // ...also 17 (Octal, baby!)
@@ -201,14 +203,21 @@ let hexInteger = 0x11 // ...and 17 in Hexidecimal
// examples (not assigned to variables):
1.25e2 // Scientific notation
1.25e-2
-0xFp2 // Break this down into "0xF", "p", "2". Read as 15 (0xF) to the power of (p) 2, which is 60
-0xFp-2
-0xC.3p0
+15e2
+
+// special hexadecimal power
+0xF
+0xFp2 // 15 * 2^2
+0xFp-2 // 15 * 2^-2 or 15 * 1/4
+
+0xC.3p0 // (12 + 3/16) * 2^0 = 12.1875 * 1
// We can pad our literals as well:
000123.456 // Zero padding
0__123.456 // Underscores are just ignored
+let bigNumber = 14_891_584 // useful for representing 14,891,584 in a more readable way
+
// Numeric type conversion
// A number that won't fit in the given type will not compile
diff --git a/1a. The Basics.playground/contents.xcplayground b/1a. The Basics.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/1a. The Basics.playground/contents.xcplayground
+++ b/1a. The Basics.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/1a. The Basics.playground/playground.xcworkspace/contents.xcworkspacedata b/1a. The Basics.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/1a. The Basics.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/1a. The Basics.playground/timeline.xctimeline b/1a. The Basics.playground/timeline.xctimeline
deleted file mode 100644
index ae188c4..0000000
--- a/1a. The Basics.playground/timeline.xctimeline
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/1b. Type alliases.playground/section-1.swift b/1b. Type alliases.playground/Contents.swift
similarity index 100%
rename from 1b. Type alliases.playground/section-1.swift
rename to 1b. Type alliases.playground/Contents.swift
diff --git a/1b. Type alliases.playground/contents.xcplayground b/1b. Type alliases.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/1b. Type alliases.playground/contents.xcplayground
+++ b/1b. Type alliases.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/1b. Type alliases.playground/playground.xcworkspace/contents.xcworkspacedata b/1b. Type alliases.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/1b. Type alliases.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/1b. Type alliases.playground/timeline.xctimeline b/1b. Type alliases.playground/timeline.xctimeline
deleted file mode 100644
index 74fb0a0..0000000
--- a/1b. Type alliases.playground/timeline.xctimeline
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
diff --git a/1c. Tuples.playground/section-1.swift b/1c. Tuples.playground/Contents.swift
similarity index 51%
rename from 1c. Tuples.playground/section-1.swift
rename to 1c. Tuples.playground/Contents.swift
index 456f8c6..31c58de 100644
--- a/1c. Tuples.playground/section-1.swift
+++ b/1c. Tuples.playground/Contents.swift
@@ -2,6 +2,10 @@
// Things to know:
//
// * Tuples are groups of values combined into a single, compound value
+//
+// Note: Tuples are intended for temporary groups of related values.
+// If your data structure is likely to persist beyond a temporary scope,
+// model it as a class or structure
// ------------------------------------------------------------------------------------------------
// Defining a Tuple - use parenthesis around the comma-delimited list of values
@@ -34,3 +38,42 @@ let namedTuple = (statusCode: 404, message: "Not found")
namedTuple.statusCode == namedTuple.0
namedTuple.message == namedTuple.1
+// Tuples can have any number of elements
+
+var result = (200, "OK", true)
+let (code, message, hasBody) = result
+
+result.dynamicType // the tuple is a new type
+
+// If we are not interested in specific value, we can use an underscore instead of an identifier
+var altResult = (404, "Not Found", false)
+
+
+let (altCode, _, _) = result
+
+// We can't compare tuples like this
+// (5,5) == (5,3)
+
+// but we can use tuples in switch statments
+// example from: https://medium.com/swift-programming/facets-of-swift-part-2-tuples-4bfe58d21abf
+
+var point = (x: 5, y: 5)
+switch point {
+ case (0, 0): // (1)
+ print("Origin")
+ case (_, 0): // (2)
+ print("On x-axis")
+ case (0, _): // (2)
+ print("On y-axis")
+ case let (x, y) where x == y: // (3)
+ print("On 1. diagonal")
+ case let (x, y) where x == -y: // (3)
+ print("On 2. diagonal")
+ case (-1...1, -1...1): // (4)
+ print("Near origin")
+ default: // (5)
+ ()
+}
+
+
+
diff --git a/1c. Tuples.playground/contents.xcplayground b/1c. Tuples.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/1c. Tuples.playground/contents.xcplayground
+++ b/1c. Tuples.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/1c. Tuples.playground/playground.xcworkspace/contents.xcworkspacedata b/1c. Tuples.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/1c. Tuples.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/1d. Optionals.playground/section-1.swift b/1d. Optionals.playground/Contents.swift
similarity index 88%
rename from 1d. Optionals.playground/section-1.swift
rename to 1d. Optionals.playground/Contents.swift
index 5383b35..07f7b49 100644
--- a/1d. Optionals.playground/section-1.swift
+++ b/1d. Optionals.playground/Contents.swift
@@ -9,32 +9,32 @@
// An optional declaration adds a "?" immediately after the explicit type. The following line
// defines a value 'someOptional' that can either hold an Int or no value at all. In this case
-// we set an optional Int value to .None (similar to nil)
-let someOptional: Int? = .None
+// we set an optional Int value to nil
+let someOptional: Int? = nil
// Let's try to convert a String to an Int
//
-// Using the String's toInt() method, we'll try to convert a string to a numeric value. Since not
-// all strings can be converted to an Integer, the toInt() returns an optional, "Int?". This way
+// Using the the Int() initializer method, we'll try to convert a string to a numeric value. Since
+// not every type can be converted to an Integer, the Int() returns an optional, "Int?". This way
// we can recognize failed conversions without having to trap exceptions or use other arcane
// methods to recognize the failure.
//
// Here's an optional in action
let notNumber = "abc"
-let failedConversion = notNumber.toInt()
+let failedConversion = Int(notNumber)
-// Notice how failedConversion is 'nil', even though it's an Int
+// Notice how failedConversion is 'nil', even though we attempted to create an Int
failedConversion
// Let's carry on with a successful conversion
let possibleNumber = "123"
-var optionalConvertedNumber = possibleNumber.toInt()
+var optionalConvertedNumber = Int(possibleNumber)
// This one worked
optionalConvertedNumber
// If we assign it to a constant, the type of that constant will be an Optional Int (Int?)
-let unwrapped = optionalConvertedNumber // 'unwrapped' is another optional
+let unwrapped = optionalConvertedNumber // 'unwrapped' is another optional
// ------------------------------------------------------------------------------------------------
// Alternate syntax for Optionals
@@ -44,8 +44,12 @@ let unwrapped = optionalConvertedNumber // 'unwrapped' is another optional
// let's not let that stop us from learning this little detail.
//
// These two lines are of equivalent types:
-let optionalA: String? = .None
-let optionalB: Optional = .None
+let optionalA: String? = nil
+let optionalB: Optional = nil
+
+// we can inspect their types and see that they are identical
+optionalA.dynamicType
+optionalB.dynamicType
// ------------------------------------------------------------------------------------------------
// Unwrapping
@@ -65,7 +69,7 @@ let unwrappedInt = optionalConvertedNumber!
// Implicit unwrapping isn't very safe because if the optional doesn't hold a value, it will
// generate a runtime error. To verify that is's safe, you can check the optional with an if
// statement.
-if optionalConvertedNumber != .None
+if optionalConvertedNumber != nil
{
// It's now safe to force-unwrap because we KNOW it has a value
let anotherUnwrappedInt = optionalConvertedNumber!
@@ -86,7 +90,7 @@ if let intValue = optionalConvertedNumber
{
// No need to use the "!" suffix as intValue is not optional
intValue
-
+ intValue.dynamicType
// In fact, since 'intValue' is an Int (not an Int?) we can't use the force-unwrap. This line
// of code won't compile:
// intValue!
@@ -104,8 +108,8 @@ if let optionalIntValue:Int? = optionalConvertedNumber
// 'optionalIntValue' is still an optional, but it's known to be safe. We can still check
// it here, though, because it's still an optional. If it weren't optional, this if statement
// wouldn't compile:
- if optionalIntValue != .None
- {
+ if optionalIntValue != nil
+ {
// 'optionalIntValue' is optional, so we still use the force-unwrap here:
"intValue is optional, but has the value \(optionalIntValue!)"
}
@@ -115,7 +119,7 @@ if let optionalIntValue:Int? = optionalConvertedNumber
optionalConvertedNumber = nil
// Now if we check it, we see that it holds no value:
-if optionalConvertedNumber != .None
+if optionalConvertedNumber != nil
{
"optionalConvertedNumber holds a value (\(optionalConvertedNumber))! (this should not happen)"
}
diff --git a/1d. Optionals.playground/contents.xcplayground b/1d. Optionals.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/1d. Optionals.playground/contents.xcplayground
+++ b/1d. Optionals.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/1d. Optionals.playground/playground.xcworkspace/contents.xcworkspacedata b/1d. Optionals.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/1d. Optionals.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/1d. Optionals.playground/timeline.xctimeline b/1d. Optionals.playground/timeline.xctimeline
index ba175f8..659b488 100644
--- a/1d. Optionals.playground/timeline.xctimeline
+++ b/1d. Optionals.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=7065&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472537774.083685"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/1e. Assertions.playground/section-1.swift b/1e. Assertions.playground/Contents.swift
similarity index 99%
rename from 1e. Assertions.playground/section-1.swift
rename to 1e. Assertions.playground/Contents.swift
index 460e628..effdc3f 100644
--- a/1e. Assertions.playground/section-1.swift
+++ b/1e. Assertions.playground/Contents.swift
@@ -14,4 +14,3 @@ assert(age >= 0, "A person's age cannot be negative")
// You can assert without the message
assert(age >= 0)
-
diff --git a/1e. Assertions.playground/contents.xcplayground b/1e. Assertions.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/1e. Assertions.playground/contents.xcplayground
+++ b/1e. Assertions.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/1e. Assertions.playground/playground.xcworkspace/contents.xcworkspacedata b/1e. Assertions.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/1e. Assertions.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/1e. Assertions.playground/timeline.xctimeline b/1e. Assertions.playground/timeline.xctimeline
index bd6221e..8a52c55 100644
--- a/1e. Assertions.playground/timeline.xctimeline
+++ b/1e. Assertions.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=575&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472538012.925907"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/2. Basic operations.playground/section-1.swift b/2. Basic operations.playground/Contents.swift
similarity index 100%
rename from 2. Basic operations.playground/section-1.swift
rename to 2. Basic operations.playground/Contents.swift
diff --git a/2. Basic operations.playground/contents.xcplayground b/2. Basic operations.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/2. Basic operations.playground/contents.xcplayground
+++ b/2. Basic operations.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/2. Basic operations.playground/playground.xcworkspace/contents.xcworkspacedata b/2. Basic operations.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/2. Basic operations.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/2. Basic operations.playground/timeline.xctimeline b/2. Basic operations.playground/timeline.xctimeline
index 9a87e18..c33adda 100644
--- a/2. Basic operations.playground/timeline.xctimeline
+++ b/2. Basic operations.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=3422&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472623487.510823"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/20. Extensions.playground/section-1.swift b/20. Extensions.playground/Contents.swift
similarity index 98%
rename from 20. Extensions.playground/section-1.swift
rename to 20. Extensions.playground/Contents.swift
index 19b54e1..c316698 100644
--- a/20. Extensions.playground/section-1.swift
+++ b/20. Extensions.playground/Contents.swift
@@ -108,7 +108,7 @@ extension Int
{
func repititions(task: () -> ())
{
- for i in 0..
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/20. Extensions.playground/playground.xcworkspace/contents.xcworkspacedata b/20. Extensions.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/20. Extensions.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/20. Extensions.playground/timeline.xctimeline b/20. Extensions.playground/timeline.xctimeline
index 94658f5..4722302 100644
--- a/20. Extensions.playground/timeline.xctimeline
+++ b/20. Extensions.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=5364&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472865268.578316"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/21. Protocols.playground/section-1.swift b/21. Protocols.playground/Contents.swift
similarity index 92%
rename from 21. Protocols.playground/section-1.swift
rename to 21. Protocols.playground/Contents.swift
index 6f1abc6..89cd1a8 100644
--- a/21. Protocols.playground/section-1.swift
+++ b/21. Protocols.playground/Contents.swift
@@ -38,7 +38,7 @@
// * The protocol can also specify if the property must be gettable or gettable and
// settable. If a protocol only requires a gettable property, the conforming class can use
// a stored property or a computed property. Also, the conforming class is allowed to add
-// a setter if it needs.
+// a setter if needed.
//
// * Property requirements are always declared as variable types with the 'var' introducer.
//
@@ -52,9 +52,9 @@ protocol someProtocolForProperties
// A read-only property
var doesNotNeedToBeSettable: Int { get }
- // A type property always uses 'class'. This is the case even if adopted by a structure or
- // enumeration which will use 'static' when conforming to the protocol's property.
- class var someTypeProperty: Int { get set }
+ // A type property always uses 'static'. Even if adopted by a class which may use 'static'
+ // or class when conforming to the protocol's property.
+ static var someTypeProperty: Int { get set }
}
// Let's create a more practical protocol that we can actually conform to:
@@ -235,10 +235,10 @@ extension Hamster: TextRepresentable
// Hamsters and Dice don't have much in common, but in our sample code above, they both conform
// to the TextRepresentable protocol. Because of this, we can create an array of things that are
// TextRepresentable which includes each:
-let textRepresentableThigns: [TextRepresentable] = [d6, tedTheHamster]
+let textRepresentableThings: [TextRepresentable] = [d6, tedTheHamster]
// We can now loop through each and produce its text representation:
-for thing in textRepresentableThigns
+for thing in textRepresentableThings
{
thing.asText()
}
@@ -247,7 +247,7 @@ for thing in textRepresentableThigns
// Protocol Inheritance
//
// Protocols can inherit from other protocols in order to add further requirements. The syntax
-// for this is similar to a class ineriting from its superclass.
+// for this is similar to a class inheriting from its superclass.
//
// Let's create a new text representable type, inherited from TextRepresentable:
protocol PrettyTextRepresentable: TextRepresentable
@@ -313,11 +313,10 @@ wishHappyBirthday(Individual(name: "Bill", age: 31))
// We can use 'is' and 'as' for testing for protocol conformance, just as we've seen in the
// section on Type Casting.
//
-// In order for this to work with protocols, they must be marked with an "@objc" attribute. See
-// further down in this playground for a special note about the @objc attribute.
-//
// Let's create a new protocol with the proper prefix so that we can investigate:
-@objc protocol HasArea
+import Foundation
+
+protocol HasArea
{
var area: Double { get }
}
@@ -329,11 +328,13 @@ class Circle: HasArea
var area: Double { return pi * radius * radius }
init(radius: Double) { self.radius = radius }
}
+
class Country: HasArea
{
var area: Double
init(area: Double) { self.area = area }
}
+
class Animal
{
var legs: Int
@@ -359,13 +360,12 @@ objects[2] is HasArea
// Sometimes it's convenient to declare protocols that have one or more requirements that are
// optional. This is done by prefixing those requirements with the 'optional' keyword.
//
-// The term "optional protocol" refers to protocols that are optional in a very similar since to
+// The term "optional protocol" refers to protocols that are optional in a very similar sense to
// optionals we've seen in the past. However, rather than stored values that can be nil, they
-// can still use optional chaining and optional binding for determining if an optional requirement
+// can use optional chaining and optional binding for determining if an optional requirement
// has been satisfied and if so, using that requirement.
//
-// As with Protocol Conformance, a protocol that uses optional requirements must also be prefixed
-// with the '@objc' attribute.
+// A protocol that uses optional requirements must be prefixed with the '@objc' attribute.
//
// A special note about @objc attribute:
//
@@ -388,7 +388,7 @@ objects[2] is HasArea
// In the class below, we'll see that checking to see if an instance conforms to a specific
// requirement is similar to checking for (and accessing) optionals. We'll use optional chaining
// for these optional reqirements:
-@objc class Counter
+class Counter
{
var count = 0
var dataSource: CounterDataSource?
@@ -400,7 +400,7 @@ objects[2] is HasArea
count += amount
}
// If not, does it conform to the fixedIncrement variable requirement?
- else if let amount = dataSource?.fixedIncrement?
+ else if let amount = dataSource?.fixedIncrement
{
count += amount
}
diff --git a/21. Protocols.playground/contents.xcplayground b/21. Protocols.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/21. Protocols.playground/contents.xcplayground
+++ b/21. Protocols.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/21. Protocols.playground/playground.xcworkspace/contents.xcworkspacedata b/21. Protocols.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/21. Protocols.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/21. Protocols.playground/timeline.xctimeline b/21. Protocols.playground/timeline.xctimeline
index e56777b..c1688ea 100644
--- a/21. Protocols.playground/timeline.xctimeline
+++ b/21. Protocols.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=12837&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472921636.099593"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/22. Generics.playground/section-1.swift b/22. Generics.playground/Contents.swift
similarity index 96%
rename from 22. Generics.playground/section-1.swift
rename to 22. Generics.playground/Contents.swift
index 3bd203c..f6af06a 100644
--- a/22. Generics.playground/section-1.swift
+++ b/22. Generics.playground/Contents.swift
@@ -21,7 +21,7 @@ func swapTwoInts(inout a: Int, inout b: Int)
// What if we wanted to swap Strings? Or any other type? We would need to write a lot of different
// swap functions. Instead, let's use Generics. Consider the following generic function:
-func swapTwoValues(inout a: T, inout b: T)
+func swapTwoValues(inout a: T, inout _ b: T)
{
let tmp = a
a = b
@@ -105,6 +105,15 @@ stackOfStrings.pop()
stackOfStrings.pop()
stackOfStrings.pop()
+
+var intStack = Stack()
+intStack.push(3)
+intStack.push(2)
+intStack.push(1)
+intStack.pop()
+intStack.pop()
+intStack.pop()
+
// ------------------------------------------------------------------------------------------------
// Type constraints
//
@@ -133,9 +142,9 @@ func doSomethingWithKeyValue(someKey: KeyType, som
// element from the array with the value being searched for. By including the Equatable, we tell
// the generic function that it is guaranteed to receive only values that meet that specific
// criteria.
-func findIndex(array: [T], valueToFind: T) -> Int?
+func findIndex(array: [T], _ valueToFind: T) -> Int?
{
- for (index, value) in enumerate(array)
+ for (index, value) in array.enumerate()
{
if value == valueToFind
{
@@ -242,7 +251,7 @@ extension Array: Container {}
// different containers that that must contain the same type of item.
func allItemsMatch
- (someContainer: C1, anotherContainer: C2) -> Bool
+ (someContainer: C1, _ anotherContainer: C2) -> Bool
{
// Check that both containers contain the same number of items
if someContainer.count != anotherContainer.count
diff --git a/22. Generics.playground/contents.xcplayground b/22. Generics.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/22. Generics.playground/contents.xcplayground
+++ b/22. Generics.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/22. Generics.playground/playground.xcworkspace/contents.xcworkspacedata b/22. Generics.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/22. Generics.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/22. Generics.playground/timeline.xctimeline b/22. Generics.playground/timeline.xctimeline
index bcaf52b..bf468af 100644
--- a/22. Generics.playground/timeline.xctimeline
+++ b/22. Generics.playground/timeline.xctimeline
@@ -2,8 +2,5 @@
-
-
diff --git a/23. Advanced Operators.playground/section-1.swift b/23. Advanced Operators.playground/Contents.swift
similarity index 96%
rename from 23. Advanced Operators.playground/section-1.swift
rename to 23. Advanced Operators.playground/Contents.swift
index 30d53d8..ec827d0 100644
--- a/23. Advanced Operators.playground/section-1.swift
+++ b/23. Advanced Operators.playground/Contents.swift
@@ -12,7 +12,7 @@
// ------------------------------------------------------------------------------------------------
// Bitwise Operators
//
-// The Bitwise operators (AND, OR, XOR, etc.) in Swift effeectively mirror the functionality that
+// The Bitwise operators (AND, OR, XOR, etc.) in Swift effectively mirror the functionality that
// you're used to with C++ and Objective-C.
//
// We'll cover them briefly. The odd formatting is intended to help show the results:
@@ -65,9 +65,6 @@ var rightShiftSignedNegativeResult: Int8 = -32 >> 1
// var overflow: Int8 = positive + positive
// var underflow: Int8 = negative + negative
//
-// This is also true for division by zero, which can be caused with the division (/) or remainder
-// (%) operators.
-//
// Sometimes, however, overflow and underflow behavior is exactly what the programmer may intend,
// so Swift provides specific overflow/underflow operators which will not trigger an error and
// allow the overflow/underflow to perform as we see in C++/Objective-C.
@@ -81,8 +78,6 @@ var aZero: Int8 = someValue - someValue
var overflowAdd: Int8 = someValue &+ someValue
var underflowSub: Int8 = -someValue &- someValue
var overflowMul: Int8 = someValue &* someValue
-var divByZero: Int8 = 100 &/ aZero
-var remainderDivByZero: Int8 = 100 &% aZero
// ------------------------------------------------------------------------------------------------
// Operator Functions (a.k.a., Operator Overloading)
@@ -193,7 +188,7 @@ func != (left: Vector2D, right: Vector2D) -> Bool
//
// So far, we've been defining operator functions for operators that Swift understands and
// for which Swift provides defined behaviors. We can also define our own custom operators for
-// doing other interestig things.
+// doing other interesting things.
//
// For example, Swift doesn't support the concept of a "vector normalization" or "cross product"
// because this functionality doesn't apply to any of the types Swift offers.
diff --git a/23. Advanced Operators.playground/contents.xcplayground b/23. Advanced Operators.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/23. Advanced Operators.playground/contents.xcplayground
+++ b/23. Advanced Operators.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/23. Advanced Operators.playground/playground.xcworkspace/contents.xcworkspacedata b/23. Advanced Operators.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/23. Advanced Operators.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/23. Advanced Operators.playground/timeline.xctimeline b/23. Advanced Operators.playground/timeline.xctimeline
index f944334..802f9c5 100644
--- a/23. Advanced Operators.playground/timeline.xctimeline
+++ b/23. Advanced Operators.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=10056&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472943958.423507"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/3. Strings and Characters.playground/section-1.swift b/3. Strings and Characters.playground/Contents.swift
similarity index 80%
rename from 3. Strings and Characters.playground/section-1.swift
rename to 3. Strings and Characters.playground/Contents.swift
index e78b818..58bdd20 100644
--- a/3. Strings and Characters.playground/section-1.swift
+++ b/3. Strings and Characters.playground/Contents.swift
@@ -44,7 +44,7 @@ somefunc(originalString)
originalString // not modified
// You can iterate over a string like this:
-for character in originalString
+for character in originalString.characters
{
character
}
@@ -53,18 +53,10 @@ for character in originalString
// instead of a String:
var notAString: Character = "t"
-// There is no length or count member of string, you have to use the global function,
-// countElements()
-//
+// There is no length or count member of string, you have to count the characters
// This is much like calling strlen in which it iterates over the Unicode string and counts
// characters. Note that Unicode chars are different lenghts, so this is a non-trivial process.
-//
-// “Note also that the character count returned by countElements is not always the same as the
-// length property of an NSString that contains the same characters. The length of an NSString is
-// based on the number of 16-bit code units within the string’s UTF-16 representation and not the
-// number of Unicode characters within the string. To reflect this fact, the length property from
-// NSString is called utf16count when it is accessed on a Swift String value.”
-countElements(originalString)
+originalString.characters.count
// Strings can be concatenated with strings and characters
var helloworld = "hello, " + "world"
diff --git a/3. Strings and Characters.playground/contents.xcplayground b/3. Strings and Characters.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/3. Strings and Characters.playground/contents.xcplayground
+++ b/3. Strings and Characters.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/3. Strings and Characters.playground/playground.xcworkspace/contents.xcworkspacedata b/3. Strings and Characters.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/3. Strings and Characters.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/3. Strings and Characters.playground/timeline.xctimeline b/3. Strings and Characters.playground/timeline.xctimeline
index ceeb430..5a5f3b0 100644
--- a/3. Strings and Characters.playground/timeline.xctimeline
+++ b/3. Strings and Characters.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=2809&EndingColumnNumber=5&EndingLineNumber=9&StartingColumnNumber=4&StartingLineNumber=9&Timestamp=472624180.15893"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/4a. Arrays.playground/section-1.swift b/4a. Arrays.playground/Contents.swift
similarity index 97%
rename from 4a. Arrays.playground/section-1.swift
rename to 4a. Arrays.playground/Contents.swift
index 716b695..b362aa7 100644
--- a/4a. Arrays.playground/section-1.swift
+++ b/4a. Arrays.playground/Contents.swift
@@ -28,6 +28,9 @@ var shorter: [String]
// would get a compiler error.
["Eggs", "Milk"]
+// This causes an error: Type of expression is ambiguous without more context
+// ["Eggs", 4]
+
// Let's create an array with some stuff in it. We'll use an explicit String type:
var commonPets: [String] = ["Cats", "Dogs"]
@@ -89,7 +92,7 @@ for item in shoppingList
// We can also use the the enumerate() method to return a tuple containing the index and value
// for each element:
-for (index, value) in enumerate(shoppingList)
+for (index, value) in shoppingList.enumerate()
{
index
value
diff --git a/4a. Arrays.playground/contents.xcplayground b/4a. Arrays.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/4a. Arrays.playground/contents.xcplayground
+++ b/4a. Arrays.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/4a. Arrays.playground/playground.xcworkspace/contents.xcworkspacedata b/4a. Arrays.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/4a. Arrays.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/4a. Arrays.playground/timeline.xctimeline b/4a. Arrays.playground/timeline.xctimeline
index 69032d4..1f7afb7 100644
--- a/4a. Arrays.playground/timeline.xctimeline
+++ b/4a. Arrays.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=5535&EndingColumnNumber=5&EndingLineNumber=17&StartingColumnNumber=4&StartingLineNumber=17&Timestamp=472626344.554557"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/4b. Dictionaries.playground/contents.xcplayground b/4b. Dictionaries.playground/contents.xcplayground
index 18a12f6..8e39341 100644
--- a/4b. Dictionaries.playground/contents.xcplayground
+++ b/4b. Dictionaries.playground/contents.xcplayground
@@ -4,4 +4,4 @@
-
+
\ No newline at end of file
diff --git a/4b. Dictionaries.playground/playground.xcworkspace/contents.xcworkspacedata b/4b. Dictionaries.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/4b. Dictionaries.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/4b. Dictionaries.playground/section-1.swift b/4b. Dictionaries.playground/section-1.swift
index c901f6c..ec1b6b2 100644
--- a/4b. Dictionaries.playground/section-1.swift
+++ b/4b. Dictionaries.playground/section-1.swift
@@ -64,7 +64,7 @@ var removedValue = airports.removeValueForKey("APL")
// ------------------------------------------------------------------------------------------------
// Iterating over a Dictionary
//
-// We can iterating over key/value pairs with a for-in loop, which uses a Tuple to hold the
+// We can iterate over key/value pairs with a for-in loop, which uses a Tuple to hold the
// key/value pair for each entry in the Dictionary:
for (airportCode, airportName) in airports
{
diff --git a/4b. Dictionaries.playground/timeline.xctimeline b/4b. Dictionaries.playground/timeline.xctimeline
index 372dfbb..c2d5cbc 100644
--- a/4b. Dictionaries.playground/timeline.xctimeline
+++ b/4b. Dictionaries.playground/timeline.xctimeline
@@ -3,10 +3,14 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=4820&EndingColumnNumber=5&EndingLineNumber=16&StartingColumnNumber=4&StartingLineNumber=16&Timestamp=472627871.743832"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
+ documentLocation = "#CharacterRangeLen=11&CharacterRangeLoc=3381&EndingColumnNumber=12&EndingLineNumber=77&StartingColumnNumber=1&StartingLineNumber=77&Timestamp=472626628.711349"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/5. Control Flow.playground/section-1.swift b/5. Control Flow.playground/Contents.swift
similarity index 90%
rename from 5. Control Flow.playground/section-1.swift
rename to 5. Control Flow.playground/Contents.swift
index 75753f2..0ee81d9 100644
--- a/5. Control Flow.playground/section-1.swift
+++ b/5. Control Flow.playground/Contents.swift
@@ -34,32 +34,10 @@ for index in 1 ..< 5
"This will print 4 times"
}
-// Apple's "Swift Programming Language" book states the following, which I find in practice to be
-// incorrect:
-//
-// “The index constant exists only within the scope of the loop. If you want to check the value of
-// index after the loop completes, or if you want to work with its value as a variable rather than
-// a constant, you must declare it yourself before its use in the loop.”
-//
-// In practice, I find that the loop constant overrides any local variable/constant and maintains
-// its scope to the loop and does not alter the locally defined value:
-var indx = 3999
-for indx in 1...5
-{
- indx // This ranges from 1 to 5, inclusive
-
- // 'indx' is still acting like a constant, so this line won't compile:
- //
- // indx++
-}
-
-// After the loop, we find that 'indx' still contains the original value of 3999
-indx
-
// We can use an underscore if you don't need access to the loop constant:
for _ in 1...10
{
- println("do something")
+ print("do something")
}
// We can iterate over arrays
@@ -78,7 +56,7 @@ for (animalName, legs) in numberOfLegs
}
// We can iterate over characters in a String
-for character in "Hello"
+for character in "Hello".characters
{
character
}
@@ -98,7 +76,8 @@ for var index = 0; index < 3; ++index
index
}
-// Variables are scoped to the For-Condition-Increment construct. To alter this, pre-declare index
+// Variables are scoped to the For-Condition-Increment construct.
+// But if pre-declare the loop variable, it is available after the loop completes.
var index = 3000
for index = 0; index < 3; ++index
{
@@ -119,7 +98,7 @@ while index > 0
// Do-While loops also resemble their C-like language counterparts. They perform the condition
// after each iteration through the loop. As a result, they always execute the code inside the
// loop at least once:
-do
+repeat
{
++index
} while (index < 3)
@@ -355,10 +334,11 @@ switch integerToDescribe
// To enable this, labels are used, similar to labels used by C's goto statement.
//
// The following will print each name until it reaches the letter 'a' then skip to the next name
+names
var result = ""
nameLoop: for name in names
{
- characterLoop: for character in name
+ characterLoop: for character in name.characters
{
theSwitch: switch character
{
@@ -373,11 +353,11 @@ nameLoop: for name in names
}
result
-// Similarly, this prints all names without the letter 'a' in them:
+// Similarly, this prints all names skipping the letter 'a' :
result = ""
nameLoop: for name in names
{
- characterLoop: for character in name
+ characterLoop: for character in name.characters
{
theSwitch: switch character
{
@@ -397,7 +377,7 @@ result
result = ""
nameLoop: for name in names
{
- characterLoop: for character in name
+ characterLoop: for character in name.characters
{
theSwitch: switch character
{
diff --git a/5. Control Flow.playground/contents.xcplayground b/5. Control Flow.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/5. Control Flow.playground/contents.xcplayground
+++ b/5. Control Flow.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/5. Control Flow.playground/playground.xcworkspace/contents.xcworkspacedata b/5. Control Flow.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/5. Control Flow.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/5. Control Flow.playground/timeline.xctimeline b/5. Control Flow.playground/timeline.xctimeline
index c1278f9..9023a9b 100644
--- a/5. Control Flow.playground/timeline.xctimeline
+++ b/5. Control Flow.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=10298&EndingColumnNumber=5&EndingLineNumber=2&StartingColumnNumber=4&StartingLineNumber=2&Timestamp=472629553.889058"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/6. Functions.playground/section-1.swift b/6. Functions.playground/Contents.swift
similarity index 91%
rename from 6. Functions.playground/section-1.swift
rename to 6. Functions.playground/Contents.swift
index b281d2d..10550cb 100644
--- a/6. Functions.playground/section-1.swift
+++ b/6. Functions.playground/Contents.swift
@@ -82,12 +82,12 @@ func addSeventeen(toNumber value: Int) -> Int
}
addSeventeen(toNumber: 42)
-// If your internal and external names are the same, you can use a shorthand #name syntax to create
-// both names at once.
+// If your internal and external names are the same, you need to 'double up' to
+// specify both names.
//
// The following declaration creates an internal parameter named "action" as well as an external
// parameter named "action":
-func kangaroosCan(#action: String) -> String
+func kangaroosCan(action action: String) -> String
{
return "A Kangaroo can \(action)"
}
@@ -96,13 +96,23 @@ func kangaroosCan(#action: String) -> String
kangaroosCan(action: "jump")
kangaroosCan(action: "carry children in their pouches")
+// If you want to omit an external name for the second or subsequent parameters of a function,
+// write an underscore (_) instead of an explicit external name for that parameter
+func addNums(first: Int, _ second: Int) -> Int
+{
+ return first + second
+}
+
+addNums(1,2)
+
+
// We can also have default parameter values. Default parameter values must be placed at the end
// of the parameter list.
//
// In the addMul routine, we'll add two numbers and multiply the result by an optional multiplier
// value. We will default the multiplier to 1 so that if the parameter is not specified, the
// multiplication won't affect the result.
-func addMul(firstAdder: Int, secondAdder: Int, multiplier: Int = 1) -> Int
+func addMul(firstAdder: Int, _ secondAdder: Int, multiplier: Int = 1) -> Int
{
return (firstAdder + secondAdder) * multiplier
}
@@ -113,9 +123,8 @@ addMul(1, 2)
// Default parameter values and external names
//
// Swift automatically creates external parameter names for those parameters that have default
-// values. Since our declaration of addMul did not specify an external name (either explicitly or
-// using the shorthand method), Swift created one for us based on the name of the internal
-// parameter name. This acts as if we had defined the third parameter using the "#" shorthand.
+// values. Since our declaration of addMul did not specify an external name, Swift created one
+// for us based on the name of the internal parameter name.
//
// Therefore, when calling the function and specifying a value for the defaulted parameter, we
// must provide the default parameter's external name:
@@ -123,7 +132,7 @@ addMul(1, 2, multiplier: 9)
// We can opt out of the automatic external name for default parameter values by specify an
// external name of "_" like so:
-func anotherAddMul(firstAdder: Int, secondAdder: Int, _ multiplier: Int = 1) -> Int
+func anotherAddMul(firstAdder: Int, _ secondAdder: Int, _ multiplier: Int = 1) -> Int
{
return (firstAdder + secondAdder) * multiplier
}
@@ -167,7 +176,7 @@ arithmeticMean(1, 2, 3, 4, 5, 6)
// If we want to use variadic parameters and default parameter values, we can do so by making sure
// that the default parameters come before the variadic, at the end of the parameter list:
-func anotherArithmeticMean(initialTotal: Double = 0, numbers: Double...) -> Double
+func anotherArithmeticMean(initialTotal initialTotal: Double = 0, _ numbers: Double...) -> Double
{
var total = initialTotal
for number in numbers
@@ -193,7 +202,7 @@ anotherArithmeticMean(initialTotal: 1, 2, 3, 4, 5, 6)
// Variadic parameters with external parameter names only apply their external name to the first
// variadic parameter specified in the function call (if present.)
-func yetAnotherArithmeticMean(initialTotal: Double = 0, values numbers: Double...) -> Double
+func yetAnotherArithmeticMean(initialTotal initialTotal: Double = 0, values numbers: Double...) -> Double
{
var total = initialTotal
for number in numbers
@@ -217,9 +226,9 @@ yetAnotherArithmeticMean(initialTotal: 1, values: 2, 3, 4, 5, 6)
// Constant and variable parameters
//
// All function parameters are constant by default. To make them variable, add the var introducer:
-func padString(var str: String, pad: Character, count: Int) -> String
+func padString(var str: String, _ pad: Character, _ count: Int) -> String
{
- str = Array(count: count, repeatedValue: pad) + str
+ str = String(count:10, repeatedValue:("." as Character)) + str
return str
}
@@ -314,7 +323,7 @@ func doDoMul(doMulFunc: (Int, Int) -> Int, a: Int, b: Int) -> Int
// We can now pass the function (along with a couple parameters to call it with) to another
// function:
-doDoMul(doMul, 5, 5)
+doDoMul(doMul, a: 5, b: 5)
// We can also return function types.
//
@@ -368,7 +377,7 @@ func getReturnFive() -> () -> Int
return returnFive
}
-// Calling outerFunc2 will return a function capable of returning the Int value 5:
+// Calling getReturnFive will return a function capable of returning the Int value 5:
let returnFive = getReturnFive()
// Here we call the nested function:
diff --git a/6. Functions.playground/contents.xcplayground b/6. Functions.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/6. Functions.playground/contents.xcplayground
+++ b/6. Functions.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/6. Functions.playground/playground.xcworkspace/contents.xcworkspacedata b/6. Functions.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/6. Functions.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/6. Functions.playground/timeline.xctimeline b/6. Functions.playground/timeline.xctimeline
index d07a687..f6c1d7b 100644
--- a/6. Functions.playground/timeline.xctimeline
+++ b/6. Functions.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=13327&EndingColumnNumber=5&EndingLineNumber=4&StartingColumnNumber=4&StartingLineNumber=3&Timestamp=472640037.365269"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/7. Closures.playground/section-1.swift b/7. Closures.playground/Contents.swift
similarity index 88%
rename from 7. Closures.playground/section-1.swift
rename to 7. Closures.playground/Contents.swift
index b46fb84..33eabd9 100644
--- a/7. Closures.playground/section-1.swift
+++ b/7. Closures.playground/Contents.swift
@@ -3,7 +3,7 @@
//
// * Closures are blocks of code.
//
-// * The can be passed as parameters to functions much like Function Types. In fact, functions
+// * They can be passed as parameters to functions much like Function Types. In fact, functions
// are a special case of closures.
//
// * Closures of all types (including nested functions) employ a method of capturing the surrounding
@@ -26,7 +26,7 @@
// return s1 < s2
// }
//
-// Here's an example using Swift's 'sorted' member function. It's important to note that this
+// Here's an example using Swift's 'sort' member function. It's important to note that this
// function receives a single closure.
//
// These can be a little tricky to read if you're not used to them. To understand the syntax, pay
@@ -34,7 +34,7 @@
// outside of those curly braces:
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
var reversed = [String]()
-reversed = names.sorted({
+reversed = names.sort({
(s1: String, s2: String) -> Bool in
return s1 > s2
})
@@ -49,7 +49,7 @@ reversed = names.sorted({
// call to sort.
//
// The following call is identical to the one above with the exception that "-> Bool" was removed:
-reversed = names.sorted({
+reversed = names.sort({
(s1: String, s2: String) in
return s1 > s2
})
@@ -59,7 +59,7 @@ reversed = names.sorted({
//
// The following call is identical to the one above with the exception that the parameter type
// annotations (": String") have been removed:
-reversed = names.sorted({
+reversed = names.sort({
(s1, s2) in
return s1 > s2
})
@@ -67,11 +67,11 @@ reversed = names.sorted({
// Since all types can be inferred and we're not using any type annotation on the parameters,
// we can simplify a bit further by removing the paranthesis around the parameters. We'll also put
// it all on a single line, since it's a bit more clear now:
-reversed = names.sorted({ s1, s2 in return s1 > s2 })
+reversed = names.sort({ s1, s2 in return s1 > s2 })
// If the closuere has only a single expression, then the return statement is also inferred. When
// this is the case, the closure returns the value of the single expression:
-reversed = names.sorted({ s1, s2 in s1 > s2 })
+reversed = names.sort({ s1, s2 in s1 > s2 })
// We're not done simplifying yet. It turns out we can get rid of the parameters as well. If we
// remove the parameters, we can still access them because Swift provides shorthand names to
@@ -80,28 +80,28 @@ reversed = names.sorted({ s1, s2 in s1 > s2 })
//
// Here's what that would might like (this will not compile - yet):
//
-// reversed = names.sorted({ s1, s2 in $0 > $1 })
+// reversed = names.sort({ s1, s2 in $0 > $1 })
//
// This won't compile because you're not allowed to use shorthand names if you specify the
// parameter list. Therefore, we need to remove those in order to get it to compile. This makes
// for a very short inline closure:
-reversed = names.sorted({ $0 > $1 })
+reversed = names.sort({ $0 > $1 })
// Interestingly enough, the operator < for String types is defined as:
//
// (String, String) -> Bool
//
-// Notice how this is the same as the closure's type for the sorted() routine? Wouldn't it be
+// Notice how this is the same as the closure's type for the sort() routine? Wouldn't it be
// nice if we could just pass in this operator? It turns out that for inline closures, Swift allows
// exactly this.
//
// Here's what that looks like:
-reversed = names.sorted(>)
+reversed = names.sort(>)
-// If you want to just sort a mutable copy of an array (in place) you can use the sort() method
+// If you want to just sort a mutable copy of an array (in place) you can use the sortInPlace() method
var mutableCopyOfNames = names
-mutableCopyOfNames.sort(>)
+mutableCopyOfNames.sortInPlace(>)
mutableCopyOfNames
@@ -110,18 +110,18 @@ mutableCopyOfNames
//
// Trailing Closures refer to closures that are the last parameter to a function. This special-case
// syntax allows a few other syntactic simplifications. In essence, you can move trailing closures
-// just outside of the parameter list. Swift's sorted() member function uses a trailing closure for
+// just outside of the parameter list. Swift's sort() member function uses a trailing closure for
// just this reason.
//
// Let's go back to our original call to sort with a fully-formed closure and move the closure
// outside of the parameter list. This resembles a function definition, but it's a function call.
-reversed = names.sorted {
+reversed = names.sort {
(s1: String, s2: String) -> Bool in
return s1 > s2
}
// Note that the opening brace for the closure must be on the same line as the function call's
-// ending paranthesis. This is the same functinon call with the starting brace for the closure
+// ending paranthesis. This is the same function call with the starting brace for the closure
// moved to the next line. This will not compile:
//
// reversed = sort(names)
@@ -131,7 +131,7 @@ reversed = names.sorted {
// }
// Let's jump back to our simplified closure ({$0 > $1}) and apply the trailing closure principle:
-reversed = names.sorted {$0 > $1}
+reversed = names.sort {$0 > $1}
// Another simplification: if a function receives just one closure as the only parameter, you can
// remove the () from the function call. First, we'll need a function that receives just one
@@ -155,7 +155,7 @@ returnValue {6}
// The idea of capturing is to allow a closure to access the variables and constants in their
// surrounding context.
//
-// For example, a nested function can access contstans and variables from the function in which
+// For example, a nested function can access contstants and variables from the function in which
// it is defined. If this nested function is returned, each time it is called, it will work within
// that "captured" context.
//
diff --git a/7. Closures.playground/contents.xcplayground b/7. Closures.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/7. Closures.playground/contents.xcplayground
+++ b/7. Closures.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/7. Closures.playground/playground.xcworkspace/contents.xcworkspacedata b/7. Closures.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/7. Closures.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/7. Closures.playground/timeline.xctimeline b/7. Closures.playground/timeline.xctimeline
index 435340c..d9c79fb 100644
--- a/7. Closures.playground/timeline.xctimeline
+++ b/7. Closures.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=7960&EndingColumnNumber=5&EndingLineNumber=14&StartingColumnNumber=4&StartingLineNumber=14&Timestamp=472641698.657649"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/8. Enumerations.playground/section-1.swift b/8. Enumerations.playground/Contents.swift
similarity index 97%
rename from 8. Enumerations.playground/section-1.swift
rename to 8. Enumerations.playground/Contents.swift
index acf994d..0d10f67 100644
--- a/8. Enumerations.playground/section-1.swift
+++ b/8. Enumerations.playground/Contents.swift
@@ -5,7 +5,7 @@
// Rather that containing "one of a set of integer values" like most C-like languages, Swift's
// enumerations can be thought of as holding one named type of a given set of named types.
//
-// To clarify: Rather than holding an integer value that has been pre-defined integer value
+// To clarify: Rather than holding an integer value that has a pre-defined integer value
// (Error = -1, Success = 0) an enumeration in Swift only associates a name with a type (like
// Int, String, Tuple, etc.) These elements of the enumeration can then be assigned "Associated
// Values." For example, an enumeration can store an "Error" which is a Tuple with an Int value
@@ -67,7 +67,7 @@ switch directionToHead
// ------------------------------------------------------------------------------------------------
// Associated Values
//
-// Associated values allows us to store information with each member of the switch using a Tuple.
+// Associated values allows us to store information with each member of the enumeration using a Tuple.
//
// The following enumeration will store not only the type of a barcode (UPCA, QR Code) but also
// the data of the barcode (this is likely a foreign concept for most.)
diff --git a/8. Enumerations.playground/contents.xcplayground b/8. Enumerations.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/8. Enumerations.playground/contents.xcplayground
+++ b/8. Enumerations.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/8. Enumerations.playground/playground.xcworkspace/contents.xcworkspacedata b/8. Enumerations.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/8. Enumerations.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/8. Enumerations.playground/timeline.xctimeline b/8. Enumerations.playground/timeline.xctimeline
index 2e9ebb7..b64a009 100644
--- a/8. Enumerations.playground/timeline.xctimeline
+++ b/8. Enumerations.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=5528&EndingColumnNumber=5&EndingLineNumber=20&StartingColumnNumber=4&StartingLineNumber=20&Timestamp=472642995.567679"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/9. Classes and Structures.playground/section-1.swift b/9. Classes and Structures.playground/Contents.swift
similarity index 100%
rename from 9. Classes and Structures.playground/section-1.swift
rename to 9. Classes and Structures.playground/Contents.swift
diff --git a/9. Classes and Structures.playground/contents.xcplayground b/9. Classes and Structures.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/9. Classes and Structures.playground/contents.xcplayground
+++ b/9. Classes and Structures.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/9. Classes and Structures.playground/playground.xcworkspace/contents.xcworkspacedata b/9. Classes and Structures.playground/playground.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/9. Classes and Structures.playground/playground.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/9. Classes and Structures.playground/timeline.xctimeline b/9. Classes and Structures.playground/timeline.xctimeline
index d16a576..f1b3dfa 100644
--- a/9. Classes and Structures.playground/timeline.xctimeline
+++ b/9. Classes and Structures.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=5563&EndingColumnNumber=5&EndingLineNumber=3&StartingColumnNumber=4&StartingLineNumber=3&Timestamp=424326586.663561"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/99. Not The End.playground/section-1.swift b/99. Not The End.playground/Contents.swift
similarity index 98%
rename from 99. Not The End.playground/section-1.swift
rename to 99. Not The End.playground/Contents.swift
index a5805be..fb00883 100644
--- a/99. Not The End.playground/section-1.swift
+++ b/99. Not The End.playground/Contents.swift
@@ -31,7 +31,7 @@ var pi = 3.14159
assert(pi > 3.14, "Pi is too small")
// Do you know why this compiles?
-func doSomeMagic(#a: Int)(b: Int) -> Int
+func doSomeMagic(a a: Int)(b: Int) -> Int
{
return a + b
}
diff --git a/99. Not The End.playground/contents.xcplayground b/99. Not The End.playground/contents.xcplayground
index 18a12f6..513c2e7 100644
--- a/99. Not The End.playground/contents.xcplayground
+++ b/99. Not The End.playground/contents.xcplayground
@@ -1,7 +1,2 @@
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/99. Not The End.playground/timeline.xctimeline b/99. Not The End.playground/timeline.xctimeline
index 9dfd7db..f65f55c 100644
--- a/99. Not The End.playground/timeline.xctimeline
+++ b/99. Not The End.playground/timeline.xctimeline
@@ -3,7 +3,9 @@
version = "3.0">
+ documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=2503&EndingColumnNumber=5&EndingLineNumber=6&StartingColumnNumber=4&StartingLineNumber=6&Timestamp=472944253.44294"
+ selectedRepresentationIndex = "0"
+ shouldTrackSuperviewWidth = "NO">
diff --git a/README.md b/README.md
index e5ddcf3..893b223 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,9 @@ learn-swift
===========
Learn Apple's Swift programming language interactively through these playgrounds.
+The outline follows Apple's Swift [Language Guide](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/)
+and goes into more detail in some sections with additional examples, and less
+detail in other sections that are likely familiar to an experienced programmer.
###Target Audience
@@ -9,15 +12,14 @@ Learn Apple's Swift programming language interactively through these playgrounds
###What you'll need
- You will need XCode 6.0 GM (or later) or 6.1 Beta 2 (or later) and probably
- a Mac to run it on.
+ You will need XCode 7 (or later) and probably a Mac to run it on.
###Purpose & Goal
More than a primer, these playgrounds are intended to get programmers up to
speed on Swift as fast as possible so they can begin using Swift productively.
- These playgrounds only cover the language. They do not dig into the Swift
+ These playgrounds only cover the language. They do not dig into the Swift
Standard Library or other APIs.
To increase your understanding, you are encouraged to experiment with them