Friday, 24 February 2017

Mix navigation bar with main view

In iOS when it comes to work with navigation controller, we need to handle different aspects of the UINavigation bar which is a property of the UINavigationController. 
In my last app , I need to merge the navigation bar into main view to mimic the user there is no navigation bar but still have bar buttons and title in it.

Here I am showing some small but important work we can do with UINavigation bar, which I come up with :

1) Add animation to title of the navigation bar 

 let lblTitle = UILabel(frame:CGRect(x:0, y:0,width:50, height: 50))  
        lblTitle.text = "Items"
        lblTitle.textColor = UIColor.white
         self.navigationItem.titleView = lblTitle
        
        let animation  = CATransition()
        animation.duration  = 3.0
        animation.type = kCATransitionPush

        lblTitle.layer.add(animation, forKey:"moveText")

2) Mix the navigation bar into main view of the screen


 To merge the navigation bar into our main view, we have to remove the separator line between navigation bar and main view. And then cha

To remove the separator line , set background image and shadow image to a blank UIImage , like this one: 

Now change the background color of the navigator bar with the color of main view
        
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()

If the default background image is used then default shadowImage also used. So to make it work backgroundImage must be changed with shadowImage.




Thursday, 16 February 2017

Working with NSDate

In iOS development  it's very common to work with NSDate. NSDate object returns the current point of time .
    
 NSDate *currentDate = [NSDate date];
The  above line of code will return the current time with date .

Last week  I was working on an app, the requirement was to calculate the difference between two dates and show the difference in number of days.

For example say you have two dates in string as:

NSString * firstDate = @"2015-10-01 05:46:41 UTC"
NSString *secondDate = @"2015-11-01 05:46:41 UTC"

Now to calculate the difference between  two, first of all we have to convert these two string dates to NSDate object.

To convert the string into NSDate object, create a formatter(NSDateFormatter) with format which matches to your string date as:

 NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
 [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ssZ"];

The first line will initialize the NSDateFormatter and the second line will set the date format, as we have our date in this format in this example .

Now we can get the NSDate for an string date. To get the date from string use formatter object as:

NSDate * startDate =  [formatter dateFromString: firstDate];
NSDate *EndDate = [formatter dateFromString: secondDate];

Now you we have two NSDate object. To get the difference between these two , we should check the which date is later . 

To compare two NSDate object , we use compare method as:

if ([EndDate compare: startDate]== NSOrderedDescending){
    //EndDate is later than startDate date

    NSTimeInterval secondsBetween = [EndDate timeIntervalSinceDate: startDate];
   int numOfdaysLeft = secondsBetween/86400 ;
                   
    } 

Summary
Here we create the NSDate object from string, compare two NSDate object and calculate the time interval between two NSDate object and finally get the number of days from time interval .


                

Sunday, 12 February 2017

Working with Swift

Swift is Apple's new development language. When we switch from Objective C to Swift , we need some tricks so that we can reuse the code and can write less code  for our app .

1) Use Extension: 

Try to code less and reuse it whenever it's possible. Follow write once and use many  approach. For example, in our app there may be a requirement that most of the views should have border and round corner .
For this we can  write those line of code for each view in our view controller . But a better approach is that we can  write an extension to UIView, which will make the input view to have border and round corner.

extension UIView{
    
    func makeCornerRound(cornerRadius:CGFloat){
        self.layer.cornerRadius = cornerRadius
        self.layer.masksToBounds = true
    }
    
    func addBorderWith(color:UIColor, width:CGFloat){
        self.layer.borderWidth = width
        self.layer.borderColor = color.cgColor
        
    }

}

To use these as:
let myView = UIView()
myView.makeCornerRound(cornerRadius:3)
myView.addBorderWith(color:UIColor.gray,width:1.0)

2) Optional Unwrapping:

Guard vs If let

 var email:String?
var password:String?
if let mail_id = email{
  if let pwd = password {
    print("Welcome to my app!")
   }
}

The above code can be written with Guard statement like this:
guard let mail = email, let pwd = password  else{
   print("ohh no! we don't have email and password")
   return
}
print("Welcome to my app!")

You can see the difference here. The scope of unwrapped variable remains to the function in which they are unwrapped with Guard statement. But with if let , the scope is limits to the block in which they are unwrapped.

3) Nil Coalescing : 

What if the value of the optional is missing and you want to  perform some action in case of the absence of the value of an optional . Let's understand  this with an example:

var userName:String?

if let name = userName{
  print("Welcome \(user)")
} else{
  print("Welcome Guest")
}

We can short the above code with nil coalescing operator .

let name =  userName ?? "Guest"
print("Welcome \(name)")

Thursday, 2 February 2017

Working with string and character in Swift

In swift string is value type. In Swift string type is built from Unicode scalar values. A unicode scalar is a unique 21 bit number for a character.

To write an arbitrary scalar value , use \u{n}, where n is a 1-8 digit hexadecimal number with a value equal to a valid Unicode code point.
For example:
let dollar = "\u{24}"
let baby:Character = "\u{1f425}"

Using Extended grapheme cluster we can create a single character by many complex script characters.
An Extended grapheme cluster is a sequence of one or more unicode scalar  that produce a  single human readable character.
let eInCircle:Character = "\u{E9}\u{20DD}"

Will print "é⃝"


String indices: 

In swift different characters require different amount of memory  to store , so in order to determine the position of a character, we must iterate over each unicode scalar from start or end of that string .That's why string in swift can not be indexed by integer values.

A) To get the position of the first character , use the startIndex property of the string:
  var name = "Budha"
   
  To get the first character of the name,
   let firstChar =  name[name.startIndex]

B) The endIndex property  is position after the last character in the string. So to access the last character in the string, use:

let endIndex = name.endIndex
let lastChar = name[name.index(before: endIndex)]

C) To check the equality for string and character, we use ==(equal to ) and != (not equal  to )operator. Two string value will be considered equal if their Extended grapheme clusters are canonically equal. Extended grapheme clusters are canonically equal if they have the same linguistic meaning and appearance, even if they are composed from  different Unicode scalars behind the scenes.

Thursday, 19 January 2017

Operation on Collection in Swift

In iOS app development we need to perform some task on collection (Array,dictionary..) in swift. For example to get the sum of the element in an array we could go for for-in loop . Do code like this:

let arr =  [1,3, 4,6,9]

var sum = 0
for i in arr{
sum += i
}

We can achieve such kind of task very easily with a line of code.

Working with Map, filter, reduce and flatMap:

To get the sum of all element we can write

let sum =  arr.reduce(0,+)

Map:

We use map to  loop over the collection and apply a same  on each element in collection. For example to get the square of of each element in an array we could go for for in loop and to square of each element in an array.

With map, we can do this task this way:
let arr = [1,2,4,5,6,7,8,9]

let squares =  arr.map{$0 * $0}

The map function has a single argument which is a closure. Map function calls this closure as it loop over the collection. This closure takes an element from the collection as an argument and returns result. The map function return the result in an array.

We can  write above line of code as:

let squares2 =  arr.map{element in   element * element}

The keyword  in separates  the argument from the body of the closure .

The map operation can be performed on each collection type it is not limited to just an array. We can use this with dictionary, set also. But the result of the operation is always an array.

Filter: We use filter where we want to filter the collection  of data with a condition. Filter function loop over the collection  and returns only those element from the collection which satisfy  a given condition in include.

let arrData  = [1,23,45,,4,6,8,3]

For example : To get only those element from above array which is even, we write:

let arrEven = arrData.filter{ $0 %2 == 0}

Reduce: reduce method used to combine all elements in a collection to create a single value . The reduce() method takes two arguments, an initial value and a closure

let  fullStatement  = arr.reduce("==") {text, name in "\(text),\(name)"}

FlatMap: Used to flatten to  collection of   collections.

let complexArray  = [[2,3,5],[34,56], [34,56,78]]

let flat =  complexArray.flatMap {$0 }

The above line of code will combine all sub array  from complexArray into  a single array.

With flatMap and  chaining of the above methods we can solve complex queries on collection .

For example: get all even elements from complexArray

let   evenNums  = complexArray.flatMap{ 
                  subArray in subArray.filter{ $0 %2 == 0}
             }

In short form we can write above line as:
let evenInShortForm =  complexArray.flatMap { $0.filter{ $0 %2 == 0  }}

References:http://useyourloaf.com

Thursday, 12 January 2017

Sort Array in swift


To sort an array we can use sort() which all arrays have in default. We can use sort() and sorted() to sort an array.

To sort an simple array like this, we can use sort() as:

var arr =  [ "orange","Apple" "Grapes","banana"]

arr.sort()


To sort an array of custom object like custom struct or class we  use sort() using a trailing closure that sort an array on field we specify.

For example: We have an array of custom object Opportunity which have a string field date . So to sort this array on date field, here we will first convert string date to Date object . Let's have a look on below code:To sort arrOpportunities on a string field say title,

arrOpportunities.sort{

$0.title.compare($1.title) == NSComparisonResult.OrderedAscending
}

 If we have title say:
["hello","ok","arm","Basket"]  then using  above code will results in

["Basket","arm","hello","ok"]

To get results in ignoring the case we can use localizedCompare() like this:

arrOpportunities.sort{

$0.title.localizedCompare($1.title) == NSComparisonResult.OrderedAscending
}

will result in
["arm","Basket","hello","ok"]

If we want to return an array after doing sort we can use sorted() like this

var arr_sorted =  arrOpportunities.sorted{

$0.title.localizedCompare($1.title) == NSComparisonResult.OrderedAscending
}

Tuesday, 27 December 2016

Integrate third party library in an iOS project:


In iOS app development we need many other libraries to be included in our app to accomplish set of task. There are number of ways by which we can include these library  in our project .

1) Using Cocoapods 

Cocoa pod is dependency manager . It is very simple to add library this way . Go to project directory and follow these steps:

a) Run pod init  command
    The above command will initialize the pod in project directory and creates a pod file. 
b) Now open the pod file and add  required library in this file . And save the file .
c) Run pod install command .
    This will install the library in project directory  and creates a xcworkspace  file in project directory .

     From now open the xcworkspace instead of Xcode project . 

2) Manually:

Using this way , we just drag and drop the required files/folder of required library to our project.

3) using git sub module:


Using this way we add a third party project using git command . This command will add third party library as a submodule in our project.

a) Go to your project directory , initialize git if git is not initialized in project directory .
      
     git init 
   
 b) git submodule add  project-url

    The above command will add third party library at given url as a sub module in our project .