Thursday, July 12, 2018

Swift Protocol Extensions


Protocol extensions is one of the beautiful features of Swift language.

Let’s see the usefulness with a use case.

I have a Logger protocol which is having simple log function which takes string to be logged and logs it.


       
 protocol Logger {
    func log(message: String)
 }



I am taking 3 service classes which has to confirm to this Logger protocol for logging service errors.

       
 class FacebookServices: Logger {
    func log(message: String) {
        print("Facebook - \(message)")
    }
 }

 class TwitterServices: Logger {
    func log(message: String) {
        print("Twitter - \(message)")
    }
 }

 class InstagramServices: Logger {
    func log(message: String) {
        print("Instagram - \(message)")
    }
 }



All the 3 classes are confirming to Logger protocol and implemented interface method log.

Now, What If we need log a generic error like "Service Unavailable”. 

We need to write that in all the 3 classes or we need to take a base class and keep the logGenericError method there.

       
 class FacebookServices: Logger {
    func log(message: String) {
        print("Facebook - \(message)")
    }
    
    func logGenericError() {
        print("Service unavailable!")
    }
 }

 class TwitterServices: Logger {
    func log(message: String) {
        print("Twitter - \(message)")
    }
    
    func logGenericError() {
        print("Service unavailable!")
    }
 }

 class InstagramServices: Logger {
    func log(message: String) {
        print("Instagram - \(message)")
    }
    
    func logGenericError() {
        print("Service unavailable!")
    }
 }



Instead of this, We can extend the Logger protocol and keep our convenient API there which allows all the classes confirming to the portal can access that extension.

       
 extension Logger {
    func logGenericError() {
        print("Service unavailable!")
    }
 }

 let twitter = TwitterServices()
 let facebook = FacebookServices()

 twitter.log(message: "404")
 twitter.logGenericError() // Service unavailable!

 twitter.log(message: "500")
 twitter.logGenericError()  // Service unavailable!




Easy and very useful Right?

We can customise the logGenericError() If a service needs like shown below.

       
 class InstagramServices: Logger {
    func log(message: String) {
        print("Instagram - \(message)")
    }
    func logGenericError() {
        print("Please try later!")
    }
 }

 let instagram = InstagramServices()
 instagram.logGenericError() // Please try later!



Go with Protocol extensions in such use cases instead of going for base classes.

Hope this post is useful. Feel free to comment incase of any queries.



No comments:

Post a Comment