Sunday, 6 May 2018

Key-Value Observing in Swift 4 Explained

Key-Value Observing (KVO) in Swift 4

Key-Value Observing (KVO), is an important concept in Cocoa API. It allows objects to be notified when the state of another object changes. Here I will explain how you can use this KVO in your swift programming skills where classes are interconnected with each others reference. If there is any change in property defined in custom type such as class then the reference of this custom type in another class should be notified quickly.


Lets do some coding {...}

Consider one small class that has definition as

@objcMembers class FirstClass: NSObject {

    // MARK: - Properties
    var createdAt = Date()
    dynamic var updatedAt = Date()
}


Read with attention that the above class is made "@objMembers" and one property is made "dynamic" that could be notified of value changes. Why because the KVO uses Objective-C runtime. And if you forgot to make the required class as @objMembers and required property as dynamic, the KVO will not work.
So for making your KVO successfull make your required class as @objMembers and required property as dynamic.

The Second class whose instance will be used in our UIViewController is as follows

class SecondClass: NSObject {
   // MARK: - Properties
   var firstClass: FirstClass

   // MARK: -
   lazy private var dateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy:MM:dd HH:mm:ss"
        return dateFormatter
    }()

   // MARK: -
   var createdAt: String {
        return dateFormatter.string(from: firstClass.createdAt)
    }
   var updatedAt: String {
        return dateFormatter.string(from: firstClass.updatedAt)
    }

   // MARK: - Initialization
    init(withFirstClass firstClass: FirstClass) {
        self.firstClass = firstClass
        super.init()
        firstClass.updatedAt = Date()
    }

    // MARK: - Public Interface
    func updateFirstClass() {
        firstClass.updatedAt = Date()
    }
}

Here the actual implementation of our KVO will happen on ViewController in real scenario.

class ViewController: UIViewController {

let secondClassInst = SecondClass(withFirstClass: FirstClass())

//MARK: this array will hold multiple observations realated to multiple property changes of any models present in this ViewController.
var observers = [NSKeyValueObservation]()

//Mark: This lable will show us the values changed via KVO
@IBOutlet weak var label: UILabel!

override func viewDidLoad() {
        super.viewDidLoad()

         //Mark: KVO Observer applied here
        observeModels()
    }
}
func observeModels(){

//Mark: since observers variable is an array that's why it can hold multiple NSKeyValueObservation. 

self.observers = [self.secondClassInst.firstClass.observe(\FirstClass.updatedAt, changeHandler: { (FirstClassIns, change) in
            print("Changes observed on ViewController \(FirstClassIns.updatedAt)")
            DispatchQueue.main.async {
                self.label.text = "\(self.secondClassInst.updatedAt)"
            }
 })]
}

Here in above observeModels() function, I had applied only one observation in this array but it will be your TODO to implement and see the multiple property changes and handled at same time by only creating new array element as per your requirement in the observers array.

//Mark: The below button action will update the property with latest DateTime.
@IBAction func updateAction(_ sender: UIButton) {
        secondClassInst.updateFirstClass()
}



Here You go with the KVO implemented and the O/P will be as follows.


Saturday, 5 May 2018

Handsome Image Gallery with Swipe to Dismiss feature using Swift iOS.

Image Gallery (iOS Swift)

We all love image gallery in our mobile app. There could be requirement / use case also in our app that we want to show the latest feeds or social feeds in our app. There could be multiple images also to be shown on separate screen where a user can download/view the images, surf the multiple images and can download it (if required).

 Image Caching

I had used static images to show in the demo app but you can use remote url downloading and caching technique to show images. The caching is done with md5 generated string for each cached image. you can easily pass remote image url to the extension method written on UIImageView such as loadImage. This function gives you completion block after image is applied to UIImageView and cached also.

imageView.loadImage(urlString: imageURL, completion: { [weak self] (image) in
 //Your code here
})

Supported orientations - Landscape + Portrait

 This demo app supports both orientation such as Landscape, Portrait in the first collection of images screen and gallery also.

Protocol delegate oriented 

The app is has the lovely implementation on protocol, delegate pattern. You only has to pass image names array or url array.  I will soon update it with as framework, pod for easy use.

Extension written on UIViewController

 The Gallery screen is opened as UIViewController and the extension is written on UIViewController for presenting and dismissing it.


This demo app can be used by those who want to integrate this functionality in their app. The source code is open.

The github repo for the source code can be seen here

Below are the screenrecorded gif can be seen. There is fps issue in gif due to large video size. That's why the gif could be seen some jerky but if you clone the repo and run in on simulator/device then it will be smooth experience.


Portrait mode -


Landscape mode -





Thanks :)