Sunday, February 28, 2016

Swift Tutorial - Part 3 - Playground, enum, Optional, casting

Playground, enum, Optional, cast


Video Description

Playground

Swift has a very cool feature that allows you to write a code and get a quick result at the right side of the screen. In order to make a Playground file you should open the Xcode. From the left hand side of the screen select "Get started with a playground". From the opening window add a name for your file and choose the platform you want to code (for this tutorial select iOS) and then give it a location to save. t opens a blank page that you can write your code there. In order to test the playground, copy paste the code that we wrote in previous tutorial.

enum

There are 3 categories that we can code in Swift (class, struct and enum). One of the categories are called enum. Here is how we define enum in swift:

enum Gender {
    case Male
    case Female
}

Then we can use it like bellow:
var huxTek: Gender
huxTek = Gender.Male

We can alsowrite only .Male like this:
huxTek = .Male

we can have a switch for this enum like bellow:
switch huxTek {
    case .Male:
        print("A man")
    case .Female:
        print("A woman")
}
Optional !?

One of the important subjects that you should get familiar early in the game is optional type. You gonna see optional type in many place and actually you will use it a lot during  swift programming. That's why I dedicated a separate session just for Optional type.

Optional is just an enum with 2 cases like bellow:
enum Optional{
    case None
    case Some(T)
}
One case is none or null and the other case is something and something could be any type (String, Array, Int, ...). In order to explain it in an example, lets define a dictionary.
var myDict = [String:String]()
myDict = [
    "key1": "val1",
    "key2": "val2",
    "key3": "val3"
]
print(myDict["key1"])
The output of the above code is:
"Optional("val1")\n"

Unwrap Optional !

The reason that we have the word Optional around the val1 is because myDict["key1"] returns an optional. It means that it could have some value or nil. In order to unwrap the optional you should put ! after the optional value like bellow:
print(myDict["key1"]!)
The output of the above code is:
"val1"\n
Optional binding

In order to assign an optional type into a variable safely we should use the following pattern:
if let key1Val = myDict["key1"] {
    print(key1Val)
}
Cast
Imagine our dictionary includes key as String and value as String or another dictionary. The way we define it is like bellow. Since we don't know if it's String or a dictionary we just use a type called AnyObject. It means any type. 

var myDict = [String:AnyObject]()
myDict = [
    "key1": ["subKey1":"subVal1"],
    "key2": ["dasda", "asdasd"],
    "key3": "val3"
]
If we define a variable to get "key1" value, it returns the type as AnyObject because it doesn't know the type. In order to define a type for it we need to cast it like bellow:
    var sub1Key1Value = myDict["key1"] as! [String:String]
Now it knows that the type is a dictionary with key as String and value as String. In order to safely check if an object is a certain type we can use "is" function as bellow: 
if myDict["key1"] is [String:String] {
    var sub1Key1Value = myDict["key1"] as! [String:String]
    print(sub1Key1Value["subKey1"]!)
}
?
We have learned how to unwrap optional into a type, now we need to know how to define an optional type. It's very easy, you just have to add a question mark after the type of the variable.
var myString: String?
It's very important to know that after we put question mark, the variable is no longer a String type. It's type optional that could be String. In order to print it out we need to unwap it with ! 

Sunday, February 7, 2016

Swift Tutorial - Part 2 - Swift Foundation Frameworks

Swift Foundation Frameworks


Video Description

var

In order to define a variable in swift we use var at the beginning of the variable then the name of the variable and at the end we define the type of the variable like bellow:
var myVariable:String = "Some String Value"

let

If the value of a variable doesn't change during it's life cycle, we should use let instead of var, otherwise compiler would show warning. We define a variable with let like bellow: 
var myVariable:String = "Some String Value"

print

In order to print on console we can use print function in swift, here is the example:
print("This text will be printed in console after running the application")

String

From the name of this class it's obvious that it's for defining strings. Here is an example:
var myVariable:String = "Some String Value"

Double

let version: Double = 1.0
print(version)

Int

let myInteger: Int = 2
print(myInteger)

Bool

let isAwesome: Bool = true
print(isAwesome)

Array

We have 2 ways to define an array, here is the first one:


var letters = Array<String>()
letters = ["a", "b", "c", "d"]
print(letters[2])

The second way is to just define it like bellow:



var letters = ["a", "b", "c", "d"]
print(letters[2])

We can iterate the array objects like bellow:


var numbers = [Int]()
numbers = [1, 2, 3, 4]
        
for number in numbers {
   print(number)
}

Dictionary

We have 2 ways to define a dictionary, here is the first one:
var dict = Dictionary<String, Int>()
dict = ["One": 1, "Two":2]

The second way is to just define it like bellow:
var dict = [String:Int]()

We can iterate through keys and values of a dictionary like bellow:
for (key, value) in dict {
   print("Value for \(key) is \(value)")
}

NSObject, NSNumber, NSData, NSDate

These classes are inherited from Objective-c language and we will talk about them later

Saturday, January 30, 2016

Swift Tutorial - Part 1 - Hello World App

Introduction to Swift


Video Description 


Before starting Swift tutorial we should know that some tutorials that I have created for Objective-C language are valid for swift, like the first three ones that we will introduce here.

Download Xcode

Here is the link for both video and description of how we can download the Xcode ( iOS development environment)

http://huxtek.blogspot.com/2013/12/fist-post.html

Create Hello World App

Creating Hello World App in Swift is almost identical with Objective-C one. It has just one small difference which is choosing the language of programming. Instead of Objective-C, you should choose Swift.

http://huxtek.blogspot.com/2013/12/creating-hello-world-app-for-iphone-ipad.html

Xcode components

In this tutorial I have explained each components of Xcode and even after 2 versions of iOS (8 and 9) we have similar layout for Xcode menus and button. They just changed the icons. So in order to get familiar with these components please watch this tutorial.

http://huxtek.blogspot.com/2013/12/description-of-xcode-components.html

Sunday, November 1, 2015

iOS Tutorial - Part 35 - Popover for iPhone and iPad

Create Popover for iPhone and iPad


Video Description 
Sometimes we don't want to cover the whole view for showing another view controller. This is mostly for iPad because it has larger screen. But it's also possible to show popover on iPhone. Creating a popover is very easy, it's a type of connection between view controllers. All you have to do is to connect the button or whatever action you want to another view controller by control dragging and the choose "Present As Popover", that's it. This will show popover only for iPad but for iPhone you have to do one more step.

Popover for iPhone

iOS 8 offered an easy way to implement popover for iPhone. All you have to do is to declare UIPopoverPresentationControllerDelegate:
@interface ViewController () <UIPopoverPresentationControllerDelegate>

Then put the view controller delegate equal to self:
self.popoverTvc.popoverPresentationController.delegate = self;

And at the end implement the delegate method:
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
    return UIModalPresentationNone;
}

Adapt the popover size based on the content

The popover that we created so far has not a proper size. The default size is very big and unnecessary. In order to fix this issue we need to override the prefferedContentSize property of the popover view controller. In this example we have a table view and we need to get the size of the table view and show only the cells that has value (not empty cells).
if (self.tableView && self.presentingViewController) {
        self.preferredContentSize = [self.tableView sizeThatFits:self.presentingViewController.view.bounds.size];
    }
First we chech if tableView and presentingViewController (The view controller that is presenting at that moment) is not nill. then we set the preferredContentSize equal the tableiew size that fits presentingViewController size.

Download

Download this app here

Saturday, September 5, 2015

iOS Tutorial - Part 34 - Split View Controller, iPad apps

Create an iPad app


Video Description 
In order to create an iPad app, all we have to do is to select iPad from the dropdown menu during the process of creating the application. It's also possible to make the existing app working on the iPad as well but this would be the subject of the future tutorial. For now we select iPad instead of iPhone when we want to create a new project.

Split View Controller

In order to create a master details view we need to use Split View Controller. If we start a new project by selecting Single View application, we can drag Split View Controller from Object library into Xcode interface. But in this tutorial we use the easiest way and instead of using single view app, we select Master-Detail Application so it adds some default classes and views for us. In Master part we have a tableView and we connect the cell via control+drag to the details view and from the opening popup for type of connection, we select the "Show Detail".

Download

Download this App from HERE.

Friday, August 7, 2015

iOS Tutorial - Part 33 - Core Data II

Core Data II


Video Description 
In previous session we learnt how to add items inside of database, in this tutorial we will learn how to search through the database and also the proper way of adding items inside of database.

Proper way of adding items in database

Previous tutorial showed the easiest way of adding items inside of database but here is the best practice of adding data into database:
+ (Students *)addStudentInfoFromDictionary:(NSDictionary *)studentInfo
{
    AppDelegate *appDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    
    Students *studentEntity = nil;
    
    NSString *studentId = studentInfo[@"studentId"];
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Students"];
    request.predicate = [NSPredicate predicateWithFormat:@"studentId = %@", studentId];
    
    NSError *error;
    NSArray *matches = [context executeFetchRequest:request error:&error];
    
    
    if (!matches || error || ([matches count] > 1))
    {
        //Handle Errors
    }
    else if ([matches count])
    {
        //Returns the existing object
        studentEntity = [matches firstObject];
    }
    else
    {
        //Create a new Object
        studentEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Students" inManagedObjectContext:context];
        studentEntity.studentId = [studentInfo valueForKey:@"studentId"];
        studentEntity.name  = [studentInfo valueForKey:@"name"];
        studentEntity.lastName = [studentInfo valueForKey:@"lastName"];
        
        NSError *error;
        if (![context save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }
    }
    return studentEntity;
}
First we check for a unique identifier in order to avoid duplicating data. In this example studentId is our unique identifier. We request a fetch through the database via NSFetchRequest. It needs the entity name in order to be initialized. Our entity name is "Students" so we add Students as entity name. Then we define a predicate. Predicate is for defining our query for search. The following line means, give me all the data that has studentId that is equal to the one that is passed to this function.
[NSPredicate predicateWithFormat:@"studentId = %@", studentId];
Since during fetch request we may get some errors, we define NSError. Then we execute the fetch request and assign the result to an array because it returns all matched results as an array. Now we have to check the matches. If matches null or it's more than one item or error is not null, we know that we have error and this if statement is for handling errors. matches should not be more than one because studentId is unique and we should have only one instance of that ID.
If matches not null and equals one, it goes to the second statement. If it goes to this statement it shows that we had this item already in the database so we just return the mach that we found.
If non of the above statements get valid, we know that it's totally new item and we add it to the database. The implementations is exactly like the one that we had in previous session.

Query the database (Search through Core Data)

Suppose that we want to search the database to find all the matches for a specific name or specific lastname. The following method can search the database to find all matches for the name and lastname that you specify. It uses the same NSFetchRequest format that we used above. Also the same NSPredicate but with different format. This time we want to check for name, so it searches for name. If we want to search the name and lastname, we put AND in our format. There are other things that we can use in our format like OR. Based on your needs you can find the proper format and pass it into the predicateWithFormat. The second function is a helper function to create a temporary dictionary for each result.
+ (NSArray *)searchStudensByName:(NSString *)name lastname:(NSString *)lastname
{
    AppDelegate *appDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    
    NSError *error;
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Students"];
    request.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND lastName == %@", name, lastname];
    
    NSArray *fetchedObject = [context executeFetchRequest:request error:&error];
    NSMutableArray *results = [[NSMutableArray alloc] init];
    
    for (Students *studentEntity in fetchedObject)
    {
        [results addObject:[self createObjectFromEntity:studentEntity]];
    }
    return results;
}

+(NSDictionary *)createObjectFromEntity:(Students *)studentInfo
{
    NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
    tempDict[@"name"] = studentInfo.name;
    tempDict[@"lastName"] = studentInfo.lastName;
    tempDict[@"studentId"] = studentInfo.studentId;
    return tempDict;
}

Download

Download this App from HERE.

Sunday, June 28, 2015

iOS Tutorial - Part 32 - Core Data I

Core Data I


Video Description 
In iOS we have two options for adding data into database. First option is Core Data and second option is SQLite. Since Core Data is more powerful and could be used in more object oriented way, so we will only talk about the first option, which is Core Data.

Add Entity, Add Attributes

If you check mark core data when you create the application, you would see a file with suffix "xcdatamodeld". If you click on it you would see
 
You can press plus button at the bottom of the page to add a new entity. Then you can add attributes by pressing add button under the attributes section. Each attribute needs a type. Here in the above screenshot all attributes are type string. Once we add all of the entities and attributes we want, we should create NSManagedObject subclass in order to have more object oriented programming style. To create NSManagedObject subclass, click on the file with suffix "xcdatamodeld" on your project structure and the from the tool menu, select Editor/Create NSManagedObject Subclass... .
Presee Next and then select the entity you want to create the subclass and then hit Create button to create your NSManagedObject class. If you open the created files you would see all of the attributes that you added for that entity. we can go ahead and add our a method in .m file for adding objects into database but it's not the best practice.

Category Files

Because later on the we may add more attribute into the application and if we auto generate the NSManagedObject superclass we would lose our functions, so it's better to add a Category class for this subclass. In order to create a category file, choose File / New / File ... Then select Objective-C File.
In the next screen give your file a name, and select a File Type as Category and select your entity name for the class field. Finally hit Create to create the Category file.

Add objects into database

Now we can add our method for adding objects into database. Here is the method we can create for adding objects:
+ (Students *)addStudentInfoFromDictionary:(NSDictionary *)studentInfo
{
    AppDelegate *appDelegate= (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    
    Students *studentEntity = nil;
    
    //Create a new Object
    studentEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Students" inManagedObjectContext:context];
    studentEntity.studentId = [studentInfo valueForKey:@"studentId"];
    studentEntity.name  = [studentInfo valueForKey:@"name"];
    studentEntity.lastName = [studentInfo valueForKey:@"lastName"];
    
    return studentEntity;
}
First two lines gets the context. Before using these two lines make sure you #import "AppDelegate.h" file. Next we create the instance of Students entity. We initialize it with the method insertNewObjectForEntityForName. Finally we can use entity properties to add our object value. Since we have this class in .m file we need to declare it in .h file so other classes can use it. So we should add the following line in the header file:
+ (Students *)addStudentInfoFromDictionary:(NSDictionary *)studentInfo;
Now we can use this method in any class we want. In this project we use it in our ViewController like bellow:
- (IBAction)addToDatabase:(UIButton *)sender
{
    NSDictionary *studentInfo = @{@"name": self.nameField.text,
                                  @"lastName": self.lastnameField.text,
                                  @"studentId": self.studentIdField.text};
    
    [Students addStudentInfoFromDictionary:studentInfo];
} 
Basically we create a dictionary with all the items we want to add into the database and then we pass it to the function that we creates in Student+Add class.

description property

Most Objective-C classes have a property called description. When you use this property it tries to get the description of that object. It's like toString method in other programming languages. We can use this property to get some output on the screen when we add an object into database. So we change the last line into the following line:
self.outPutTextView.text = [Students addStudentInfoFromDictionary:studentInfo].description; 

Download

Download this App from HERE.