Skip to main content

Moving from Objective-C To Swift!!!


Swift is a new programming language introduced by apple in WWDC-2014. It is one of the fastest adapted programming language.

When apple launch the language I have some question in my mind:

1) What is the need of new programming language?
2) What is wrong with the old one (Objective-c) ?
3) Objective-C will be obsolete?

When i reached office next day and discussed about the new language. They are very happy as they found syntax very similar to other language. Now they can easily relate syntax and concept of swift with the other modern languages and quickly learn iOS development.

Apple introduced the new language with following tagline

1) Safe
2) Modern
3) Powerful

Let have look on the feature of swift:

Variable & Properties in Swift:

In Objective-C properties and ivar are two different entity. You need to declare a property seperately to access ivar from outside of class.

//ViewController.h

@interface ViewController : UIViewController{
    NSString       *name;
}
@end

//AppDelegate.h
ViewController* viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
NSLog(viewController.name); //Error Property 'name' not found on object of type 'ViewController *'

In swift there is no need to declare property separately. When you declare a iVar it is treated as property. In swift property are mainly two types:

Stored Properties:

A property which hold a reference to particular class. It can be constant or variable. Constant stored properties is defined by let and variable by var.

class Time{
    var minute:Int //Variable Stored Property
    var hour:Int   //Variable Stored Property
    let numberOfMinuteInHours = 60  //Constant Stored Property
}

In above example first two are variable stored property and last one is constant stored property. In the above example if you notice in case of first two we are adding the type as well but in last there is no type.
Swift automatically inference the type for you by the value store on right side. That does not mean you cannot add the type in that case.

How you can access it directly with class object ?

let timeObject = Time()
print(timeObject.numberOfMinuteInHours)

Computed Properties:

A property which does not hold any value instead they provided a value at run time. It provide getters to access value after computation and sometime setter to set the value for other store property. now in following example is computed property and it return the current time in a string format.

class Time{
    var minute:Int //Variable Stored Property
    var hour:Int   //Variable Stored Property
    let numberOfMinuteInHours = 60  //Constant Stored Property
    //Computed Properties only with getter
    var now:String{
        return "time is \(hour):\(minute)"
    }
    init(){
        minute = 15
        hour = 3
    }
}

 You can access now:

let timeObject = Time()
print(timeObject.now)

//Output
time is 3:15

Collection in Swift

Swift introduce two new types of collections Array and Dictionary.  Wait a minute we already have same collection type provided by cocoa framework NSArray and NSDictionary.

Why apple introduce two new types if we already have it seems like two different books for the same subject. Nope there is differnce:

1) In swift Collection are Typed Collection. i.e Collection already know which type of variable you can store in array or dictionary. If you store any other type then it will generate error.

var blogAddress:[String] = ["swift", "language", "blogspot", ".com"]
print(blogAddress)

In above case we define a blog address array with type array of String. Now try to insert any number in that array Error!!

blogAddress.append(1)
//Error: Cannot convert value of type 'Int' to expected argument type 'String'

Now Try to do same thing in NSMutableArray:

var nsBlogAddress:NSMutableArray = ["swift", "language", "blogspot", ".com"]
nsBlogAddress.addObject(NSNumber(int: 1))
//Great No Error

2) Swift collection will work with scaler data type. You can directly add integer value into array or dictionary without converting into object.

var swiftReleaseYear = [2, 0 , 1]
//OPPS swift is not too old
swiftReleaseYear.append(4)
print(swiftReleaseYear)

You cannot add a integer value to NSMutableArray.

3) Array and Dictionary in swift is value type.  It behave like a scaler type when you assign a array to other array then it is a new copy. So be careful when you use swift Array and Dictionary it will not behave like NSArray and NSDictionary.

Try the Following code:

var swiftReleaseYear = [2, 0 , 1]
swiftReleaseYear.append(4)
var swiftReleaseYearCopy = swiftReleaseYear
swiftReleaseYearCopy.removeLast()
print("swiftReleaseYear:",  swiftReleaseYear);
print("swiftReleaseYearCopy:",  swiftReleaseYearCopy);

//Output:
swiftReleaseYear: [2, 0, 1, 4]
swiftReleaseYearCopy: [2, 0, 1]

When you try this with NSMutableArray then both the array will have same values.
Now you can choose which book(collection) to read based on the requirement.

Classes and Struct in Swift

Classes in swift can be defined with keyword "class". In swift there is no base or root class require. You can simply define a class without inherit from any other class.

class Body{
    var numberOfEyes = 2;
    var numberOfEars = 2;
    var numberOfNose = 1;
    var hasMouth = true;
    
    func canSpeak() -> Bool{
        return hasMouth;
    }
}

If you want that your object should behave like Cocoa object then you can inherit it from NSObject.
Similarly you can inherit from any cocoa class or your defined class. When you inherit the class from any objective-c class then their will be runtime behaviour changes:

Swift classes that are subclasses of NSObject:
  • are Objective-C classes themselves
  • use objc_msgSend() for calls to (most of) their methods
  • provide Objective-C runtime metadata for (most of) their method implementations
Swift classes that are not subclasses of NSObject:
  • are Objective-C classes, but implement only a handful of methods for NSObject compatibility
  • do not use objc_msgSend() for calls to their methods (by default)
  • do not provide Objective-C runtime metadata for their method implementations (by default)
Subclassing NSObject in Swift gets you Objective-C runtime flexibility but also Objective-C performance. Avoiding NSObject can improve performance if you don't need Objective-C's flexibility.
Source : StackOverflow

Struct in swift are much like classes. You can add ivar and method just like classes.

struct User{
    var username : String
    var password : String
    var userrole : String
    
    func isValidUser(){
        if self.username.isEmpty || self.password.isEmpty{
            print("invalid user")
        }
    }
}

You can create a object of struct and use just like a class in swift.

let newUser = User(username: "", password: "", userrole: "");
newUser.isValidUser()

One Thing you can notice here while creating a object of struct I initialise the each member. If I have not done that then it will be compilation error. So every ivar of class and struct should be initialise in init method. It is compulsion and advantage is you do not miss or use any uninitialize value which may cause crash for your application.

Same question single subject with two books!! What is wrong with the apple? Ohh again I missed the point:

1) Inheritance is not possible in case of struct. So if your need is User can also has type. Like Admin User, Employee, Manager etc. Then in that case you need inheritance you should go with classes.

2) Struct are value type in swift while classes are reference types. So Struct object will behave like a scaler type.

var user1 = User(username: "", password: "", userrole: "");
var user2 = user1;
user2.username = "swift";
print("User1 name is: \(user1.username)")
print("User2 name is: \(user2.username)")

//Output:
User1 name is: 
User2 name is: swift

You can see on assigning a value it just copy the ivar like a scaler type. So based on your requirement you can choose struct or class.

nil is still there in Swift! With Magic Value!

We already discuss above each member of class is initialize in init method of class before super call. What if you need to initialise a variable at run time. For that swift has optional type:

class MyProfile{
    //Optionaly type
    var name:String?
    var profilePic:UIImage?
    var friendCount:Int
    
    init(){
        friendCount = 0
    }
}

In above case there will not be compilation error because other two ivar is optional type. You can declare any optional type with the expected type of variable with question mark append.

What is the default value in this case and how we can assign a value in optional type?

1) Default value is nil so you can directly check any optional type with nil value if it is nil then no value is present.

let profile = MyProfile()
if(profile.name == nil){
   print("no value assigned")
}

You can even check nil with scaler data type.

Nil in swift is different from the objective -c nil:

1) nil in swift means no value. It does not point to void pointer or -1. It just means no value is present. nil is only assignable to optional type. If you go the the definition of nil then it is an optional enum with two case. None point to no value and other is value is present.

2) nil in swift can be applied to scaler type as well but in case of objective-c you can check with pointer type only. It is due to definition of nil in objective-c which is void pointer.

Value Type and Reference Type Variable

1) The behaviour of value type is when you assign it to any other variable it just copy like scaler type. On the other hand reference type just increase the retain count.

2) Enum, Struct , Array , Dictionary are value types in swift and on the other hand classes are reference types. 

Comments

Post a Comment

Popular posts from this blog

Using Swift with Objective-C and Cocoa

Swift gain so much popularity in very short duration and people are really very excited to develop the application in swift. So, the number of application in swift is increasing exponentially. However, there are vast numbers of legacy applications which are built using objective-c and now in the process of migration or mixture (Objective-C & Swift). Today, I will explain how to integrate swift in the existing Objective-c application and vice versa. Let suppose you are working on an application written totally in objective-c and now you want to implement all the new feature in swift then you can follow the following steps to use both the languages in a single application: Access Swift Class into Objective-C 1) Add a new swift file in your application by selecting File ->  New->File. Then select a swift file as an   option. 2) As you click on "Create", a dialogue box will appear which give you an option to create   a bridging Header....