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