Skip to main content

iOS Mid Senior level [Part 3/4]: Applying design patterns.


[1] Singleton
When a class is restricted to just one instantiation, that one object is called a singleton. A singleton class returns the same instance no matter how many times an application requests it.  
Example :
+ (instancetype)sharedManager   {
     static DocumentManager * sharedDocumentManager = nil;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
         sharedDocumentManager = [[DocumentManager alloc] init];
         NSLog(@"Singleton memory address: %@", sharedDocumentManager);
     });
     return sharedDocumentManager;
}

[2] Abstract Factory 
Provide an interface for creating families of related or dependent objects without specifying their concrete classes. Creates a base class with abstract methods defining methods for the objects that should be created. Each factory class which derives the base class can create their own implementation of each object type.
Ex : Button factory produces windows button or OS X button based on type.

[3] Factory method
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

[4] Category
Categories allows you to extend the behaviour of existing classes by adding new class or instance methods. Unlike subclass we cannot add instance variable.
At runtime there is no difference b/w a method added by a category and one that is implemented by the original class. Declared in separate .h and .m files
 Ex:  ClassName + CategoryName.h
Syntax : 
@interface ClassName (CategoryName)
@end

[5] Class Extension
Similar to category, but it can be only be added to a class for which you have source code at compile time. Also called Anonymous categories or Category with no name. Useful for hide private information.
Syntax : 
@interface ClassName () 
@end

[6] Protocols
Protocol is set of methods and properties that encapsulates a unit of functionality. The protocol does not actually contain any of its implementation for these things; it early defines the required elements. Any class that declares itself to conform to this protocol must implement the methods and properties dictated in the protocol.
Multiple inheritance can be achieved as class can adopt more than one protocol.

@protocol ProtocolName
//List of methods and properties
@end

//Confirming to protocol
@interface myClass:NSObject <protocolName>
 //….
@end

[7] Formal Protocol
Formal Protocols allow us to define the interface for a set of methods, but implementation is not done. Formal Protocols are useful when you are using DistributedObjects, because they allow you to define a protocol for communication between objects, so that the DO system doesn't have to constantly check whether or not a certain method is implemented by the distant object.

[8] Informal Protocol
Informal protocols are typically declared as categories of the NSObject class, because that broadly associates the method names with any class that inherits from NSObject. Because all classes inherit from the root class, the methods aren’t restricted to any part of the inheritance hierarchy. 

[9] Delegation
A delegate is an object that acts on behalf of, or in coordination with, another object when that object encounters an event in a program.
Message passing between 2 objects. (one to one, if we need one-to-many, then use observer pattern). No subclassing involved. Delegation work hand in hand with protocols because it allows a class to specify a delegate property which confirm to some protocol. Then second class which actually confirms to that protocol can assigned to that property. 
Now first class can be communicate with the second class thought the delegate property using the methods and property as defined by the protocol.

[10] Data source
Data source is like delegate, except that its method supply data for another objects to display. The difference is in the relationship with the delegating object. Instead of being delegated control of the user interface, a data source is delegated control of data. The delegating object, typically a view object such as a table view, holds a reference to its data source and occasionally asks it for the data it should display. The data source pattern fits nicely in the MVC pattern. 

[11] MVC 
Model View Controller design pattern is a popular way to make logical divisions among class responsibilities.
Each object oriented programming environment/language has a slightly different definition/convention of MVC.
The main advantage of adopting a design pattern like MVC is that it allows the code in each unit to be decoupled from the others, making it more robust and immune to changes in other code.

[12] KVO (Key Value Observer) 
Key value observing (KVO) is a pattern in which one object can observe the value of another object’s properties to find out about changes. Where the previous two patterns (delegation and notifications) are more suited to a controller communicating with arbitrary objects, KVO is more suited for objects of any type listening for changes of another arbitrary object (not necessarily, and most often not a controller). It is a way in which we can keep our objects in sync with one another; a way in which we can make one object react when another object’s state changes. It is only used for properties and cannot be used to respond to methods or other actions.

[13] KVC (Key value coding)
Key-value coding is a mechanism for accessing an object’s properties indirectly, using strings to identify properties, rather than through invocation of an accessor method or accessing them directly through instance variables. E.g. NSDictionary and NSMutableDictionary
 "Keys" are just strings, and "values" can be any type of object.

[14] Key value path
Cocoa makes a distinction between "keys" and "key paths". A "key" allows you to get a value on an object. A "key path" allows you to chain multiple keys together, separated by dots. 
For example : 
      [p valueForKeyPath:@"spouse.name"];
      … is exactly the same as this…

      [[p valueForKey:@"spouse"] valueForKey:@“name"];

Popular posts from this blog

Animating label text update - choosing a better way

Recently I published a countdown app .  At one point of development - I have to show a timer on a UILabel which ticks on each seconds. As usual I started  setting text to a label object - self .timerLabel.text = someString Easy piece of cake right !?   But wait ... it won't take much user attention when timer ticks on every seconds. So I decided to make use of a simple animation while label gets text update. I found there are dozens of ways to animate a label. In this short article, I listed 3 best way you can animate text on a label. ( Spoiler Alert 👀- I decided to go with 3rd option)  1. Fade In - Fade out animation : CATransition class has got transition type `fade`. With timing function of CATransition - I was able to see the below result. let animation: CATransition = CATransition () animation.timingFunction = CAMediaTimingFunction (name: CAMediaTimingFunctionName .easeInEaseOut) animation.type = CATransitionType .fade animation.subtype = C...

Prevent Navigationbar or Tabbar overlapping Subview - solved for Card view

Recently, I started with a Card view added as a subview of UIView in a view-controller. When a view controller created along subviews, it tends to use entire screen bounds and also slips behind Tab bar or Navigation bar. In my current situation, it's second case. Casually new iOS developers will write a patch by additional value for coordinate y and subtracting bar height from its size. A lot of them posted in SO threads too : How to prevent UINavigationBar from covering top of view? View got hidden below UINavigationBar iOS 7 Navigation Bar covers some part of view at Top So, how I got solved ? self.edgesForExtendedLayout = [] This  will avoid all subviews in a view controller get behind any bars. Read full apple  documentation on here. Full Source code below :  //Simple view controller where its view layed-out as a card. class WidgetCardViewController : UIViewController { var containerView = UIView () //MARK:- View Controller Life Cyc...

Printing Staircase Pattern : Swift coding challenge

In this post, we can try interesting pattern printing challenge in Swift. The problem statement goes like this " Print a staircase of given size 'n'. Make sure that its base and height are both equal to n, and the image is drawn only using `#` symbols and spaces. The last line is not preceded by any spaces." Expected Output : # ## ### #### ##### ###### Working solution: func makePatternOf ( _ size : Int ) { var str = "" // 1 for index in ( 0 ..< size ) { let stop = size -index-1; // 2 for _ in 0 ..< stop { str. append ( " " ) ; } // 3 for _ in 0 .. . index { str. append ( "#" ) ; } print ( str ) str = "" } } makePatternOf ( 6 ) Loop to visit every row of stair case. Loop for appe...

Implementing autocompletion OTP field in iOS

Long waiting is over. !!  iOS 12 brings Autofill for OTP text field which is close to Android provided a decade back. Previously in iOS we used to toggle between OTP text screen and message inbox.  Which was hard to remember and time consuming resulting a bad user experience. Personally, I have been asked from the client/customer couple of times to implement autocompletion for OTP field and took me a lot of time to convey that it is not possible in iOS. Why Autofill was not possible previously?  We all know that Apple gives at most care for user privacy. When we see iOS architecture, each individual app is like a separate island. There is no inter-app bridge between apps (exception for Keychain and URLSchemes APIs which gives very limited scope). Thus we cannot read message content from inbox. Where to start Autofilling? First of all, the target SMS need to have the OTP Code with prefix string "Code" or "Passcode"on its message content. Beware of OTP c...

UICollectionViewCell shows with wrong size on First time - Solved

We commonly use Collection view where its cell size calculated run time. The flow layout delegate is responsible to return individual cell sizes. BUT in most of the cases, delegate method `collectionView: layout sizeForItem:` expects cell size too early. Before generating actual cell size. extension YourViewController : UICollectionViewDelegateFlowLayout { func collectionView ( _ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize (width: externalWidth, height: externalHeight) } } For instance, if a cell size depends on external view and its frame is not yet ready - results with wrong (or outdated) cell size. Typically happens for the first time view controller laid out all views. You can find similar queries in StackOverflow community : Collection view sizeForItemNotWorking UICollectionViewCell content wrong size on first load How to refresh UICollec...