IOS - Delegate vs Notification
Asked Answered
J

4

7

Would like to have your opinion regarding the following architecture:

In My app I have a static class (LoginManager) that handles an asynchronous login. Once the login phase is completed the app should response and transition to another state.

I have 2 implementation suggestions

  1. using a Delegate:

    import Foundation
    
    protocol LoginManagerDelegate{
        func onLogin(result:AnyObject)
    }
    
    class LoginManager {
        struct Wrapper {
            static var delegate:LoginManagerDelegate?
        }
    
        class func userDidLogin(result){            
             Wrapper.delegate?.onLogin(result)
        }
    
    }
    
  2. using a Notification:

    import Foundation
    
    class LoginManager {
    
        class func userDidLogin(result){            
             NSNotificationCenter.defaultCenter().postNotificationName("onLogin", object: result)
        }
    
    }
    

Q:What would be the best approach?

Jerrold answered 25/12, 2014 at 12:7 Comment(0)
W
9

If the

func onLogin(result:AnyObject)

Is implemented in only one class, I would go with the delegate. More appropriate for a 1 to 1 relation.

If it's an 1 to n relation, I would go with the Notification.

I don't like to rely on Notification (personal taste), so I usually handle the login/logout transitions in my AppDelegate, which permits me to use the Delegate pattern.

Wilonah answered 25/12, 2014 at 12:13 Comment(0)
C
11

For

  1. Delegate/Protocol

It is generally used when you want to update or done any procedure in you previous controller from current view controller. so if you want to update values in previous view controller then Delegate/Protocol is preferable.

So it is basically 1-to-1 Relation.

  1. Notification

It is generally used when you want to update values in your view controller from any other viewcontroller. so its basically 1-to-n relation.

So use this type as per your requirement.

Maybe this will help you.

Cither answered 25/12, 2014 at 12:23 Comment(0)
W
9

If the

func onLogin(result:AnyObject)

Is implemented in only one class, I would go with the delegate. More appropriate for a 1 to 1 relation.

If it's an 1 to n relation, I would go with the Notification.

I don't like to rely on Notification (personal taste), so I usually handle the login/logout transitions in my AppDelegate, which permits me to use the Delegate pattern.

Wilonah answered 25/12, 2014 at 12:13 Comment(0)
C
1

3: A callback function. (like 1, but without the faff of declaring a protocol specifically just for this purpose).

class LoginManager {
    // using this singleton makes me feel dirty
    struct Wrapper {
        // this AnyObject too...
        static var callback: ((result: AnyObject)->())?
    }

    class func userDidLogin(result){            
         Wrapper.callback?(result)
    }
}
Cusack answered 25/12, 2014 at 12:17 Comment(4)
thanks for the reply. why don't you like the singleton approach?Jerrold
Global state can be troublesome and best avoided if practical. The fact you have to make it an optional is a sign there might be a better way. Say you re-used the login class but forgot to set the callback–could cause a nasty bug. Do you have the thing you want to call back to-hand when you create the login object? In which case you could just pass it in as a parameter and make it a regular member property (and ditch the optional, maybe make it a let not a var). Similarly, why use AnyObject? You know what type you’re planning to pass into the callback argument, make it that type. HTH.Cusack
for full disclosure, I'm using facebook as the 3rd party login authenticator, the AnyObject is the result I get back for the startForMeWithCompletionHandler method. "Say you re-used the login class but forgot to set the callback–could cause a nasty bug" that is why I thought about a delegate. could you please provide an alternative approach that will keep the login mechanism decoupled from the main logic?Jerrold
The delegate doesn’t really help mitigate the risk of the global state. Basically, using your LoginManager is a multi-step process. First you have to set the callback. Then display the manager to receive a callback. If you forget to do the first one, weird stuff happens. LoginManager isn’t really a “class” – it’s a global variable and a global function. If you instead made LoginManager a thing you create, you could give it an init that took the callback.Cusack
A
0

I would go for completion block with delegate implemented. By the way, as a good practice, NSNotification should not be fired/used for transition. Better use delegates.

Ait answered 25/12, 2014 at 12:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.