Showing posts with label Swift. Show all posts
Showing posts with label Swift. Show all posts

Wednesday, November 25, 2015

How to check API availability in Swift?

If you are working with Swift then you need to be very careful to use the iOS specific API. As before Swift 2.0, there were no standard way to check the availability of any API or method.

Swift 2.0 introduced the “#available“ to check the API availability or run version specific code in blocks . If you are developing the application with deployment target 8.0 with base sdk 9.0. You need to use the API which is available in iOS 9 only then you could do this by checking the API availability. 

If you will not check the API availability then it will give you a compiler error. To prevent this error, you need to check the API availability.

if #available(iOS 9, *) {
            let stackView = UIStackView()
            // do iOS 9 stuff
        }

Using the availability syntax we will check whether we are running iOS 9 or later and if so will execute the code.

You can also add the availability check for the instance method and classes by inserting the given line above the method definition or at the top of the class.

@available(iOS 8.0, *)
    func iOS8Method() {
        // do stuff
        
    }

You can’t use this method without availability check if your deployment target is below 8.0. This method will run above iOS8.0 target. 

The * at the end is used to refer all the Future platforms that Apple introduces, and it's required.



Wednesday, April 29, 2015

Lazy Loading in Swift


Lazy loading is a technique to initialize the property only if they are called. In this way, memory is not allocated  to the property until it’s not initialized and if this property is not used then memory will never be allocated to this property. Lazy loading is also known as Dynamic loading.

In Swift, we have the keyword lazy to initialize the property with lazy loading. Lazy keyword makes sure that the property will be initialized only when its gets called and it would be initialized only once.

Also, whenever we want to declare the lazy property, always use the var keyword not let keyword as constant must always have a value before the initialization.

Here, we have define the Person Class with two properties name and message with lazy attribute means this variable will be initialized only when it is used. 

class Person {
    
    var name : String?
    lazy var message: String = {
        return "Hello \(self.name!)"
        }()
    
    init(name: String) {
        self.name = name
    }
}

Now, initialize the Person class. This will also initiate the name property but message is not initialized means person.mesage is nil.

var person = Person(name: "John"



And when you tries to use the message properties then it will initialized.

println("\(person.message)") //  Hello John
      
As the message property closure will be called only once so even if you update the name property, it will not make any changes to your message property.
  
person.name = "Jimmy"
println("\(person.message)") //  Hello John


Lazy loading technique is used to improve the performance and to perform expensive operation. Swift has provided the direct support for lazy initialization with lazy attribute.




Tuesday, March 10, 2015

How to create custom operators in Swift?

In Swift, you can create your own custom operators in additions to the Swift operators. 

Swift has Unary, Binary and Ternary Operators. You can create the custom operators for Unary and Binary operators. For Unary operators, you can use Prefix and Postfix modifier and for Binary Operator, you can use Infix modifier.

Currently, we cannot write the Custom Ternary operators. Swift has only one Ternary Operator that is Condition operator.
eg- a ? b: c

Following are the modifier which you can use to create the custom operators. 

Prefix- A Unary Operator that is placed before the operand.
eg- b = ++a (++ is operator and a is operand)

Postfix- A Unary Operator that is placed after the operand.
eg- b = a++

Infix- A Binary operator that is placed in between the two operands.
eg- c = a + b

You can create the custom operators that starts with one of the ASCII characters /, =, -, +, !, *, %, <, >, &, |, , or ~, or any of the Unicode characters in the "Math Symbols" character set.

Note-  As mentioned in the Apple documentation, there are some operators which can’t be overloaded nor can be used as Custom Operators. 
The tokens =, ->, //, /*, */, ., the prefix operators <, &, and ?, the infix operator ?, and the postfix operators >, !, and ? are reserved. These tokens can’t be overloaded, nor can they be used as custom operators.

Implementing a Prefix and postfix operator-

As you know that Unary operator operates on single operand. It can be Prefix (++a) if they precede the operand or Postfix (a++) if they follows the operand.

You can implement your own custom unary operators by preceding the operators function with the prefix and postfix modifier.

Let’s declare the +++  prefix operator which can doubles the operand’s value.

prefix operator +++ {}

Now, define the operator functions.

prefix func +++ (number: Double) -> Double {
    return (number + number)
}

let value = +++10 // 20

In the same way, you can create the unary operator with  the postfix modifier.




Implementing an Infix Operator- 

Infix operator is operates on two operators and placed in between the two operands. When you declare the custom Infix operators you can specify the Associativity and Precedence. 

If there are two or more infix operators in the expressions then on the basis of Associativity and Precedence, it can be define which infix operator executes first.

Here, we have define the new custom infix operator +- with left associativity and 140 precedence.

Associativity value can be left, Right and None. By default it is None and the precedence value is 100 if it is not specified. 

infix operator +- { associativity left precedence 140 }

Now, implements the +- operator which returns the tuple value of sum and difference of two operands.

func +- (left: Double, right: Double) -> (Double, Double) {
    return (left + right, left - right)
}

let value = 3 +- 2 // (5, 1)






Tuesday, February 24, 2015

Subscript in Swift

Subscript are the shortcut to access the elements from collection, sequence and list. You can define the subscript in Class, Struct and enumeration to set and get the value by index. By using Subscript, you don’t need to write the separate methods for getting and setting the values.


Subscript can  read- write or read only. You define subscript by using the subscript keyword and specify one or more input parameters and return type.

subscript(parameters) -> ReturnType {
    get {
        //return someValue
    }
    set (newValue) {
        //setSomeValue()
    }
}

For read only Subscript, you can drop the get keyword.

subscript(parameters) -> ReturnType {
        //return someValue
}

Here, we have created the subscript in String Extension to check the substring is found in String or not. This Subscript will return a true value if substring is found in the String. This is the Read Only subscript.

extension String {
    
    subscript(pattern: String) -> Bool {
            let range = self.rangeOfString(pattern)
            return (range != nil)
    }
}

   var str = "Hello Swift"
   println(str["Swift"]) // true


Let’s create another Subscript of Read-Write type. In this Subscript, we can replace the Substring with another substring. Also, you can check that String contains substring or not. If the String contains the Substring, it will return the substring otherwise nil.

extension String {
    
    subscript(pattern: String) -> String? {
        get {
            let range = self.rangeOfString(pattern)
            
            if range != nil {
                return pattern
            } else {
                return nil
            }
        }
        set(replacement) {
            let range = self.rangeOfString(pattern)
            
            if range != nil {
                self = self.stringByReplacingCharactersInRange(range!, withString: replacement!)
            }
        }
    }
}


var str = "Hello Swift"
println(str["Swift"]) // Swift
println(str["Java"]) // nil

// Replace Hello with Hi
str["Hello"] = "Hi"
println(str)

In the setter, you can use the newValue keyword in place of replacement and code look like this.

subscript(pattern: String) -> String? {
        get {
            let range = self.rangeOfString(pattern)
            
            if range != nil {
                return pattern
            } else {
                return nil
            }
        }
        set {
            let range = self.rangeOfString(pattern)
            
            if range != nil {
                self = self.stringByReplacingCharactersInRange(range!, withString: newValue!)
            }
        }
    }

Monday, February 2, 2015

Generic Functions in Swift.


Generic is one of the powerful feature of Swift. Most of the Swift Standard library uses this feature.

For instance, Swift Array and Dictionary are Generics Collection which can hold the value of any Type. You can create the array which holds Int values or String values.

With Generics code, developer can write flexible and reusable function which can work with any Type.

Suppose you have to write a function to swap two Int values. 



In Swift, parameters are passed by value so you can’t change the parameters value within the Function. If you want to modify the parameters value then you have to define the parameters as inout.

When you call a  function with an inout parameters, you use ampersand (&). This is something like passing the address of values as we have in C language.

If you want to write a function which can swap String or Doubles values then your function will look like this.





You may have noticed that all these functions bodies are same. Only difference is the type of the value passed to this functions.

So, you can write Generics functions which can work with any Type.




Generics function uses a placeholder type in angular bracket instead of actual Type name (Int, String). Both parameter a and b must be of same T type whatever T represents. 






Thursday, January 29, 2015

How to open Share and Action Extension from your application?


With the introduction of Extension in iOS 8, many applications is available with Share and Action Extension and if we want to share content and perform some action from our application to those app then we can open the extensions of those application using UIActivityViewController.

UIActivityViewController is a standard view controller which can offers System specific services such as copying items to the pasteboard, posting content to social media sites, sending items via email or SMS from your application.

Below is the code to initiate UIActivityViewController.

let text = "Text to share"
        let url : AnyObject! = NSURL(string: "https://www.google.co.in")
        let image : AnyObject = UIImage(named:"download.jpeg")!
        let activityItems : [AnyObject] = [text, url, image]
        
        let activityViewController : UIActivityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
        self.presentViewController(activityViewController, animated: true, completion: nil)


Here, we have created array of AcitivityItems(image, text, url) and passed it to the UIActivityViewController Constructor.

This will show all the Share and Action Extension supported by the system or application which are installed in your devices.




Note- User can manually enable and disable the application by tapping the More shown in the Share and Action Activity section. User can also reorder this activities.



     
There are 2 types of activities- Share and Action. Following are the activities for which system has built in supports-

 UIActivityTypePostToFacebook;
 UIActivityTypePostToTwitter;
 UIActivityTypePostToWeibo;
 UIActivityTypeMessage;
 UIActivityTypeMail;
 UIActivityTypePrint;
 UIActivityTypeCopyToPasteboard;
 UIActivityTypeAssignToContact;
 UIActivityTypeSaveToCameraRoll;
 UIActivityTypeAddToReadingList;
 UIActivityTypePostToFlickr;
 UIActivityTypePostToVimeo;
 UIActivityTypePostToTencentWeibo;
 UIActivityTypeAirDrop;

By Default, UIActivityViewController will show all the available activities. If you want to exclude any of the activity from your application then you can do this by passing the array of activities which you want to exclude to excludedActivityTypes property of UIActivityViewController.

        activityViewController.excludedActivityTypes = [UIActivityTypeAirDrop];

Here, we have excluded AirDrop to be shown in our application.




You can also check when the activity has been completed by calling completionWithItemsHandler.

 activityViewController.completionWithItemsHandler = {
            (activity, success, items, error) in
            println("Activity: \(activity) Success: \(success) Items: \(items) Error: \(error)")
        }

This is the complete method which you can use in your application and connect the action with the Button.
  
    @IBAction func shareAction(sender: AnyObject) {
        
        let text = "Text to share"
        let url : AnyObject! = NSURL(string: "https://www.google.co.in")
        let image : AnyObject = UIImage(named:"download.jpeg")!
        let activityItems : [AnyObject] = [text, url, image]
        
        let activityViewController : UIActivityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
        activityViewController.excludedActivityTypes = [UIActivityTypeAirDrop];
        self.presentViewController(activityViewController, animated: true, completion: nil)
        
        activityViewController.completionWithItemsHandler = {
            (activity, success, items, error) in
            println("Activity: \(activity) Success: \(success) Items: \(items) Error: \(error)")
        }
        
    }


Download the complete Project from here.

Monday, January 19, 2015

How to use both Objective C and Swift in same Project


With the introduction of new language Swift, developers can use this language to develop the iOS project. But most of the APIs are available in Objective C. So if any developer is developing the project in Swift language and they wants to use these Objective C API in there project then they can do it.

Even Developers can create the project with mix and match of both languages Objective C and Swift.

This post will tell you how you can use both language in the application.


Use Objective C in Your Swift project-

If you want to use Swift file in your Objective C project, just create a Objective C file and Xcode will prompt you asking “Would you like to create Objective C Bridging Header?”





When you tap on Yes it will create a Bridging Header file with name "ProductName-Bridging-Header.h"

You can import your Objective C code to Swift by importing your header file in this Bridging header file.





Use Swift in Your Objective-C project-


In order to use Swift file in your Objective C project, just create a Swift file by selecting File> New > Swift.



Now Xcode will prompt you asking “Would you like to create Objective C Bridging Header?”
 You can import your Swift code to any Objective C file by using this syntax-

#import “ProjectName-Swift.h”



You can download the sample app from Github.



Friday, October 17, 2014

How to initialise View controller in Swift?


Initialising ViewController in Swift is different from the Objective C. As in Swift, we have to implement the Required Designated initialiser method and they will not return any value.

If you create a subclass of UIViewController using Swift Language then your file will look like this-

import UIKit

class DetailViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

You have to implement init(coder aDecoder: NSCoder!) and init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) to initialize the ViewController manually. 

After adding the initializer method your ViewController class look like this-

class DetailViewController: UIViewController {

required init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
// Here you can init your properties
}

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

If you will not add this methods in your ViewController File then app will crash and it will show error “fatal error: use of unimplemented initializer” to you.

This error is occurring because we have different initialising behaviour in Swift in comparison to Objective C. Objective C automatically calls the initialising method but in swift we have to add the required initialising method manually.  

Also, Swift initialiser do not return any value as return by Objective C initialiser.

Note-
1) If you are using StoryBoard then add init(coder aDecoder: NSCoder!) in your ViewController class.
2) If you are initialising the ViewController programatically then add init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) in your ViewController class.


Thursday, October 16, 2014

Create custom view using IBDesignable & IBInspectable in XCode6


With XCode6, Apple has added two new attributes for Interface Builder i.e. IBDesignable & IBInspectable. It allows to add controls in the Interface builder.

IBDesignable tells the interface builder that it can load the view & render it. This view should be in framework to work. 

IBInspectable will show the properties declared in custom view class in the Interface builder Inspector.

You can use these two attributes to expand the functionality of your custom view & preview the custom view directly through IB. 

In this post we will create a custom view that renders in the Interface builder.

1) Open Xcode 6 and create a single view application & select the language Swift.

2) Add new target to the project & select Framework & Library & choose Cocoa Touch Framework and named it "CustomView".





3) Create new Swift File "CustomView" subclass of UIView & add it in CustomView framework. Your Swift file look like this

import UIKit

class CustomView: UIView {

}

4) Now you need to prefix your class with keyword @IBDesignable keyword to inform the Interface builder that class will design themselves.

@IBDesignable class CustomView: UIView {

}

5) Add the properties which you want to render in the attributes Inspector of Interface builder. Here i have added 3 properties with a prefix of @IBInspectable & implement the didSet observer to update UI. This will allow the Interface builder to read & write the values of these property in the inspector.

@IBDesignable class CustomView: UIView {

@IBInspectable var borderColor: UIColor = UIColor.clearColor() {
didSet {
layer.borderColor = borderColor.CGColor
}
}
@IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
}

6) Now open the Storyboard & add the view & change the class to CustomView.



7) Open the attribute Inspector, it will show all the properties. You can change the value of this properties & see the results.



You can download the sample app from github.


Before XCode6, we were doing all this things programatically. But now using these two keywords, we can customised the view easily & reduce the code & makes the custom view more reusable.


Note- In Objective C, you can use IB_DESIGNABLE and IBInspectable to render custom view in Interface builder.
Please check this link for more details-