Move to Swift 3.0

Some notices about Threading in Swift 3: 

More Object Oriented approach to GCD, The C style GCD API have been replaced by a more swift style , now DispatchQueue has been introduced as a base class for most basic operations , with this class we can create a new queue or obtain an existing Queue such as Global queue or Main queue, then we submit our block to this Queue in either async or sync mode.

avoid confusion between concurrent tasks and parallelism!
First you as a developer should know Parallelism is a mechanism at Processor level ,It's the execution of two or more tasks at the same times on two or more Processors, it really controlled by OS ,it's up to system to decide how to handle tasks this said two or more tasks may be executed on just one processor through context switching and never be parallel! concurrent tasks on the other hand are managed and controlled by developers , we can dispatch multiple block of codes through multiple concurrent tasks.

each task may or may not be started at the same time with other but it's not reflecting absolutely the parallelism.

Swift 3 :

let queue = DispatchQueue(label: "myqueue", attributes:.xxxxxx)

queue.async {

  print("submit queue")


xxxxx attribute is the execution mode as concurrent or serial 


let parrallelQueue = DispatchQueue(label: "myqueue", attributes:.concurrent)

parrallelQueue.async {

  .....


to get a serial Queue

let serialQueue = DispatchQueue(label: "myqueue", attributes: .serial)

serialQueue.sync { 

.......

}


we can execute an async operation using main thread as 

DispatchQueue.main.async {

....

}

or to run a background thread by a global queue

DispatchQueue.global(attributes: .qosDefault).async {

}


With his OOP approach , it’s easier to update UI from a background thread with less codes 

DispatchQueue.global(attributes: [.qosDefault]).async { 

    // Background thread

DispatchQueue.main.async(execute: { 

        // UI Updates

    })

}

dispatch_once is now deprecated in Swift 3.0


*Threads have 4 level of Priorities in Swift 3.0 , priority table defined as

DISPATCH_QUEUE_PRIORITY_HIGH == .qosUserInitiated

DISPATCH_QUEUE_PRIORITY_DEFAULT == .qosDefault

DISPATCH_QUEUE_PRIORITY_LOW == .qosUtility

DISPATCH_QUEUE_PRIORITY_BACKGROUND == .qosBackground


Focus on the bold changes and concepts in Swift 3:


1) As expected from developer’s community Consistent Label Behavior for function Parameters

Now all functions arguments are labeled

func adder(a:Int,b:Int)-> Int  

swift 2 : adder(5,b:2)

swift 3 :adder(a:5,b:2)


2) "var" keyword in functions parameters has been removed in Swift3 , let's see by example

using swift2 we can have this function:

func adder (a:Int , var y:Int)->Int{

y = a+y

return y;

}

in fact y is a variable who has its own copy so you can change it inside your function
with Swift3 it’s no longer allowed pass such a variable to function, and you probably have
to create your own copy of variable inside if you need to do any operation on the variable on question like:


func adder (a:Int , var y:Int)->Int{

var c = a

var d = b

return (c+d)

}


3) C-Style increment ++ and decrement -- operators are removed


4) Change in KVC/KVO in Swift3 passing key as string to retrieve value is no longer permitted

Instead you are using new keyword #keyPath , the reason for what Apple remove old fashion is first the mistyping issue which result generally in unexpected Crash and second the more swifty syntax!


Swift 2 : 

class Record {

name:String

init(name: String) {

    self.name = name

  }


}

let record = Record(name:"Khosrov")

let val = record.valueForKeyPath("name")


instead you are using this :

let val = record.value(forKeyPath: #keyPath(Record.name))


5) Remove prefix NS for foundation types:

we all have seen or used in the past refrences like NSUserDefaults ,NSFileManager, NSBundle...with 'NS' as prefix, Apple SWift team have decided to remove those perfix 'NS' in order to get distance with OBJECTIVE_C syntax and expose a swifty new subset of interface ,

from now in XCode8/Swift3 any reference to NSBundle.mainBundle() should be changed to Bundle.mainBundle()

Swift 2 :NSBundle.mainBundle().pathForResource(filename, ofType: type)

Swift 3 :Bundle.mainBundle().pathForResource(filename, ofType: type)

6) simplify and renaming some API syntax in order to be more relevant:

For example this function for inserting an item to an array

array.insert("One", atIndex: 0

now get shorter and replaced by 

array.insert("One", at: 0

or this function below 

array.insertContentsOf(["One", "Two", "Three"], atIndex: 0)

which we move slightly “ContentOf” from function name to argument as follow:

array.insertContentsOf(["One", "Two", "Three"], at: 0)

the sameway in an array indexOf(xxx)  changed to indx(of:xxx)

or removing not necessary word

let red = UIColor.redColor()//Color is obvious as the Object is UIColor!

Now in Swift 3:

let blue = UIColor.blue() //

Unify relevent naming:

Most of API heve been reviewed to reflect the current operation they perform,

word "ed" is added to api which return a value

array.reverse() is performing a reverse operation but array.reversed() actually return the reversed array

 in Swift 2.x sort() function return the sorted elements , in Swift 3 this job is done by sorted() and sort() do only a sort in place job and dopesnt return antything.


another change reveled in WWDC 2016 is about presentViewController which becomes more consistent alongside those described above, it’s shorter we just call present instead of presentViewController

Swift2: parentViewController.presentViewController(newViewController, animated: true, completion: nil)

In Swift 3, this code snippet looks slightly different as you can see below.

Swift3 : parentViewController.present(newViewController, animated: true, completion: nil)




Other change is related to removing an existent mechanism in Swift2 , “Modify variable passing as argument to a function”

func getAreaSwift3(r:Float,result:inout Float){

    result =  (Float.pi)*r*r
}

var res:Float = 0

getAreaSwift3(r: 5, result: &res)

print(res)

You cannot anymore use such a function to modify variable passed as argument ,instead you use inout feature

Notice you cannot declare a unique variable for multiple argument at the same time


example:

func swift3function(x:inout Int,y:inout Int){

x = x*2

y= x*3

}

then use function as following

var a = 5

swift3function(x:&a,y:&a) //Error

7) Unify all Float, CGFloat, Double,Float 80 by FloatingPoint protocol in which pi number is easily accessible in other word Moving M_PI (pi number) to a static memeber of Float, Double , CGFloat named "pi"


Swift 2 : let circleArea  =  M_PI  * pow(r,2)

Swift 3 : let circleArea =  (Float.pi) * pow(r,2)

8)  All graphical operation are now use the properties from CGContext , rather than reference it from other graphical objects ,  these properties are added to  CGContext  

Example:

if let context = UIGraphicsGetCurrentContext() {

    

    context.setFillColor()

    .....

    context.drawPath(using: .fillStroke)


    UIGraphicsEndImageContext()

}

9)  UnsafePointer now can be optional as

var pF: UnsafePointer<Float>?

This improvement make sense for many developers who implement some lower level of thier codings in C,and call much more safer C function witout worring about handling the null pointers which in some cases leads to crash.

Remind:

In Swift we can delegate some lower level tasks in C , the main challenge doing that is how to deal with pointers ,InterOperability between C codes and Swift in general pass through UnsafePointer and UnsafeMutablePointer pointers , the first one references a constant pointer and the second one reference a non-constant pointer,here a resume of equivalent functions in both Swift & C syntax

 

C API                                                          Swift API

const Type *                                             UnsafePointer<Type>

Type *                                                     UnsafeMutablePointer<Type>

Type **                                                      AutoreleasingUnsafeMutablePointer<Type>



The rule for type equivalent is easy to keep in mind : C+[FirstLetterCapitalized(Swift Type)] =[C Type]

such as : bool = CBool long = CLong, char = CChar , int = CInt , float = CFloat , ....


in reality they are declared as type alias for example let's look at CInt , it's declared as following typealias:

typealias CInt = Int32


Example:

var x: CInt = 10
myFunction(&x)    // Output 10

But it remain still one issue ,  how to deal with pointers values? how to cast the value stored in memory which our pointer pint to? actually even the cast is not very safe but we can use unsafeBitCast [or withUnsafePointer] which prototype is:

func unsafeBitCast<T, U>(_ x: T, to: U.Type) -> U


this API maps a pointer with a binary value in memory by casting with a given type (here U)

let's see a buffer pointer like what we have used in memcpy for many years ! suppose we have some data of string type to copy(dataToCopy)

void* buffer;//somewhere in code
memcpy(buffer,dataToCopy,sizeof(dataToCopy));
….

Then somewhere you have data copid to a swift equivalent buffer

var  Buffer : UnsafeMutablePointer<Void>?


let swiftBuffer = unsafeBitCast(Buffer, CFString.self)

be careful unsafeBitCast is a dangerous api , it maps the memory zone as it is ( binary) without any safety checking!


"For a custom type pointer which has not any equivalent in Swift we can use COpaquePointer for example a structure pointer passed into a C function can be implemented in swift as

func setData(dataStruct:COpaquePointer){

}

Some notices about System Level Threading: 

avoid confusion between concurrent tasks and parallelism!
First you as a developer should know Parallelism is a mechanism at Processor level ,It's the execution of two or more tasks at the same times on two or more Processors, it really controlled by OS ,it's up to system to decide how to handle tasks this said two or more tasks may be executed on just one processor through context switching and never be parallel! concurrent tasks on the other hand are managed and controlled by developers , we can dispatch multiple block of codes through multiple concurrent tasks.

each task may or may not be started at the same time with other but it's not reflecting absolutely the parallelism.


7) More Object Oriented approach to GCD, The C style GCD API have been replaced by a more swift style , now DispatchQueue has been introduced as a base class for most basic operations , with this class we can create a new queue or obtain an existing Queue such as Global queue or Main queue, then we submit our block to this Queue in either async or sync mode.

Swift 3 :

let queue = DispatchQueue(label: "myqueue", attributes:.xxxxxx)

queue.async {

  print("submit queue")


xxxxx attribute is the execution mode as concurrent or serial 


let parrallelQueue = DispatchQueue(label: "myqueue", attributes:.concurrent)

parrallelQueue.async {

  .....


to get a serial Queue

let serialQueue = DispatchQueue(label: "myqueue", attributes: .serial)

serialQueue.sync { 

.......

}


we can execute an async operation using main thread as 

DispatchQueue.main.async {

....

}

or to run a background thread by a global queue

DispatchQueue.global(attributes: .qosDefault).async {

}


With his OOP approach , it’s easier to update UI from a background thread with less codes 

DispatchQueue.global(attributes: [.qosDefault]).async { 

    // Background thread

DispatchQueue.main.async(execute: { 

        // UI Updates

    })

}






 © Xosrov 2016