Swift is an object-oriented programming language designed for a complete replacement of both the C and Objective-C, pre-bundled with all of the Cocoa (OS X) and Cocoa Touch (iOS) frameworks.
Less Syntax, More Concepts
Swift Notes
First clicks
- We can mix-n-match the Objective C with Swift
- Swift apps works on iOS 7+ and OSX Mav+
- Swift use same object model as Objective C
- Swift use the same memory management as the Objective C
- XCode auto translate the Objective C headers to Swift headers on its own
- We can create documentations in playgrounds as well
Basics
- Main function not needed because code are written at global scope.
- Use "println()" for logs
- Use "\()" to print variable in logs e.g;
var anyInt = 0; var anyString = ""; var anyDouble = 0.0; println("we can print any kinda var in \(anyVar) \(anyString) \(anyDouble)")
- We don't need to add semicolons if we are not writing in same line, Like above example ^
Constant and Variables
- Use "let" to init a constant and "var" to init a variable.
- We can declare commas separated multiple constants and variables in a single line.
- For constant and variable names we can use any character which not begin with a number, except mathematical symbols, arrows, line- and box-drawing characters
- Swift is a Type safe and Type inference language. All vars can take its type by its initial value, e.g;
let strVar = "" let intVar = 0 let doubleVar = 0.0
- We can define Type aliases with the "typealias" keyword e.g;
typealias nonNegativeShortNumber = UInt8
- We can cast Explicit vars types by adding colon, e.g;
let expStr: String = "70"
- We can cast Optional-Explicit vars by adding question mark, e.g;
var expStr: String? = nil
- We need to place an exclamation mark (!) after an optional value to force the unwrapping of its value
- Tuple (a data structure that has a specific number and sequence of elements) support, e.g;
let http404 = (404, "Internet address cannot be found.") //We can name the individual elements let http200 = (statusCode: 200, description: "OK") //Access code without name and ignore a part of the tuple with an underscore let (code, _) = http404 println("The http200 statusCode is \(http200.statusCode) and http404 code is \(code)")
- We can create arrays and dictionaries using brackets (Swift supports literals) i.e; array as [] and dictionary as [:]
- Dictionary instance is always being copied when assigned to another variable
- Array instance are not being copied when:
- Assigned a constant or variable
- Passed as an argument to a function or method call
- Array is beight copied when:
- We do modify the array’s length
- Force copy with ".copy()" method
- We call the ".unshare()" method
- We can check copy with Identity operators (=== and !==)
- Once a variable is defined with an enum value we can later use only dot "." syntax to chnage the value e.g;
enum CompassPoint { case North; case South; case East; case West } var directionToHead = CompassPoint.West directionToHead = .East
- Lazy Stored Properties is decleared with keyword "@lazy" and its initial value is not calculated until the first time it is used. Its useful when;
- Initial value is dependent on outside factors whose values are not known until after an instance’s initialization is complete
- Initial value requires complex or computationally expensive setup that should not be performed unless or until it is needed
- Initializing a global constants and variables (by default all of globals are Lazy)
Conditions and Loops
- Swift has four loops:
- for
- for-in
- while
- do-while
- Swift has four control transfer statements:
- break
- return
- continue
- fallthrough (its opposite to the break statement, fallthrough is quite usefull in this language because Swift don't need a break statement in switch cases)
- Only boolean expression are supported in if statements, we can use Optional binding i.e;
if let constantName = someOptionalVar { //do some work with constantName } // or we can still treat an implicitly unwrapped optional like a normal optional if someOptionalVar { //do some work with someOptionalVar }
- No need to use brackets in if conditions for single statement
- Switch case don't require the break keyword.
- Switch is powerful enough to handle any kind of data
- Switch case don't support cross datatype check, i.e; "1"==1
- Swicth case supports "where" clause, Value Bindings and Range Matching
- Switch case always need a default case and each case must contain at least one executable statement.
- Switch case support wide variety of comparison operations case including Tuples, e.g;
let somePoint = (1, 1) switch somePoint { case (0, 0): println("(0, 0) is at the origin") case (_, 0): println("(\(somePoint.0), 0) is on the x-axis") case (0, _): println("(0, \(somePoint.1)) is on the y-axis") //demonstrating range matching case (-2...2, -2...2): println("(\(somePoint.0), \(somePoint.1)) is inside the box") //demonstrating where clause and value bindings case let (x, y) where x == y: println("(\(x), \(y)) is on the line x == y") case let (x, y) where x == -y: println("(\(x), \(y)) is on the line x == -y") //demonstrating compulsory default case default: println("(\(somePoint.0), \(somePoint.1)) is outside of the box") }
- We can use .. to make a range, i.e;
let n = 9; for i in 0..n { //this will run 9 times }
Object-Oriented Part
- Swift have very small diffrence between Classes and Structures but they suited to different kinds of tasks. Keep in mind that; Structure instances are passed by value and Class instances are passed by reference
- We can nest enumerations, classes and structures within their definitions. its known as Nested Types
- We can define Functions (which are more like Java Lambda Expressions) with "func" and Closures with "{}" (Closures in Swift are similar to blocks in C and Objective-C) e.g;
let user = { (name: String, age: Int) -> String in return "Name: "+name+", Age: "+String(age); } user("Gaurav", 28)
- Unlike ObjectiveC, External Parameter Names are optional in Swift and it also supports Shorthand External Parameter Names with keyword "#" e.g;
//Function with external parameter names func someFunction(externalParameterName localParameterName: Int){ //externalParameterName is for easy reference and its a good practice to define it in public - multiple param functions } //Same function with shorthand external parameter names func someFunction(#externalParameterName : Int){ //here localParameterName exposed and replaced as externalParameterName with the help of # keyword }
- Functions supports In-Out Parameters (functions that can modify a parameter’s value) with "inout" keyword e.g;
func swapFirstAndLastName(inout fName: String, inout lName: String) { let temp = fName fName = lName lName = temp } var firstName = "Gaurav" var lastName = "Singh" swapFirstAndLastName(&firstName, &lastName)
- Func can have multiple return values as well as multiple param. e.g;
func userPlus(name: String, age: Int, weight: Double) -> (String, Int, Double) { return ("user name: "+name, age + 1, weight + 0.1) }
- Functions supports Variadic Parameters (can also take n number of arguments of same kind) by adding "..." e.g;
func userNames(names: String...) { }
- Functions can be nested, can return a function, can take function as argument and supports Trailing Closures. e.g;
func userData() -> (String, Int, Double) { return ("Guarav", 28, 3.79) } var name: String ? = nil var age: Int = 0 var weight: Double = 0.0 (name, age, weight) = getGasPrices()
- A class can be simply created by using class keyword, it can have multiple init with unique params and a deinit method to perform some tasks while initialization and deinitialization
- We can use the Type check operators to check kind of class, i.e;
- is to check whether an instance is of a certain subclass type or not
- as to force downcasting
- as? to downcast in optional case
- Swift provides Any (for all instances except function types) and AnyObject (for instance of a class only) type aliases for working with non-specific types, its not recommended for often use
- There are two kinds of initializers for class types "Designated initializers (main initializers>) and Convenience initializers (supporting initializers)
- To declear convenience initializers use "convenience" keywork infront of the method e.g;
class User { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[Unnamed]") } } //init with convenience var U = User() //init with designated U = User(name:"Gaurav")
- We can also do memberwise initializers for structure types, e.g;
struct User { var fName = "", lName = "" } let UserName = User(fName: "Gaurav", lName: "Singh")
- Superclass methods should be override using "override"
- We can prevent overrides with "@final" keywork e.g; @final var, @final func, @final class func and @final subscript
- Getter & Setter method are quite interesting and introduced in Swift as "Shorthand Declaration", i.e;
let int = 10 class plusTwo{ var _val: Int = 0 var val: Int { get { //getter method return _val } set { //setter method //the new value has the implicit name newValue _val = newValue + 2 } /* willSet { //code that will run before setting a new value } didSet { //code that will run after setting a new value _val = 0 } */ } init (v: Int) { //init method _val = v; } deinit{ //deinitializer method } } var p2 = plusTwo(v: 0); p2.val = int p2.val //setter will add plus two in the same
- Enum can have methods in them
- Enum value types can be different for each member of the enumeration (its also known as discriminated unions, tagged unions, or variants in other programming languages)
- Use the toRaw and fromRaw functions to convert between the raw value and the enumeration value.
- Classes, enumerations, and structs can all adopt Protocols
- Use "mutating" keyword before a method so that it can modify the properties of the structure or enumeration in future
- ---
- An Extension can be simply declared by "extension" keyword, its more like an class extension or a category without name
- With "extension" keyword we can make an existing type conform to more protocols and add new
- properties
- methods
- initializers
- subscripts and
- nested types
- Generic functions (more like Java Generics) are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters, e.g;
- We can make generic forms "<...>" of functions and methods, as well as classes, enumerations, and structures.
- We can use "where" statement to specify a list of requirements e.g;
- To require the type to implement a protocol
- To require two types to be the same
- To require a class to have a particular superclass
- Subscripts, yet another bingo concept by Swift:
- Classes, structures and enum can define it
- It is shortcut for accessing the member elements of a collection, list or sequence
- You get/set elements in an instance as anObject[index], aDictionary[key], anArray[key]
- Bounced off? e.g:
class HelloUser { let message: String = "" var val = Dictionary
() subscript(key: String) -> String { get { // return an appropriate subscript value here return val[key]! } set { // perform a suitable setting action here val[key] = message+newValue } } init(msg: String){ message = msg } } let hU = HelloUser(msg: "Hello ") hU.message hU["user1"] = "Gaurav" println(hU["user1"]) //this will print "Hello Gaurav" hU["user2"] = "Nikhil" println(hU["user2"]) //this will give "Hello Nikhil"
Post a Comment