Swift 3.1 Concurrency, Operation Queue, Grand Central Dispatch

Created By: Debasis Das (23-May-2017)

In this article we will cover the following topics in Cocoa, Objective C with examples and sample code in Swift depicting the usage of each.

  • What is Concurrency?
  • Grand Central Dispatch
  • What is NSOperationQueue?
  • Introduction to Operation Queue
    • NSInvocationOperation
    • NSBlockOperation
    • Custom Operation
  • Dispatch Queues
    • Types of Dispatch Queues
  • NSOperationQueue vs DispatchQueues
  • Examples

Read more ›

Posted in Swift 3.1 Tagged with: , , , ,

Swift 3.1 NSTableView – Different Approaches Sample Code

Created By: Debasis Das (22-May-2017)

In this post we will try the different approaches of handling data population in a NSTableView and rendering different content types in a NSTableView.

We will create NSTableViews which are

  • Simple Cell based NSTableView using Datasource
  • Simple View based NSTableView using Datasource
  • View Based NSTableView with different UI Elements in Columns
  • View Based NSTableView single column multiple UI Elements in Row
  • View Based NSTableView Single column Header Cell and Data Cell

Swift 3.1 Cell Based NSTableView
Switf 3.1 View Based NSTableView using Datasource
Switf 3.1 View Based NSTableView multiple column types
Swift 3.1 View Based NSTableView Single Column Multiple Cell type
Swift 3.1 View Based NSTableView Header Cell Data Cell Read more ›

Posted in Swift 3.1 Tagged with:

Swift 3.1 Column Chart Animation using CABasicAnimation and CALayer

Created By: Debasis Das (22-May-2017)
In this post we will create a simple animation of Column Chart value changes.
We will be using CABasicAnimation and CALayers for creating this effect.

ColumnChart-Animation
Read more ›

Posted in Charts n Graphs, Swift 3.1 Tagged with:

Swift 3.1 Matrix Screensaver effect

Created By: Debasis Das (16-May-2017)

In this post we will create a simple cocoa application in Swift 3.1 to generate the matrix screen saver effect.
MatrixScreenSaver

Swift 3.1 Matrix Screen Saver Sample Code

Read more ›

Posted in CoreAnimation, Mac OSX Animation, Swift 3.1 Tagged with: , ,

Swift 3.1 CALayer

Created By: Debasis Das (15-May-2017)

An introduction to CALayer and Swift Sample code to create CALayer and modify its properties.
Layers are backing store for views and also can be used without a view to display content.
We can modify the visual attributes of a layer such as background color, border width, border color, shadow, opacity etc
In addition to the visual content, layers also maintain its position, size and transforms.
Animations can be initiated by modifying the properties of a layer
There are different types of layers such as

  • CALayer
  • CAGradientLayer
  • CATextLayer
  • CAShapeLayer
  • CAReplicatorLayer
  • CATiledLayer etc

In this article we will focus on creating a simple CALayer and setting it as the layer of the view and change the property of the layers on click of buttons

CALayer-gif

CAGradientLayer_gif2
Read more ›

Posted in Swift 3.1 Tagged with: , , , ,

Swift 3.1 Arrays


Created By: Debasis Das (15-May-2017)

In this post we will dive into Swift collection type array and see how it works and then we will apply map, reduce and filter on different arrays and check the corresponding output and behavior

Create an empty array

var array1 = [Int]()
print("is Array1 empty = \(array1.isEmpty)")
//is Array1 empty = true

//Lets append a few elements
array1.append(10)
array1.append(20)
print(array1)
//[10, 20]

Creating an Int array with repeated values

let array2 = [Int](repeating: 2, count: 5)
print(array2)
//[2, 2, 2, 2, 2]

Creating a Float array with repeated values

let array3 = [Float](repeatElement(2.3, count: 5))
print(array3)
//[2.29999995, 2.29999995, 2.29999995, 2.29999995, 2.29999995]

Lets add Two arrays

let array4 = [1,2]
let array5 = [3,4]
let array6 = array4 + array5
print(array6)
//[1, 2, 3, 4]

Accessing and modifying an Array

var monthArray = ["Jan","Feb"]
print ("is month array empty = \(monthArray.isEmpty)")
//is month array empty = false
monthArray += ["Apr","May"]

print(monthArray.first)
//Optional("Jan")

print(monthArray[0])
//Jan

monthArray[0] = "January"
print(monthArray[0])
//January

//Enumerating over an array
for (index, value ) in monthArray.enumerated(){
    print("index = \(index) & value = \(value)")
}
/*
index = 0 & value = January
index = 1 & value = Feb
index = 2 & value = Apr
index = 3 & value = May
 */

Array copies
Each array has an independent value that includes the values of all of its elements. For simple types such as integers and other structures, this means that when we change a value in one array, the value of that element does not change in any copies of the array

var array7 = [1,2,3,4,5]
var array8 = array7
array7[0] = 100
print(array7) //[100, 2, 3, 4, 5]
print(array8) //[1, 2, 3, 4, 5] , The first element is still 1 and not 100

Creating an array using Array Initializers

let array9 = Array(1...7)
print(array9)
//[1, 2, 3, 4, 5, 6, 7]

let array10 = Array(1..<7)
print(array10)
//[1, 2, 3, 4, 5, 6]

Creating an array using array literal

let daysArray = ["Monday","Tuesday","Wednesday"]

init(repeating:count:)
Creates a new array containing the specified number of a single, repeated value.

let attendance = Array(repeating: "P", count: 7)
print(attendance)
//["P", "P", "P", "P", "P", "P", "P"]

array count and array capacity

var numbers = [10, 20, 30, 40, 50]
print(numbers.count)    //5
print(numbers.capacity) //5
numbers.append(contentsOf: stride(from: 60, through: 100, by: 5))
print(numbers) //[10, 20, 30, 40, 50, 60, 65, 70, 75, 80, 85, 90, 95, 100]
print(numbers.count) //14
print(numbers.capacity) //20

Debug description

print(daysArray.debugDescription) //["Monday", "Tuesday", "Wednesday"]
print(daysArray.description) //["Monday", "Tuesday", "Wednesday"]

first

var array14 = [6,11,15,65,89,12]
var firstMultipleOfFive = array14.first { (num:Int) -> Bool in
    return num % 5 == 0
}
print (firstMultipleOfFive) //Optional(15)
print(firstMultipleOfFive.customMirror.subjectType) //Optional Int

Using Map – More on maps in subsequent examples

let array15 = [1,2,3,4,5,6]
let squaredNumbers = array15.map { (num:Int) -> Int in
    return num * num
}
print(squaredNumbers) //[1, 4, 9, 16, 25, 36]

let squaredNumbersAsString = array15.map { (num:Int) -> String in
    return "\(num * num)"
}
print(squaredNumbersAsString) //["1", "4", "9", "16", "25", "36"]
print(squaredNumbers.max()) //Optional(36)
print(squaredNumbers.min()) //Optional(1)

Array Partition

var array16 = [Int]()
array16 += 1...10
let idx = array16.partition { (num:Int) -> Bool in
    num % 2 == 0
}
print (array16[0..<idx]) //[1, 9, 3, 7, 5]
print (array16[idx..<array16.endIndex]) //[6, 4, 8, 2, 10]

Maps, filter and reduce

  • map returns an Array containing results of applying a transform to each item.
  • filter returns an Array containing only those items that match an include condition.
  • reduce returns a single value calculated by calling a combine closure for each item with an initial value.

Map
Map can be used to loop over a collection and apply the same operation to each element in the collection

var array1 = [1,2,3,4,5,6,7,8]
//long form map
var array2 = array1.map { (num:Int) -> Int in
    num * num
}
print(array2) //[1, 4, 9, 16, 25, 36, 49, 64]

//short form map
var array3 = array1.map {
    $0 * $0
}
print(array3) //[1, 4, 9, 16, 25, 36, 49, 64]

var days = ["Mon","Tues","Wed"]
var daysUpper = days.map { (day:String) -> String in
    return day.uppercased()
}
print(daysUpper)//["MON", "TUES", "WED"]

var dates = [NSDate(),NSDate(timeIntervalSince1970: 0)]
var formattedDates = dates.map { (date:NSDate) -> String in
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .short
    let dateString = dateFormatter.string(from: date as Date)
    return dateString
}
print(formattedDates) //["5/10/17", "12/31/69"]

Filter
Filter can be used to loop over a collection and return an array containing those elements that match the condition

var array4 = [1,2,3,4,5,6,7,8]
//Filtering the even numbers from an Int Array
var array5 = array4.filter { (num:Int) -> Bool in
    return num % 2 == 0
}
print(array5)  //[2, 4, 6, 8]

//Filter values greater than certain value in an Array
var array6 = array4.filter { (num:Int) -> Bool in
    return num > 3
}
print(array6) //4, 5, 6, 7, 8]

Reduce
reduce can be used to combine all items in a collection to create a single new value.

let array7 = [1.0,3.2,4.5,76.8]
let total = array7.reduce(0) { (x:Double, y:Double) -> Double in
    return x+y
}

print(total) //85.5

let newTotal = array7.reduce(100) { (x:Double, y:Double) -> Double in
    return x+y
}
print(newTotal) //185.5

//Combining Strings using reduce
let array8 = ["a","b","c","d"]
let concatArray = array8.reduce("") { (x:String, y:String) -> String in
    return x+" "+y
}
print(concatArray) // a b c d

Flat Map

let array9 = [[1,2,3],[4,5],[6,7,8]]
let array10 = array9.flatMap {
    $0
}
print(array10) //[1, 2, 3, 4, 5, 6, 7, 8]

let array11 = array9.flatMap { (intArray) -> [Int] in
    intArray.filter({ (num:Int) -> Bool in
        return num%2 == 0
    })
}
print(array11) //[2, 4, 6, 8]

Chaining
We can chain methods (filter, map etc)

let array12 = [1,2,3,4,5,6,7,8]
let array13 = array12.filter { (num:Int) -> Bool in
    num%2==0}.map { (num:Int) -> Int in
    num * num
}
print(array13) //[4, 16, 36, 64]
//In the above code we are filtering the array to find out only the even numbers followed by doing a square on each indvidual even number and finally returning the array

Posted in Swift, Swift 3.1 Tagged with: , , , , ,

Swift 3.1 Closures

Created By: Debasis Das (14-May-2017)

Closures are self contained blocks of functionality that can be used in our code and pass around as function parameters
Closures in Swift are similar to blocks in Objective C

In the below sample we will create two functions and pass it as an argument to the sorted by function of an array

import Cocoa
var array = [23,21,76,12,79]

func descending(val1:Int, val2:Int)-> Bool{
    return val1 > val2
}
func ascending(val1:Int, val2:Int)-> Bool{
    return val1 < val2
}

var descendingArray = array.sorted(by: descending)
print(descendingArray) //[79, 76, 23, 21, 12]

var ascendingArray = array.sorted(by: ascending)
print(ascendingArray) //[12, 21, 23, 76, 79]

Excerpt From: Apple Inc. “The Swift Programming Language (Swift 3.1).” iBooks. https://itun.es/us/jEUH0.l
“The sorted(by:) method accepts a closure that takes two arguments of the same type as the array’s contents, and returns a Bool value to say whether the first value should appear before or after the second value once the values are sorted. The sorting closure needs to return true if the first value should appear before the second value, and false otherwise.”

In the below sample we will use a closure expression syntax rather than sending a function as an argument to the sorted by method

var newDescendingArray = array.sorted { (num1:Int, num2:Int) -> Bool in
    return num1>num2
}
print(newDescendingArray) //[79, 76, 23, 21, 12]

Inferring Type from context

var names = ["John","Jim","Jane","Mary","Bill"]
var sortedNames = names.sorted { (s1, s2) -> Bool in
    return s1 < s2
}
print(sortedNames) //["Bill", "Jane", "Jim", "John", "Mary"]

Implicit Returns from Single-Expression Closures
Single-expression closures can implicitly return the result of their single expression by omitting the return keyword from their declaration

var sortedNames1 = names.sorted { (s1, s2) -> Bool in
    s1 < s2
}
print(sortedNames1) //["Bill", "Jane", "Jim", "John", "Mary"]

Shorthand Argument Names
Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2 etc

var sortedNames2 = names.sorted(by: { $0 < $1})
print(sortedNames2) //["Bill", "Jane", "Jim", "John", "Mary"]

Operator Methods
An even shorter way to write the above

var sortedNames3 = names.sorted(by:  > )
print(sortedNames3) //["Mary", "John", "Jim", "Jane", "Bill"]

Trailing closures

var sortedNames4 = names.sorted(){$0>$1}
print(sortedNames4) //["Mary", "John", "Jim", "Jane", "Bill"]


var monthNamesMap = [1:"Jan",2:"Feb",3:"Mar"]
let months = [1,2]
let monthNames = months.map { (number:Int) -> String in
    var name = ""
    name = monthNamesMap[number]!
    return name
}
print(monthNames) //["Jan", "Feb"]

Capturing values
A closure can capture constants and variables from the surrounding context in which it is defined. The closure can then refer to and modify the values of those constants and variables from within its body, even if the original scope that defined the constants and variables no longer exists.

var total = 0
var incrementTotal = {
    total += 1
}
var printTotal = {
    print("total is \(total)")
}
printTotal() //total is 0
incrementTotal()
printTotal() //total is 1
incrementTotal()
printTotal() //total is 2
Posted in Swift, Swift 3.1 Tagged with: , ,

Swift 3.1 Algorithms – Part 1


Created by: Debasis Das (13-May-2017)

In this post we will implement the following algorithms in Swift

  • Implementing a stack in Swift
  • Implementing a queue in Swift
  • Prime Numbers – Check if a number is prime
  • List of Prime numbers less than a given number
  • Binary Search
  • Binary Search Using Swift Generics
  • Quick Sort
  • Selection Sort
  • Insertion Sort
  • Recursively Searching a File in folders and sub folders
  • Bubblesort
  • Merge Sort

 

Read more ›

Posted in algorithms, Swift, Swift 3.1 Tagged with: , , ,

CALayer Sample Code – Part 1

CALayer Sample Code – Part 1

Created By: Debasis Das (31-Dec-2016)

In this post we will create a simple CALayer and then change its properties like backgroundColor, borderWidth, borderColor, cornerRadius etc

CALayer Sample

CALayer Sample

CALayer Sample Code

//  AppDelegate.m
//  CALayerDemo1
//  Created by Debasis Das on 26/12/16.
//  Copyright © 2016 Knowstack. All rights reserved.

#import "AppDelegate.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSView *view1;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    

}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}

-(void)awakeFromNib{
    CALayer *rootLayer = [CALayer layer];
    rootLayer.backgroundColor = [[NSColor whiteColor] CGColor];
    rootLayer.bounds = [self.view1 bounds];
    rootLayer.cornerRadius = 10.0;
    rootLayer.borderColor = [[NSColor redColor] CGColor];
    rootLayer.borderWidth = 10.0;
    rootLayer.shadowOpacity = 1.0;
    rootLayer.shadowRadius = 10.0;
    self.view1.layer = rootLayer;
    [self.view1 setWantsLayer:YES];
    
}

-(IBAction)changeColor:(id)sender{
    self.view1.layer.backgroundColor = [[NSColor colorWithRed:randFloat() green:randFloat() blue:randFloat() alpha:1.0] CGColor];
}

-(IBAction)changeBorderWidth:(id)sender{
    [self.view1.layer setBorderWidth:([self.view1.layer borderWidth] >= 10.0 ? 0.0 : 10.0)];
}

-(IBAction)changeBorderColor:(id)sender{
    self.view1.layer.borderColor = [[NSColor colorWithRed:randFloat() green:randFloat() blue:randFloat() alpha:1.0] CGColor];
    
}

-(IBAction)changeSize:(id)sender{
    CGRect layerBounds = self.view1.layer.bounds;
    layerBounds.size.height = (layerBounds.size.height == 200.0) ? 320.0 : 200.0;
    [self.view1.layer setBounds:layerBounds];
    
 }

-(IBAction)changeCornerRadius:(id)sender{
    self.view1.layer.cornerRadius = (self.view1.layer.cornerRadius == 10.0)? 20:10;
}

-(IBAction)changeOpacity:(id)sender{
    self.view1.layer.opacity = (self.view1.layer.opacity == 1.0)? 0.5:1.0;
}

-(IBAction)toggleShadow:(id)sender{
    self.view1.layer.shadowOpacity = (self.view1.layer.shadowOpacity == 1.0)?0.0:1.0;
    self.view1.layer.shadowRadius = (self.view1.layer.shadowRadius == 10.0)?0.0:10.0;
    
}

-(IBAction)changeAll:(id)sender{
    [self changeColor:self];
    [self changeBorderWidth:self];
    [self changeSize:self];
    [self changeCornerRadius:self];
    [self changeOpacity:self];
    [self toggleShadow:self];
    
}

float randFloat() {
    return (random() % 1001) / 1000.0f;
}

@end

Posted in Cocoa, CoreAnimation, Mac OSX Animation, Objective C Tagged with: , ,

CoreAnimation Analog Clock

CoreAnimation Analog Clock

Created By: Debasis Das (31-Dec-2016)

In this post we will create an analog clock using Core Animation. The final output will be as follows.

CoreAnimation Analog Clock

CoreAnimation Analog Clock

Core Animation Analog Clock Source Code

//  AppDelegate.m
//  AnalogClock
//  Created by Debasis Das on 31/12/16.
//  Copyright © 2016 Knowstack. All rights reserved.

#import "AppDelegate.h"

@interface AppDelegate ()
{
    //self.window.contentView will have a root layer and on top of the root layer we will add 3 layer.
    //Each layer representing a hand of the clock
    CALayer *hourLayer;
    CALayer *minuteLayer;
    CALayer *secondsLayer;
}
@property (weak) IBOutlet NSWindow *window;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    CALayer *layer = [CALayer layer];
    layer.frame = [self.window.contentView frame];
    layer.contents = [NSImage imageNamed:@"ClockFace"];
    [self.window.contentView setLayer:layer];
    [self.window.contentView setWantsLayer:YES];
    
    //Draw the hours hand layer
    hourLayer = [CALayer layer];
    hourLayer.backgroundColor = [[NSColor blackColor] CGColor];
    hourLayer.anchorPoint = CGPointMake(0.5, 0);
    hourLayer.position = CGPointMake(self.window.contentView.frame.size.width/2, self.window.contentView.frame.size.height/2);
    hourLayer.bounds = CGRectMake(0, 0, 10, self.window.contentView.frame.size.width/2 -100);
    [layer addSublayer:hourLayer];

    //Draw the minutes hand layer
    minuteLayer = [CALayer layer];
    minuteLayer.backgroundColor = [[NSColor blueColor] CGColor];
    minuteLayer.anchorPoint = CGPointMake(0.5, 0);
    minuteLayer.position = CGPointMake(self.window.contentView.frame.size.width/2, self.window.contentView.frame.size.height/2);
    minuteLayer.bounds = CGRectMake(0, 0, 6, self.window.contentView.frame.size.width/2 -50);
    [layer addSublayer:minuteLayer];

    //Draw the seconds hand layer
    secondsLayer = [CALayer layer];
    secondsLayer.backgroundColor = [[NSColor redColor] CGColor];
    secondsLayer.anchorPoint = CGPointMake(0.5, 0);
    secondsLayer.position = CGPointMake(self.window.contentView.frame.size.width/2, self.window.contentView.frame.size.height/2);
    secondsLayer.bounds = CGRectMake(0, 0, 3, self.window.contentView.frame.size.width/2 -20);
    [layer addSublayer:secondsLayer];

    //Place the hands at correct location
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *dateComponents = [calendar components:NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour fromDate:[NSDate date]];
    
    NSInteger seconds = dateComponents.second;
    NSInteger minutes = dateComponents.minute;
    NSInteger hours = dateComponents.hour;
    
    //Calculate the angles for each hand of the analog clock
    CGFloat hourAngle = (hours * (360/12)) + (minutes * (1.0/60) * (360/12));
    CGFloat minuteAngle = minutes * (360/60);
    CGFloat secondsAngle = seconds * 360/60;

    
    hourLayer.transform = CATransform3DMakeRotation(hourAngle /180 *M_PI, 0, 0, 1);
    minuteLayer.transform = CATransform3DMakeRotation(minuteAngle /180 *M_PI, 0, 0, 1);
    secondsLayer.transform = CATransform3DMakeRotation(secondsAngle /180 *M_PI, 0, 0, 1);
    
    //Add 3 animations for each layer    
    CABasicAnimation *secondsAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    secondsAnimation.repeatCount = HUGE_VALF;
    secondsAnimation.duration = 60;
    secondsAnimation.removedOnCompletion = NO;
    secondsAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    secondsAnimation.fromValue = @(secondsAngle * M_PI / 180);
    secondsAnimation.byValue = @(-2 * M_PI);
    [secondsLayer addAnimation:secondsAnimation forKey:@"SecondAnimationKey"];

    CABasicAnimation *minutesAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    minutesAnimation.repeatCount = HUGE_VALF;
    minutesAnimation.duration = 60*60;
    minutesAnimation.removedOnCompletion = NO;
    minutesAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    minutesAnimation.fromValue = @(-minuteAngle * M_PI / 180);
    minutesAnimation.byValue = @(-2 * M_PI);
    [minuteLayer addAnimation:minutesAnimation forKey:@"MinutesAnimationKey"];

    CABasicAnimation *hoursAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    hoursAnimation.repeatCount = HUGE_VALF;
    hoursAnimation.duration = 60*60*12;
    hoursAnimation.removedOnCompletion = NO;
    hoursAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    hoursAnimation.fromValue = @(-hourAngle * M_PI / 180);
    hoursAnimation.byValue = @(-2 * M_PI);
    [hourLayer addAnimation:hoursAnimation forKey:@"HoursAnimationKey"];


}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}

@end

CoreAnimation Analog Clock Source Code

Posted in CoreAnimation, Mac OSX Animation Tagged with: , , ,

Recent Posts


Hit Counter provided by technology news