update viewcontroller from appdelegate - best practice?
Asked Answered
W

2

6

I am playing around with iBeacons implementing CoreLocation methods inside AppDelegate.swift (methods are implemented in AppDelegate to ensure App Background Capabilities)

In a SingleView application that comes with "ViewController.swift", what would be the best practice to pass data from AppDelegate to ViewController to update Views, say UIImages, UILabels or UITableViews ?

I have successfully implemented two different approaches:

1) Delegation, by firing Viewcontroller Delegation methods inside AppDelegate.swift:

protocol BeaconLocationDelegate { func minorBeaconChanged(minorValue:NSNumber) }

var locationDelegate: BeaconLocationDelegate

locationDelegate?.minorBeaconChanged(nearestBeacon.minor)

ViewController.swift:

in viewDidLoad method:

(UIApplication.sharedApplication().delegate as AppDelegate).locationDelegate = self

(I find this to look rather ugly - any better way to declare this property as delegate?)

protocol implementation:

func minorBeaconChanged(minorValue: NSNumber) {
  // do fancy stuff here
}

2) By creating a reference to ViewController inside AppDelegate:

let viewController:ViewController = window!.rootViewController as ViewController
viewController.doSomethingFancy()

Both approaches work fine for me, but I think the first approach via delegation is more elegant and the better choice once you have multiple ViewControllers.

Any recommendations?

Wellfixed answered 21/3, 2015 at 3:4 Comment(0)
M
1

I think the second solution is much easier. It also ensures the view controller does not go out of memory (is "released") and the app delegate does not try to contact an inexistent object.

Also, I do not understand the delegate argument in the case of more than one controllers. In that case, you would have to have multiple delegates, really not an ideal situation. Or you would have to change the delegate to different view controllers from the outside - also not very elegant and quite risky.

For the multiple view controller scenario I recommend notifications via NSNotificationCenter. This is a lose coupling that ensures only those objects that need to react receive the message. View controllers should start listening to the notifications upon creation and deregister from the notification center when they disappear.

Mallarme answered 21/3, 2015 at 3:25 Comment(4)
Is that also the best practice? I was thinking delegates would be the best choice, partly because of the MVC concept where updates to the view would mainly be fired by delegate methods, thus seperating the view from the model.Wellfixed
I am also not feeling very confident about handling the data in the appdelegate. Looking for ways to move it into a seperate class, but still not sure how. Goal is to move from dirty hacks to good and reusable code.Wellfixed
The proposed solution does not violate MVC. We have not discussed the model at all. It is just a question of how closely you want to couple the controller to the app delegate (the "global" class of the app). Very loosely (notifications) or tightly (retained property). In your use case there is no reason against a tight coupling.Mallarme
Your second comment regards a different problem that perhaps you should address in separate question. Welcome to Stackoverflow. Start showing appreciation by up-voting and/or accepting the answer.Mallarme
G
1

How about this?

In AppDelegate

var minorBeaconChanged: NSNumber -> () = { minor in }

And call this method when location is updated.

In ViewController's viewWillAppear

( UIApplication.sharedApplication().delegate as? AppDelegate )!.minorBeaconChanged = { minor in
//  Do with minor
}

EDIT: 27/8/2015

If you wanna have multiple observers.

In AppDelegate

var minorBeaconObservers: [ NSNumber -> () ] = []

And call all the item in minorBeaconObservers with 'minor'

In ViewController's viewWillAppear

( UIApplication.sharedApplication().delegate as? AppDelegate )!.minorBeaconObservers.append( 
    { minor in
    //  Do with minor
    }
)
Gambol answered 21/3, 2015 at 12:7 Comment(1)
This way minorBeaconChanged can only have 1 observer, but I'm using it by now.Staircase

© 2022 - 2024 — McMap. All rights reserved.