Showing posts with label learning. Show all posts
Showing posts with label learning. Show all posts

Friday, July 14, 2017

Swift access modifiers

Swift access modifiers

Swift access modifiers

Open:
open classes and class members can be subclassed and overridden both within and outside the defining module (target). Open access is the highest (least restrictive) access level.

Public:
public classes and class members can only be subclassed and overridden within the defining module (target).

Internal:
Enables an entity to be used within the defining module (target). You typically use internal access when defining an app’s or a framework’s internal structure.

FilePrivate:
Restricts the use of an entity to its defining source file. You typically use fileprivate access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.

Private:
Restricts the use of an entity to its enclosing declaration. You typically use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration. private access is the lowest (most restrictive) access level.

Final:
The final keyword is not an access level but you can add it to any of the access levels (apart from open) to prevent subclassing or overriding.


Now the question is What does it mean by same module?
Let’s understand it by example: many times we subclass UITextField (class), which is a part of UIKIT (Different module) but we can do this because it is defined as open. Same applies for class member and methods.

@available(iOS 2.0, *)
open class UITextField : UIControl, UITextInput, NSCoding, UIContentSizeCategoryAdjusting {
...
...
}

UITextField: Swift access modifiers

Some other observations: (I have checked it with swift 3.0.)

In order to apply the open and public access modifiers we need to inherit our class from NSObject. Or we may get below error while using outside of class.
'openClass' initializer is inaccessible due to 'internal' protection level.
'publicClass' initializer is inaccessible due to 'internal' protection level.
'fileprivateFunc' is inaccessible due to 'fileprivate' protection level

We cannot inherit public class outside the module. We get below error:
Cannot inherit from non-open class 'publicClass' outside of its defining module

We cannot access internal method or object outside the module.
'internalObject' is inaccessible due to 'internal' protection level

In other file or module,We get below error when we try to create object of FilePrivate class and private class respectively.
Use of undeclared type 'fileprivateClass'
Use of undeclared type 'privateClass'

In same file, we can inherit or create object of private class as below and we can access all class members and methods which are not private.

fileprivate var privateClassObject = privateClass()

private class IprivateClass :privateClass {
}

Here is a link of apple document for more details.

Thursday, July 13, 2017

VIPER- Class binding using Protocol

In last post we have seen how to bind all classes together. In this post we would see app flows from view controller to interactor and to view controller.To make it more decoupled we would generate some protocols and implement it in classes.

Step:1 list-ViewController
Architecting iOS Apps with VIPER - App event flow in VIPER
override func viewDidLoad() {
        super.viewDidLoad()
        DispatchQueue.global().async {
            self.eventHandler?.updateView()
        }
    }

Step:2 list-Presenter
Architecting iOS Apps with VIPER - App event flow in VIPER

func updateView() {
        listInteractor?.findListData()
    }

Step:3 list-Interactor
Architecting iOS Apps with VIPER - App event flow in VIPER


func findListData() {
        //Find data
        //output?.foundListData(aList: nil);
        let reader = FileReader()
        if let data = reader.readJsonFile(name: "company") {
            let myArr:NSArray? = ParseData(aObject: data)
            if myArr != nil {
                output?.foundList(aList: myArr);
            }
        }
    }

Step:4 list-Presenter
Architecting iOS Apps with VIPER - App event flow in VIPER

func foundList(aList:NSArray?) {
        let sortedArray:NSArray? = self.SortCompanyList(aList: aList)
        if(sortedArray != nil) {
            userInterface?.reloadList(alist: sortedArray)
        }
        else {
            userInterface?.showNoContenctView()
        }
    }

Protocols:
1) ViewController Interface:
Implemented   by ViewController
Object owned by Presenter
Architecting iOS Apps with VIPER - Protocol binding in VIPER

protocol listViewInterface {
    func showNoContenctView()
    func reloadList(alist:NSArray?)
}
*********************************************************
class ViewController: UIViewController,listViewInterface
 {
  //MARK: listViewInterface methods implementation
    func reloadList(alist:NSArray?) {
        //reload table view
    }
    func showNoContenctView() {
     //Show alert code
    }
 }
*********************************************************
class listPresenter: NSObject {
    var userInterface:listViewInterface?
}

2) Presenter Interface:
Implemented by Presenter
Object owned by ViewController
Architecting iOS Apps with VIPER - Protocol binding in VIPER

protocol listPresenterInterface {
    func updateView();
}
*********************************************************
class listPresenter: NSObject,listPresenterInterface {
    var userInterface:listViewInterface?
    func updateView() {
        //Call for data adjustment and interactor calling
    }
}
*********************************************************
class ViewController: UIViewController,listViewInterface {
   var eventHandler:listPresenterInterface?
   override func viewDidLoad() {
     super.viewDidLoad()
     self.eventHandler?.updateView();
   }

   //MARK: listViewInterface implementation
    func reloadList(alist:NSArray?) {
        //reload table view
    }
    func showNoContenctView(){
        //Show alert code
        }
 }


3) Interactor Input Interface:
Implemented   by interactor
Object owned  by presenter
Architecting iOS Apps with VIPER - Protocol binding in VIPER

protocol listInteractorInput {
    func findListData()
}
*********************************************************
class listInteractor: NSObject,listInteractorInput {
    func findListData() {
        //Find data
    }
*********************************************************
class listPresenter: NSObject,listPresenterInterface {
    var listInteractor:listInteractorInput?
    func updateView() {
     //Code for data adjustment and interactor calling
     listInteractor?.findListData();
    }
}

4) Interactor output Interface:
Implemented   by presenter
Object owned  by interactor
Architecting iOS Apps with VIPER - Protocol binding in VIPER

protocol listInteractorOutput {
    func foundList(aList:NSArray?)
}
*********************************************************
class listPresenter: NSObject,listPresenterInterface,listInteractorOutput {
    var listInteractor:listInteractorInput?
    var userInterface:listViewInterface?
    
    func updateView() {
        listInteractor?.findListData();
    }
    func foundList(aList:NSArray?) {
       userInterface?.reloadList(alist: sortedArray);
    }
}
*********************************************************
class listInteractor: NSObject,listInteractorInput {
    var output:listInteractorOutput?
    func findListData() {
        //Find data
    }
}

Note:Presenter is implementing two protocols.
This is the end of the post. In next post we will see how VIPER is useful for testing and coverage.

Tuesday, June 20, 2017

5 Levels of Leadership

Find out more with this summary of John Maxwell's The 5 Levels of Leadership.

Level 1: Position (This would mostly comes with job title, People follow because they have to.)

Level 2: Permission (People follow because they want to. as you personally taking interest in every member, Why, What and How they work? and set them on level 1 by being their mentor.)

Level 3: Production (People follow because of what you have done for the organization. You encourage Level 2 people to do and be with them.)

Level 4: People Development (People follow because of what you have done for them. At this stage people at Level 3 should not need your strict mentorship, they can do it and can do it very well.)

Level 5: The Pinnacle (People follow because of who you are and what you represent. At this stage people do it and Level 4 would watch them.)


5 Levels of Leadership

Leadership is an Action and its always on going, learning and growing process.
View a quick talk on leadership

Wednesday, June 14, 2017

VIPER an iOS architecture

I have been practicing VIPER architecture since one year and I found lots of ups and down while using it.
In this blog I will try to explain and simplify VIPER architecture.
Here are the two images which you could see when you search for VIPER architecture. 

VIPER an iOS architecture


VIPER an iOS architecture


Both are almost same and right. It is on you and use cases that which one you could choose to use. We will use both images at various time as we proceed.

Why VIPER?
Most of the iOS Apps follows MVC pattern and since much of the application code cannot fit in model or view are ended up in ViewController which makes our ViewController the Massive View Controller. VIPER could focus to reduce the load of ViewController.
Testing was never a major part of making iOS Apps and it is too difficult to test with various architectures but VIPER helps a lot in this area too.
We can divide code on basis of functionality like login, register, view account etc.

What is VIPER?
Here what VIPER stands for:
V-> View
I-> Interactor
P-> presenter
E-> Entity
R-> Router
Here is a general diagram which helps you to understand the flow.

VIPER Flow Diagram



View: One super secret is Your View = ViewController class + Interface View. It is a passive and can request presenter to update itself. The presenter does not know about any existence of UI elements like UIButton or UILabel, but it maintains the content. Till now what you do in ViewController class is your View and we will practice to reduce its load so now on View Controller has to worry only about showing content. And other responsibilities we will pass to presenter, interactor and so on.

Presenter: It consist the logic to drive the UI. And also handles the events passed by View and interactor. Lets explore this both using example.


Use case: We have a ViewController and we want to show some content in the view, however this is our first step we do not have any content to show, so we would show only popup with no content.

Prior code:
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
            self.updateView()
    }
    func updateView() {
         var myArray:NSArray? = nil ;
        //now we would call web service or db method to load data so that myArray != nil
        if(myArray != nil) {
            //Do change to make it appropriate with regards to view, like change array into model - entity form.
        }
        else {
            let alert = UIAlertController.init(title: "VIPER", message: "No content to show", preferredStyle:.alert)
            let okAction = UIAlertAction.init(title: "OK", style: UIAlertActionStyle.default, handler: nil)
            alert.addAction(okAction)
            self.present(alert, animated:true, completion: nil)
        }
    }

}

After adding presenter:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
            presenter.updateView()
    }
    func showNoContenctView(){
        let alert = UIAlertController.init(title: "VIPER", message: "No content to show", preferredStyle:.alert)
        let okAction = UIAlertAction.init(title: "OK", style: UIAlertActionStyle.default, handler: nil)
        alert.addAction(okAction)
        self.present(alert, animated:true, completion: nil)
    }

}
class Presenter:NSObject {
    func updateView() {
        //ask interactor for data.
        interactor.findListData()
      }
   
    //This method will be called by interactor once interactor gets the data
    func foundList(aList:NSArray?) {
        if(aList != nil) {
            //if list != nil //we would be doing some data formation before passing this to the view.
        }
        else {
            userInterface?.showNoContenctView();
        }
    }
    
}

Draft:1 This is the end of first draft, in next post we will learn about interactor and entity.

Friday, May 26, 2017

Eat That Frog - Consider the Consequences

I have read the book ‘Eat That Frog’, Here is a snippet that I could get from the fourth chapter ‘Consider the Consequences ’:



1. Long-time perspective turns out to be more important than any other single factor in determining your success in life and at work.

2. Always ask yourself, "What are the potential consequences of doing or not doing this task?"

3. Failures do what is tension relieving, while winners do what is goal achieving.

4. For example, coming into work earlier, reading regularly in your field, taking courses to improve your skills, and focusing on high-value tasks in your work will all combine to have an enormous positive impact on your future.
On the other hand, coming into work at the last moment, reading the newspaper, drinking coffee, and socializing with your coworkers may seem fun and enjoyable in the short term.



Eat that Frog
If you wish to purchase a book from AMAZON click here: http://amzn.to/2pnTEQB

Have a great day ahead!