Notes written while Swift was being released to the world.
Tuesday 3 June 2014, writing my first app:
- At the moment of this writing there is no support for “class” (or “static”) variables (although it seems to work with structs) which makes singletons almost impossible to write
- No optional methods for protocols (only for Objective-C protocols)
- Important point: the standard library. The types defined there are not the same as those from Foundation; the Foundation types can be used very easily, though.
- No need to import files; all symbols are automatically available from every other file in the application.
- “nil” can be used with value types, like Int and others (when optional, that is)
- Type names start with uppercase, always
- In the current version (first Beta after the WWDC) the first parameter of a function call must not have a parameter named specified; all the others must have a parameter name. Apparently it’s a bug.
- Use the “as” keyword to force a return value to have a certain type. This information is used by the compiler. The variable type is not taken into account in some cases (useful in case of assignment of an instance of a subclass to a variable typed as its superclass)
- Array is the same as String[] (syntactic sugar)
- Functions are closures Xcode > Build Settings > Enable Strict Checking of objc_msgSend Calls = Yes https://twitter.com/gparker/status/473571205400645632
Wednesday 4 June 2014, watching the 1st WWDC video (session 402) about the language:
- The standard library is included by default
- Semicolons are optional
- Safe, modern, powerful
- var for variables, let for constants
- String, Double, Int, Bool
- Immutability / const by default -> preferred -> this allows the language to be optimized in multicore environments
- Type inference makes (in most cases) the type definition useless
- Unicode names for variables, including emoji
- String is a Unicode compliant implementation
- Looks like a C-String
- Can be used everywhere an NSString is required
- All the NSString API is available in native Swift strings
- for character in “mouse” -> including full Unicode compatibility
- “+” can be used to concatenate strings
- “printf” -> let result = “(a) times (b) is (a * b)”
- cannot “+” another string to a constant (var strings are mutable)
- Array and Dictionary
- Can be used just like NSArray or NSDictionary
- Can be created with literals, just like in Objective-C
- Keys and values can be anything, value or object
- Collections are typed
- var names: String[] = [“boom”, “bam”] -> the typed is inferred from the assignment
- Typed collection are safe, enforced by the compiler and the IDE
- Loops -> while, for, for in.
- For loops can have ranges “1…5” with three dots between the bounds (bounds are included)
- But “0..5” (with two dots) does not include the 5
- Can “for in” with dictionaries, which uses “for (key, value) in dict { … } “
- Modifying arrays
- The += operator can be used to add one or many (using another array) objects to an array
- “array[0…5] = …” can be used to replace lots of objects at once
- Optionals
- Indicated with question marks. It means that a type might contain something OR nil.
- Nil can be used with values
- The exclamation mark is an “unwrap” operator, to force the value out
- The exclamation mark triggers an assertion if the value stored is nil
- Better and safe: “if let obj = optional {…} “
- If statements don’t require parenthesis
- But they do require curly braces
- Switch statements do not fallback -> break statement not required.
- Don’t need to “case” numbers only, but also strings and objects
- Case statements can match multiple values in a single case
- Switch statements MUST be exhaustive: they MUST have a case for every possible value; you can use a “default” keyword for “the other values”
- Cases can match against a range
- println
- defined in the standard library
- Functions
- Use the func keyword
- Default values: func sayHello(name: String = “World”) {…}
- Return types specified using “->” and the type
- Tuples
- Can return multiple values using a tuple: (3.70, 3.25, 6.7) or (404, “Not Found”)
- Not a replacement for complex types or collections
- let (statusCode, message) = (200, “Success”)
- The tuple is (Int, String)
- Used when enumerating dictionaries
- Values in tuples can be named: (code: Int, message: String) -> let status = tuple -> tuple.code, tuple.message
- Closures
- Blocks like in Objective-C
- Type of a void/void closure is “() -> ()”
- Functions are named closures
- Can be passed as parameters
- If the closure is the last parameter, it can be passed outside of the parenthesis as a “trailing closure”
- Classes
- Don’t need to import .h files (no header files)
- Swift does not have a universal base class; can use any Objective-C class if required
- variable declarations in classes become properties
- Ivars and properties are the same
- Stored properties and computed properties, using a “get” keyword with a block inside returning a value, similar to C# (the “get” is not really required if the variable is readonly)
- Instantiation like Python, no “new” keyword
- Dot syntax for properties and methods
- All members are public
- “init()” is the initialiser of the class
- super.init() required
- No return
- “override” keyword to override a property in a subclass -> type safety
- Property observers using a “willSet” or “didSet” observer on the overridden properties; that code is in-place KVO code executed automatically
- In methods “self.” is optional when referring to properties, can be used to avoid confusion
- Structures
- “struct” keyword
- Can have custom initialisers
- Can have computed properties
- Can have methods
- Struct vs Class; differences?
- Struct cannot inherit
- Structs are passed as value (copy,) class instances as reference
- Constants and variables:
- Constants to a class instance can be used to change the properties of the referred object, but I cannot change the reference itself
- Constants to structs are immutable, and this includes the properties of the struct. The whole struct values are immutable too
- Hence, to mutate a structure on a method YOU HAVE TO USE the “mutating” keyword in front of the method declaration
- Enumerations
- .toRaw() method returns the raw integer value of an enumeration
- Enumerations can be based on other raw values, like strings
- Sometimes, no underlying raw value at all
- can use the “.Value” to change enum variables
- Enumerations with associated values
- enum TrainStatus { case OnTime, case Delayed(Int) }
- status = .Delayed(10)
- enums can have initializers and computed properties
- Type nesting
- A class can define its own internal enums
- Extensions
- Like a category in Objective-C
- Any named type, including value types, in any framework
- Generics
- Works for classes and structs
- Similar syntax as in Java or C#
“@Catfish_Man @siracusa Swift doesn’t dispatch through objc_msgSend() unless you inherit from NSObject or mark @objc. It’s pretty crazy.” https://twitter.com/brentdax/status/473929502955823106
Every iOS/OS X dev conference talk for the next ten years is going to have Swift code with the poop emoji as a variable name. https://twitter.com/mattgemmell/status/474104244384305152
Seems odd that Swift is still using @ prefixes for certain keywords (such as at the lazy modifier) - does anyone know why that is? https://twitter.com/nicklockwood/status/474178519468343297
Most perplexing feedback on Swift: folks who see it (and judge it) as the end of a trek - but don’t realize it is the start of a new world. https://twitter.com/clattner_llvm/status/474082459860992000
Looking forward to next month: I’ll be the first and only guy with 4 years of swift programming experience :-) https://twitter.com/clattner_llvm/status/473835365137416192
http://www.raywenderlich.com/73967/swift-cheat-sheet-and-quick-reference
Thursday 5 June 2014: Notes from session 406, “Integrating Swift with Objective-C”
- Swift and Objective-C are both first-class citizens in Cocoa
- Xcode creates a “bridging header” when adding a Swift class to an Objective-C project
- It also generates a generated header that allows the inverse operation
The .swift Icon is the “Crazy Ones” text now. 😊 (via @blunckalex) http://t.co/JA63Fs5iyG https://twitter.com/_nb/status/474569926297276416
Of course Swift supports hashbang scripts, you can immediately execute a swift script with “xcrun swift -i”. https://twitter.com/clattner_llvm/status/474593140511211520
Observations while creating sb2code:
- Port of nib2objc to Swift
- Can generate Swift, ObjC (classic with setters, modern with @properties,) C# (Xamarin) and maybe more later.
- New architecture that allows to read OSX storyboards and generate AppKit code
- Unfortunately the compiler chokes over the large number of classes (there’s one handler class per managed object on the Storyboard)
- Swift can return a “class” object from any class using the “.self” property, and this object is of type “.Type”
- For example: “var type: String.Type = String.self”
- Command-line tool at the moment does not have access to the command-line arguments (so far at least) so I’m using NSProcessInfo instead (as suggested by a question on devforums.apple.com)
- I had to create the bridging header manually to import an NSString category manually into Swift (see above picture,) but it did work.
- At the moment you cannot call sscanf (or other C standard libraries) directly from Swift, so you can use a bridging header for that wrapping on Objective-C. http://fuckingclosuresyntax.com http://goshdarnclosuresyntax.com
Friday 6 June 2014: Intermediate (403) and advanced (404) Swift sessions in WWDC
- Argument names and parameter names can be different in the class or function definition
- Argument names can be avoided using the underscore as an argument name in the definition
- sort() is a function that returns an array. Array.sort() does not return a new array; it just orders the current one in place. This means that you cannot change Array.sort().filter().map()… etc because Array.sort() returns Void.
- Variables must be initialised in init() prior to calling super.init() -> this is to ensure object initialisation before calling virtual methods, similar to what C++ does
- Use @lazy in front of a property to create a lazy-loading property; its value will only be loaded when required the first time.
- Special protocols the compiler knows about: LogicValue, Printable, Sequence, IntegerLiteralConvertible…
- “Printable” protocol has a “description” read-only property
- Operator overloading using the @infix keyword
- Method overloading is possible, to receive different value types
- “Any” is an “empty protocol” and it throws away type information. Generics conserve type information, providing performance and type safety
- Trailing closure syntax (when closures are the last argument) brings memories of Ruby blocks
- Generics can be applied to classes, functions, closures, structs…
- The “Sequence” protocol is required to objects used in “for…in” enumerations
- Protocols let you hook into the core language elements Swift model:
- Swift is statically compiled, with a small runtime
- Transparent interaction with C and ObjC
- Can deploy to previous versions of iOS and OS X
- Predictable compilation, no JIT or GC
- Efficient: native code, no abstraction, bare-to-the-metal
- During compilation, Swift analyses the code and optimises it
- Structs have no runtime penalty
- Int and Float are structs
- Generic specialisation “can” happen, but it’s not mandatory as in C++; some code can run in generic mode at runtime
- Dynamic method calls at compile-time: if Swift knows that there aren’t subclasses, or if you use the @final keyword
That’s one very strong statement: Swift is a protocol based language. https://twitter.com/fabricetdc/status/474824367126638592 (heard in session 404, minute 51)
In swift, “==” is compiled to [object1 isEqualTo:object2]. Something Cocoa developers have been begging for. “===” behaves as “==” in C. https://twitter.com/rosyna/status/474746076864344065
Swift web view tutorial video: https://www.youtube.com/watch?v=-wQ8sVa9TbU
Swift performance tip: compile your code in -Ofast mode to remove runtime safety checks. Your code will run much faster. https://twitter.com/SwiftDevs/status/474988521623916544
Safety and immutability are preferred, but Swift has UnsafePointer, malloc(), and mutability for the times you still need or want them https://twitter.com/clattner_llvm/status/475026273870180352