What does SOLID aka (S.O.L.I.D) means?

S.O.L.I.D is an acronym for the first five object-oriented design(OOD) principles by Robert C. Martin, popularly known as Uncle Bob.

These principles, when combined together, make it easy for a programmer to develop software that are easy to maintain and extend. They also make it easy for developers to avoid code smells, easily refactor code, and are also a part of the agile or adaptive software development.

S.O.L.I.D stands for:

When expanded the acronyms might seem complicated, but they are pretty simple to grasp.

Let’s look at each principle individually to understand why S.O.L.I.D can help make us better developers.

Single-responsibility Principle

S.R.P for short – this principle states that:

A class should have one and only one reason to change, meaning that a class should have only one job.

Open-closed Principle

Objects or entities should be open for extension, but closed for modification.

Liskov substitution principle

Let q(x) be a property provable about objects of x of type T. Then q(y) should be provable for objects y of type S where Sis a subtype of T.

Interface segregation principle

A client should never be forced to implement an interface that it doesn’t use or clients shouldn’t be forced to depend on methods they do not use.

Dependency Inversion principle

The last, but definitely not the least states that:

Entities must depend on abstractions not on concretions. It states that the high level module must not depend on the low level module, but they should depend on abstractions.

Advertisements

What’s the “higher order function” in Swift

Higher order functions “a function can take either accept functions or closure as a argumant”  you’ve already familiar with last one right? You can also write your own higher order function or there are a bunch all ready to take advantage of!

Most commonly mentioned higher order functions are; (maps, filter, reduce, sort)

But I want to look at Array high order functions! ( containsdrop, first, flatMapforEach, partition  and split, – yaaaaay )

I just want to you to just realize you can’t remember how to use it and resort reinventing the wheel. Let’s take a look at some of these more obscure higher order functions, and compare how some would need to be coded in for-in or while loop.

Imagine we have an array of fruits

var fruits = ["Banana","Pineapple","Coconut","papaya","Kiwi","Rambutan"]

Map

Perform an operation on every element in an array to build another array.
eg. Let’s create another array consisting of all of the fruits in lowercase.
Instead of:

var fruitLowercase:[String] = []
for fruit in fruits {
  fruitLowercase.append(fruit.lowercased())
}
//["Banana", "Pineapple", "Coconut", "papaya", "Kiwi", "Rambutan"]

We can simply use map:

let fruitLowercase = fruits.map { $0.lowercased() }
//["Banana", "Pineapple", "Coconut", "papaya", "Kiwi", "Rambutan"]

Filter
Returns every element in an array that satisfies a condition
eg. Lets say we want all of the fruits that begin with C-P

var fruitAK:[String] = []
for fruit in fruits {
  if ("C"..."P").contains(fruit.characters.first!) {
      fruitAK.append(fruit)
  }
}
//["Coconut", "papaya"]

We can simply use filter:

let fruitAK = fruits.filter { ("C"..."P").contains($0.characters.first!) }
//["Coconut", "papaya"]

Reduce
Generate a single value by performing an operation on every element in that array.
eg. Lets say we need to know the letter count all of the fruits.

var totalLetters = 0
for fruit in fruits {
  totalLetters+=fruit.characters.count
}
//40

We can simply use reduce:

let totalLetters = fruits.reduce(0) {$0 + $1.characters.count}
//40

Sorted
Create a sorted version of an array. You don’t need to see an example of manually sorting an array to understand how this works!
Sort an array simply by describing how you want the sort to work. You can do this simply by indicating the direction of the sort with a less than mark or greater than mark.

var fruitSorted = fruits.sorted(by: <)
//["Banana", "Coconut", "Kiwi", "Pineapple", "Rambutan", "papaya"]

Notice that “papaya” comes last, as lower case letters come after upper case letters. You may want to ignore capitalization (or localization) differences:

var fruitSorted = fruits.sorted(by: {$0.localizedLowercase < $1.localizedLowercase })
//["Banana", "Coconut", "Kiwi", "papaya", "Pineapple", "Rambutan"]

Contains
Generate a true/false by checking if any element in your array satisfies a condition. Related to filter, but returns a Bool, rather than an array.

eg. Let’s say we need to know if our fruits array contains a four letter fruit.
Instead of:

var fruitContains4Char = false
for fruit in fruits {
  if fruit.characters.count == 4 {
    fruitContains4Char = true
    break
  }
}
//true

We can simply use contains:

let fruitContains4Char = fruits.contains {$0.characters.count == 4}
//true

Drop
Drops elements from your array while a condition is true, stops checking when it encounters an element that shouldn’t be dropped.

eg. Let’s say we want to drop all elements at the beginning of the array that contain the letter ‘a’.
Instead of:

var fruitDropA:[String] = fruits
while fruitDropA.count>0 && fruitDropA.first!.contains("a") {
  fruitDropA.remove(at: 0)
}
//["Coconut", "papaya", "Kiwi", "Rambutan"]

We can simply use contains:

let fruitDropA = fruits.drop { $0.contains("a") }
//["Coconut", "papaya", "Kiwi", "Rambutan"]

First
You’re probably familiar with the first property that retrieves the first element of an array, but did you know you can pass in a condition to get only the first element that meets that condition?

eg. Let’s say we want the first element of the array that contains the letter ‘i’.
Instead of:

var firstFruitI:String?
for fruit in fruits {
  if fruit.contains("i") {
    firstFruitI = fruit
    break
  }
}
//Optional("Pineapple")

We can simply use contains:

var firstFruitI = fruits.first { $0.contains("i") }
//Optional("Pineapple")

FlatMap
Closely related to map, flatMap automatically removes any nil values from a map call, ensuring that the array returned does not contain optionals.

eg. Let’s say we have an array of String values:

let numbers = ["1","3","pineapple","2"]

And we want to convert these to an Array of Int. The map function would return an Array of Optional Int, and a nil value for “pineapple” that isn’t a number:

let numbersMapped = numbers.map { Int($0) }
//[Optional(1), Optional(3), nil, Optional(2)]

That’s not what we’re after, we want an array of Int!

We could of course do this in a for loop:

var numbersMapped:[Int] = []
for number in numbers {
  if let int = Int(number) {
    numbersMapped.append(int)
  }
}
//[1, 3, 2]

But much easier using flatMap:

let numbersMapped = numbers.flatMap { Int($0) }
//[1, 3, 2]

ForEach
The forEach higher order function is a cool tool for your programming arsenal – basically short-hand for the for-in loop.

eg. Let’s say we want print the lowercase version of every fruit in our fruits array.
Instead of:

for fruit in fruits {
  print(fruit.lowercased(), terminator: " ")
}
//banana pineapple coconut papaya kiwi rambutan

We can simply use contains:

fruits.forEach { print($0.lowercased()) }
//banana pineapple coconut papaya kiwi rambutan

Partition
The partition method partitions the elements of your array based on a condition. Elements that meet the condition are placed last in the array.

eg. Let’s say we want all of the fruit in our fruits array that contains the letter “i” to come last. We could do this with a for-in loop:

var partitionedFruit:[String] = []
var partition = 0
for fruit in fruits {
  if fruit.contains("i") {
    partitionedFruit.append(fruit)
  } else {
    partitionedFruit.insert(fruit, at: partition)
    partition+=1
  }
}
fruits = partitionedFruit
//["Banana", "Coconut", "papaya", "Rambutan", "Pineapple", "Kiwi"]

Notice that “Kiwi” and “Pineapple”, the only elements with an “i” are placed at the end of the array. Alternatively, we can do this with just one line of code with the partition method:

fruits.partition(by: { $0.contains("i") })
//["Banana", "Rambutan", "Coconut", "papaya", "Kiwi", "Pineapple"]

Notice that this method, rather than returning a new array, actually changes the array itself. Notice also that the order of the elements within each partition changes in a somewhat random fashion.

Split
You may be familiar with the components method on String, used to split a String based on a separator.

eg. Let’s say we have a paragraph that we want to split into sentences. We could use the components method, checking for full-stops (aka periods):

let paragraph = "I can't believe it! These higher order functions are like magic. Don't you think? Well, maybe not magic, but pretty useful all the same."
 
let sentences = paragraph.components(separatedBy: ".")
//["I can\'t believe it! These higher order functions are like magic",
//" Don\'t you think? Well, maybe not magic, but pretty useful all the same",
//""]

What’s with that final element though? An alternative to the components method is the split method, which accepts a separator too, but by default will omit blank elements.

To use the split method on a String, you would use it on the String.characters property, which is a String.CharacterType, which adopts the Collection protocol, giving characters access to many of the same cool higher order functions that Array has access to. Once you’ve separated String characters with split, you’ll have an array of something called a SubSequence, that you can pass in when initializing a String – you can do this on each element of your new array using the map higher order function to end up with an array of Strings.

Phew – what does that look like?

let sentencesSubsequences = paragraph.characters.split(separator: ".")
let sentences = sentencesSubsequences.map{ String($0) }
//["I can\'t believe it! These higher order functions are like magic",
//" Don\'t you think? Well, maybe not magic, but pretty useful all the same",
//""]

But wait, that ignored exclamation marks and question marks – they also define the end of a sentence. How to separate our paragraph using all three?

The split method has a fancy higher order function option as well. You can use it to divide our paragraph by full stops, exclamation marks or question marks:

let sentencesSubsequences = paragraph.characters.split { $0 == "." || $0 == "!" || $0 == "?" }
let sentences = sentencesSubsequences.map{ String($0) }
//["I can\'t believe it",
//" These higher order functions are like magic",
//" Don\'t you think",
//" Well, maybe not magic, but pretty useful all the same"]

Well that’s it! I hope next time you need to perform some magic on an array, you too might remember and take advantage of one of these higher order functions, keep your code nice, pretty and succinct and remember that you don’t need to reinvent the wheel!

Generic type extension by retrofitting protocols in Swift 2

A common Swift problem is that extensions of generics can only be constrained to protocols. We use a lot of big words here but this issue is quite common and a simple example will clearly illustrate this situation.
So let’s assume that we want to detect if an optional string is either empty or nil.
The basic solution would look something like this

let myString: String? = …
if myString?.isEmpty ?? true { … }

This looks like a bit bloated for such a simple operation and we would rather use something like

let myString: String? = …
if myString.isEmpty { … }

However this property does not exist and we are immediately thinking of adding an extension to Optional type to help us doing this :

extension Optional where Wrapped: String {
    var isEmpty: Bool {
        return map { $0.isEmpty } ?? true
    }
}

But there we fall short on a Swift limitation :

Type ‘Wrapped’ constrained to non-protocol type ‘String’.

Swift only accepts protocol as constraints on generic type extensions.
This especially does not work on value types (structs, enums, base types).
An interesting thing is that swift implicitely provides a protocol for classes describing their interface. You can therefore constraint to classes easily.
We will now see how to constraint on value types.

Solution

protocol PossiblyEmpty {
    var isEmpty: Bool { get }
}

Now let’s retrofit it on String. We only need to declare it as the implementation already exists :

extension String: PossiblyEmpty {}

Now let’s update our Optional extension to support this protocol:

extension Optional where Wrapped: PossiblyEmpty { … }

and we are done:

let myString: String? = …
if myString.isEmpty { … }

Bonus code: we can even retrofit more implementations as long as they provide an implementation for this signature !

extension Array: PossiblyEmpty {}

Here is the full code, you can add comment, edit or anything you want!

How to create Auto-Layout in code

Auto Layout works great in Interface Builder, but it’s often helpful to have the flexibility and clarity of wiring up constraints in code. Let’s dive in.

We’ll add a view and set translatesAutoresizingMaskIntoConstraints to false. Normally Interface Builder does this automatically under the hood, but since we’re working in code we’ll need to set it ourselves. Don’t want any funky autoresizing constraints in there meddling around.

let logo = UIView()

logo.translatesAutoresizingMaskIntoConstraints = false

container.addSubview(logo)

When learning to work with Auto Layout in code, it can be helpful to remember that constraints are essentially just linear equations:

viewA.property = multiplier * viewB.property + constant

To express centering a view inside it’s superview, we could write it as:

view.center.x = 1.0 * superview.center.x + 0.0
view.center.y = 1.0 * superview.center.y + 0.0

Let’s look at how to express the same thing (centering our logo view inside it’s superview) using NSLayoutConstraint objects in code:

container.addConstraints([
  NSLayoutConstraint(item: logo, attribute: .CenterX, relatedBy: .Equal, toItem: container, attribute: .CenterX, multiplier: 1, constant: 0),
  NSLayoutConstraint(item: logo, attribute: .CenterY, relatedBy: .Equal, toItem: container, attribute: .CenterY, multiplier: 1, constant: 0)
])

Whew! That’s a long constructor. The neat part though, is from left-to-right it almost reads like the equations from before. Lastly, we’ll assign a fixed size to our logo view. Since there’s only 1view involved, the equation is much simpler:

view.height = 0.0 * nothing + constant.

And finally, in code this looks like:

 container.addConstraints([ NSLayoutConstraint(item: logo, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 115), NSLayoutConstraint(item: logo, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 70) ]) 

Debug casting class


id DebugCastCpp(id sourceClass, Class cl)
{
	if (sourceClass != nil)
	{
		if (![sourceClass isKindOfClass: cl])
		{
            NSLog(@"%@", [NSString stringWithFormat: @"The cast is invalid (%@ to %@)", [sourceClass class], cl]);
			@throw [NSException exceptionWithName:@"CastException" reason: [NSString stringWithFormat: @"The cast is invalid (%@ to %@)", [sourceClass class], cl] userInfo:nil];
		}
	}
	
	return sourceClass;
}



Reverse NSString with Objective-C

Objective-C ensure you more possibilities when you’re manipulating existing objects like NSArray, NSString, NSDictionary etc. Some API functions can be done less code and some other snippets really mess.

Here is the reverse string block code

NSString *myString = @"abcdefghijklmnopqrstuvwxyz";
NSMutableString *reversedString = [NSMutableString stringWithCapacity:[myString length]];

[myString enumerateSubstringsInRange:NSMakeRange(0,[myString length]) 
                             options:(NSStringEnumerationReverse | NSStringEnumerationByComposedCharacterSequences)
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                            [reversedString appendString:substring];
                        }];

Before I learn reverse string block syntax I was doing this iterate trough all exist string length and after the range this string I was add these reversed string in a mutable array. Here is the my old approach

// first retrieve the text of textField1
NSString *myString = textField1.text;
NSMutableString *reversedString = [NSMutableString string];
NSInteger charIndex = [myString length];
while (myString && charIndex > 0) {
    charIndex--;
    NSRange subStrRange = NSMakeRange(charIndex, 1);
    [reversedString appendString:[myString substringWithRange:subStrRange]];
}

Scale to fill for UIColor pattern UIImage

Sometimes we need to scale to fill our images to fit in certain image view. This code snippet easly do this. I definitely recommend to you use UIImage category for this. So that you don’t repeat same code again and again.

 
+ (UIImage *)fitImageWithView:(UIView *)view imageName:(NSString *)imageName {
    
    if(imageName.length < 1) {
        [NSException raise:@"There is no image name." format:@"Image name is : %@", imageName];
    }
    
    UIImage *img = nil;
    
    UIGraphicsBeginImageContext(view.frame.size);
    [[UIImage imageNamed:imageName] drawInRect:view.bounds];
    img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return img;
}

Quick tip: Import necessary classes in a single file

When we working on a project and it has lot of class where doing same job we don’t need to import these classes again and again. Instead we need to a model class. Declare these classes in a single model class and use this class when necessary.

UserModel.h – Implementation file

#import "UserInformation.h"
#import "UserProducts.h"
#import "UserFriendList.h"

After that we should declare this model in our “Prefix” file.

#ifdef __OBJC__
     #import "UserModel.h"
#endif

Public functions

In Objective-C some APIs may wish to  expose own helper functions publicly. For concern and state procedures. Functions are great way to encapsulate like these behaviours. If you think they’re really useful, it may be worth making them available globally.

Interface File:

typedef NS_ENUM(NSUInteger, UserState) {
    UserState_Active,
    UserState_Deactive,
    UserState_SuperUser,
    UserState_Admin,
    UserState_Moderator
};

extern NSString *NSStringFromUserState(UserState state);

Implematation File

NSString *NSStringFromUserState(UserState state) {
    
    switch (state) {
        case UserState_Admin: return @"Admin";
        case UserState_Moderator: return @"Moderator";
        case UserState_SuperUser: return @"Super User";
        case UserState_Active: return @"Active User";
        case UserState_Deactive: return @"De-active User";
        default:return nil;
    }
    return nil;
}