Pages

Showing posts with label ios. Show all posts
Showing posts with label ios. Show all posts

Sunday, 29 June 2014

Programming in Swift [Basic]

Swift is a new programming language introduce by Apple at WWDC 2014. This language supports iOS7+ and you can integrate Swift with Objective-C and vice versa. 

I am covering Swift in three parts: Basic, Intermediate, and Advance.  This post is all about basic of Swift Programming language. 

Its a brand new language and to learn this you don't require prior knowledge of Objective-C, but basics knowledge of C programming and Object Oriented Programming required. To execute Swift code you need latest version of development IDE (Xcode 6).


Playground

      We are going to use new document type ".playground" to experiment with Swift. Its supported by Xcode 6. Playground allow you to write/edit the swift code and see the result immediately side by side. 

Xcode create a playground for cocoa by default, you can create iOS playground through File --> New --> File --> iOS/Source/Playground. Cheers!! now you have a playground to play with Swift. Playground comes with some default code, it saying Hello playground, now delete the line starting with var keyword, We will discuss var latter in this tutorial. 

As usual say "Hello" to playground by printing a string. 



    println("Hello Playground")


Can you  see the "Hello Playground" message in right pan? No right!! Okay so to see the result, you need to open the console output pan (View --> Assistant Editor --> Show Assistant Editor). In third pan you can see the "Hello Playground" message. Okay! so what is the use of second pan? It shows value of variables and expressions. So whatever you print or draw comes under console pan.


Constants & Variables

      You can use "let" keyword to create constants and "var" keyword to create variables. I have created two variables below :


    //constant 
    let minimumPrice = 18.5//Double type

    //Variables
    var myVariable = 42 // Inter type
    var blogName = "Coding for Bugs" //String type


You have just created one constant as "minimumPrice" and two variables: "myVariable" is of type Integer and "blogName" is of type String. Wait we have not given any type, how swift is deciding the type of variable? Okay so swift infer the type of variable from its value. So as soon as you assign any variable a number, its become Int. If you assign string its become string, and so on...

Swift is a type safe language, that means you can't assign a int value to a String variable. So once type is infer you can't change the type of variable by assigning another type of value. If you will do so, It will be reported as compile time error.

As you know Swift infer the type itself but you can also give the desire type to a variable or constant at time of declaration, this is known as Type Annotation. For example lets create one Double and String variable. 



    var price: Double = 13.0 //Swift infer floating number to Double by default

    var helloMessage: String = "Hello reader"


The colon(:) in declaration means of type so that above declaration can be read as: 
    Declare a variable called price that is of type Double.
    Declare a variable called helloMessage that is of type String.

Semicolons

      “Unlike many other languages, Swift does not require you to write a semicolon (;) after each statement in your code, although you can do so if you wish.”

Data types in Swift

  • Int Its used for whole numbers. Ex: var num: Int = 32
  • Float Its used for numbers with decimal points. Ex: var fNum: Float = 32.1
  • Double Its used for bigger numbers with decimal points. Ex: var dNum = 32.6374
  • String Its used for ordered sequences of characters. Ex: var pi = "π",
       var name: String = "you name"
  • Bool Its used for true or false. Ex: var isRead: Bool = false
  • Array Its used for collection of same type data. Ex: let array = String[]()
  • Dictionary Its used for collection of same type data and key.         Ex: let emptyDictionary = Dictionary<String, Float>()
  • Tuple Its used for collection of objects of any type. Use () to create tuple.
         
    Ex: var HTTP404Error = (404, "Not Found")

Tuples

      Tuples group multiple values into a single compound value. The values in tuples an be of any types and don't have to be of the same type. This is the primary difference between Array and Tuples.


    // 1. Creating tuple
    let http404Error = (404, "Not Found") //type is (Int, String), and equals (404, "Not Found")”

    // 2. Accessing elements of tuple
    let (statusCode, statusMessage) = http404Error
    println("The status code is \(statusCode)") //String interpolation: use \() to insert any value in string
    println("The status message is \(statusMessage)")

    // 3. Ignoring any element in tuple, Use underscore "_" to ignore any value
    let (justTheStatusCode, _) = http404Error
    println("The status code is \(justTheStatusCode)")

    //4. Accessing individual element values in tuple using index number
    println("The status code is \(http404Error.0)")
    println("The status message is \(http404Error.1)")

    // 5. Naming individual elements in a tuple when tuple defined
    let http200Status = (statusCode: 200, description: "OK")
    println("The status code is \(http200Status.statusCode)")
    println("The status message is \(http200Status.description)")


In above code we have created two tuples named as http404Error and http200Status.and in other parts we have used first tuple in different ways. 

1. The (404, "Not Found") tuple groups together an Int and a String to give the HTTP status code two separate values: a number and a human-readable description. It can be described as “a tuple of type (Int, String)”.

2. We have decompose tuple in different constant named as status code and status message. We have inserted value of those constant in string using String Interpolation.

3. We have used _ to ignore second element "status message" of tuple. 

4. We have use elements index number to access their value. Index start from 0.

5. We have given names to individual elements of tuple. These name helps us in accessing individual elements. 

NOTE: don't forget to see the log by opening console(opt + cmd + enter)


String Interpolation

      Its include the name of a constant or variable as a placeholder in a longer string, and to prompt Swift to replace it with the current value of that constant or variable. Wrap the name in parentheses and escape it with a backslash before the opening parenthesis. Ex. println("The status message is \(statusMessage)")

Optionals

      Optionals variable either contains a value or does not contain any value at all. For example lets say you have a string value and you are trying to convert it to number/ Int. It not possible that every string can be converted into an integer. Thats why swift toInt method of String class return an optional value. 

    let possibleNumber = "123"
    let convertedNumber = possibleNumber.toInt()


Because the toInt method might fail, it returns an optional Int, rather than an Int. An optional Int is written as Int?, not Int. The question mark indicates that the value it contains is optional, meaning that it might contain some Int value, or it might contain no value at all.

If you will try to print or use a optional value directly then it might lead to a crash because it might be nil. It means no value. Swift nil is different from Objective-C nil. In case of Objective-C its a pointer to nil but in Swift nil is not a pointer. Simply it is the absence of a value of a certain type. 

Note: Optional of any type can be set to nil not only Object type.

Unwrapping Values of optionals:    
     You can use an if statement to find out whether an optional contains a value. If an optional does have a value, it evaluates to true; if it has no value at all, it evaluates to false.

Once you’re sure that the optional does contain a value, you can access its underlying value by adding an exclamation mark (!) to the end of the optional’s name. The exclamation mark effectively says, “I know that this optional definitely has a value; please use it.” This is known as forced unwrapping of the optional’s value:



    if convertedNumber {
        println("\(possibleNumber) has an integer value of \(convertedNumber!)")
    } else {
        println("\(possibleNumber) could not be converted to an integer")
    }


If you try to use ! to access a non-existent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.

Using if else each time is boring and time consuming So swift has introduce a new concept call Optional binding, that we can use to Unwrap the value. Optional Binding is used to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable. Optional binding can be used with if and while statements to check for a value inside an optional, and to extract that value into a constant or variable, as part of a single action.



    if let actualNumber = possibleNumber.toInt() {
        println("\(possibleNumber) has an integer value of \(actualNumber)")
    } else {
        println("\(possibleNumber) could not be converted to an integer")
    }
    // prints "123 has an integer value of 123


It will execute else part when it is not possible to convert the given string into a number. 

Operators

      Swift supports all Objective-C operators where some of them are modified and others same as objective-C. Its also support operator overloading that we will discuss in Advance tutorial of this series. 

All arithmetic operator are same as C except reminder operator (%). Now reminder operator work with floating point and negative number. Ex: 8 % 2.5   // equals 0.5 and -9 % 4   // equals -1 

Increment, decrement, unary minus, logical, and compound assignment operator as same as C. 

Swift supports all C based comparison operator and also introduced two new comparison operator (=== and !==). Which you use to test whether two object references both refer to the same object instance.

Range Operator 
   Swift includes two range operators, which are shortcuts for expressing a range of values:

  1. Closed Range Operator(a...b)
         The  closed range operator (
    a...b) defines a range of values that runs from a to b, and include a and b.
  2. Half-Closed Range operator(a..<b)
        Half-closed range operator (
    a..<b) define a range of values thats run from a to b but does not include b. Thats why its called half-closed range. See the below example: 


    for index in 1...5 {
        //here index is of type Int. No need to write var before index
        println("\(index) times 5 is \(index * 5)")
    }
    // 1 times 5 is 5
    // 2 times 5 is 10
    // 3 times 5 is 15
    // 4 times 5 is 20
    // 5 times 5 is 25

    //If you change above range to Half-Closed(1..<5) then it will only up to 20.



Control Flow

      Swift supports all control flow statement of Objective-C with a huge modification in Switch statement. Its also change the way we write conditions, Now we don't need to write brackets () around the condition you can directly write the condition followed by flower braces {}. Examples:



    // If else  conditions
    var a = 2
    var b = 6
    if a > b {
        println("Yes!! \(a) is not greater than \(b)")
    } else {
        println("No!! \(a) is greater than \(b)")
    }

    //while loop 
    while a != b {
        a += 2
        println("a incremented to \(a)")
    }



Switch Statement
      In swift switch statement has below changes 
  • No need to write break statement. Swift is smart enough to break out of matched case.
  • Body of each case must contain at least one executable statement. to ignore any case use break statement.
  • Multiple matching can be separated by comma. Ex: case 2,3,4: .
  • Switch value can be matched against any built in type: Int, Double, String, Tuple, Range.
  • switch statement must be exhaustive. Using default case is easy way to get rid of this condition. 


    let count = 3_000_000_000_000 //you can use _ in number to make it redable
    let countedThings = "stars in the Milky Way"
    var naturalCount: String
    switch count {
    case 0,1:
        naturalCount = "very few"
    case 2...3:
        naturalCount = "a few"
    case 4...9:
        naturalCount = "several"
    case 10...99:
        naturalCount = "tens of"
    case 100...999:
        naturalCount = "hundreds of"
    case 1000...999_999:
        naturalCount = "thousands of"
    default:
        naturalCount = "millions and millions of"
    }
    println("There are \(naturalCount) \(countedThings).")
    // prints "There are millions and millions of stars in the Milky Way.


In above example we are matching a number and commenting about number of stars. In case first we are trying to match multiple values against some value to switch. In rest of conditions we we are trying to match switch value against range of value. 

Without the default statement this switch will not become exhaustive  because its not matching all possible value of count. Thats means every possible value of the type being considered must be matched by one of the switch case.

Switch and Tuple: We can also use tuple to test multiple value in switch statement. You can also bind the elements of tuple to variable or constant. See below example:



    let somePoint = (1, 1)
    var comment:String

    switch somePoint {
    case (0, 0):
        comment = ("(0, 0) is at the origin")
    case (_, 0):
        comment = ("(\(somePoint.0), 0) is on the x-axis")
    case (0, _):
        comment = ("(0, \(somePoint.1)) is on the y-axis")
    case (-2...2, -2...2):
        comment = ("(\(somePoint.0), \(somePoint.1)) is inside the box")
    case (let x, let y):
        ("(\(x), \(y)) is outside of the box")
    }


Above code will print "(1, 1) is inside the box" and in above switch statement we have not used default statement, because without that our switch statement is . If you wish to use default you can replace case (let x, let y) by default statement and replace x and y with indexes of individual elements. 

Thats it, in basic. In next part we will discuss Collections, Functions, Class, Closures etc.
Thanks for reading!! Please do not forget to leave your valuable comments. Bye Bye !!

Wednesday, 21 March 2012

Sharing data among iOS applications using UIPasteboard

Hello Friends,
As iOS apps have their own sandbox and one app can't read data of other application, for security reason its look good and really its good.One day i got a requirement in which i need to share data of one app with other app.First i thought it is not possible in an environment like sandbox, i searched on google and got a luck on  stackoverflow saying use UIPasteboard but a programmer like me expect some code. That day i  did not get any thing more than a little luck saying don't worry it is possible using UIpasteboard so in this post i am going to talk about UIPasteboard and write some basic codes.

UIPasteboard:
   UIPasteboard is a class given in UIKit.framework.You can use it to share data within the application and with other applications.

I am using two application to demonstrate the use of UIPasteboard.
  1. PBWriter
  2. PBReader 
let's create first application named as PBWriter or you can name something else.This application take some input from user and save those in UIPasteboard.User Interface of this application look like this - 

Enter data in above fields, hit "Save in PB" button it will save the data in Pasteboard.Oh! i have not discussed any thing about code. let's write code -

You can use any of following methods to create/get Pasteboard object, i am using "pasteboardWithName:create:"
  • +generalPasteboar //use this to get system pasteboard
  • +pasteboardWithName:create: //use this to create your own pasteboard

//use reverse DNS notation to keep you Paste board unique 
NSString *PBNAME = @"com.codingForBugs.PBDemo.PBDemo";


 UIPasteboard *pb = [UIPasteboard pasteboardWithName:PBNAME create:YES];//create a new PB if does not exists 

By default custom pasteboards are not persistent, you need to make it manually.If not required in your case just ignore it.

//pass yes to make pasteboard persistent 
[pb setPersistent:YES];


If you are not setting Persistent  property to YES, remamber that pastboard will be removed when your application quit.Now we have pasteboard and we need to write user information in it.

Note:Pasteboard will be removed when application uninstalled not matter it is persistent or not. 

There are some predefine properties in which you can write your data like string, strings, url,image, items etc.For example you have only one string you can use "string" property of UIPasteboard. If you want to save more than one item than better to use items properties like - 
    NSMutableArray *pbValues = [[NSMutableArray alloc] init];
    NSDictionary *d1 = [NSDictionary dictionaryWithObject:name.text forKey:@"name"];
    NSDictionary *d2 = [NSDictionary dictionaryWithObject:s1Value.text forKey:@"dob"];
    NSDictionary *d3 = [NSDictionary dictionaryWithObject:s2Value.text forKey:@"age"];
    NSDictionary *d4 = [NSDictionary dictionaryWithObject:s3Value.text forKey:@"height"];
    [pbValues addObject:d1];
    [pbValues addObject:d2];
    [pbValues addObject:d3];
    [pbValues addObject:d4];
    
    //save all items in pasteboard
    [pb setItems:pbValues];
When you will hit "Save in PB" it call a method "saveButtonClicked:", this method look like this
- (IBAction)saveButtonClicked:(id)sender {
    //get paste board 
    
    UIPasteboard *pb = [UIPasteboard pasteboardWithName:PBNAME create:YES];//create a new PB if does not exists 
    
    //make PB persistent. PB will be deleted when its owner application uninstalled
    [pb setPersistent:YES];
    
    //save values in PB with unique key so thet other application can read it
    NSLog(@"name = %@",name.text);
    NSMutableArray *pbValues = [[NSMutableArray alloc] init];
    NSDictionary *d1 = [NSDictionary dictionaryWithObject:name.text forKey:@"name"];
    NSDictionary *d2 = [NSDictionary dictionaryWithObject:nameValue.text forKey:@"dob"];
    NSDictionary *d3 = [NSDictionary dictionaryWithObject:ageValue.text forKey:@"age"];
    NSDictionary *d4 = [NSDictionary dictionaryWithObject:heightValue.text forKey:@"height"];
    [pbValues addObject:d1];
    [pbValues addObject:d2];
    [pbValues addObject:d3];
    [pbValues addObject:d4];
    
    //save all items in pasteboard
    [pb setItems:pbValues];
    
}

If you calls setItems: again, it overwrites previous values to prevent it use addItems: as [pb addItems:newValues]
Now we have finish the writer part we need to write a reader application that will read the data save in pasteboard. Reader app ui look like this - 
When you will hit the "Read PB" button one pop-up will come displaying whatever information we have saved in pasteboard.To read data first we need to get the pasteboard, we will retrieve dat using any of following function - 
  • dataForPasteboardType:
  • string
  • strings
  • items and so on 


Data will be returned in form of NSData and of particular type same as properties. For example if you are assigning value to string property it will return string, when we access using other method, we need to convert it in string from NSData. When you will hit "Read PB" button "- (IBAction)readPB:(id)sender" called this method look like this -
- (IBAction)readPB:(id)sender {
    //get pasteboard with predefine name
    UIPasteboard *pb = [UIPasteboard pasteboardWithName:PBNAME create:NO];//no because we doesn't want to create a new one 
    if (pb) {
        NSArray *dataArray = [pb items];
        NSDictionary *name = [dataArray objectAtIndex:0];
        //valuesInPb use to create message text
        NSString *valuesInPb = [NSString stringWithFormat:@"Name = %@\n",
                                [[NSString alloc] initWithData:[name valueForKey:@"name"] encoding:NSUTF8StringEncoding]];
        NSDictionary *info = [dataArray objectAtIndex:1];
        valuesInPb = [NSString stringWithFormat:@"%@D.O.b = %@\n",valuesInPb,
                      [[NSString alloc] initWithData:[info valueForKey:@"dob"] encoding:NSUTF8StringEncoding]];
        NSDictionary *info1 = [dataArray objectAtIndex:2];
        valuesInPb = [NSString stringWithFormat:@"%@Age = %@\n",valuesInPb,
                      [[NSString alloc] initWithData:[info1 valueForKey:@"age"] encoding:NSUTF8StringEncoding]];
        NSDictionary *info2 = [dataArray objectAtIndex:3];
        valuesInPb = [NSString stringWithFormat:@"%@Height = %@\n",valuesInPb,
                      [[NSString alloc] initWithData:[info2 valueForKey:@"height"] encoding:NSUTF8StringEncoding]];
        [self showText:valuesInPb target:self];
        NSLog(@"%i",[dataArray count]);
    }else{
        [self showText:@"PB doesn't exists.\nYou should run PBWritter app first" target:self];
    }
}


//this method is use to display the alert vew
-(void)showText:(NSString*)textMessage target:(id)target{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"pbReader" message:textMessage delegate:target cancelButtonTitle:@"OK" otherButtonTitles: nil];
    [alert show];
    [alert release];
}
I think it  may help you, plese leave you comments.bye bye!