Is there anything like this outside of the application delegate? I would just like to be able to do certain things in my view controllers when I receive a notification. Will I just have to import each of them and check the type of class against my current view controllers in order to perform actions on them?
Essentially, if I received a remote notification and I didn't have an exact reference to the top most view controller on the stack, is there a good way to access a class or instance method of that controller? Or maybe even some properties?
Why don't you just send an NSNotification (don't mistake notification center and Apple Push Notifications) to them? You have a nice article here talking about it.
Related
Edit something in the parent view, when moved from the child modal view. Should I use "viewWillAppear" or some other pre-defined functions for the view to be appeared in foreground..
There are actually plenty of ways to achieve what you want.
One would be checking on viewWillAppear,
another way is to create protocol, and call some protocol method when child is going to be dismissed.
Also, you could have a property in the child class to hold object
reference to the parent, and when being dismissed call some method
on parent to notify the parent that the modal is being dismissed.
You could use NotificationCenter, and post a notification, and
handle the notification on the parent to update it, as well.
I don't know which one is the most suitable for you, if you give more context to the problem, I could clarify the answer. Good luck!
Edit:
Here is the official Apple documentation;
Here you can find information about how to use the notifications and notification center.
You can search the Google for more on Notifications and NotificationCenter.
I'm creating an app that implements a Facebook and a Twitter service. In my view I have a button that toggles sharing on Facebook/Twitter or not. If Facebook/Twitter aren't connected, then the button will show "connect to".
When I click the button, a method in my controller (not my viewcontroller) will try to toggle the value because this controller tracks the state of my app. When I'm not connected to a social network my controller will notice and will call the correct service. This service will start a webview to provide the user credentials.
And now my question:
When I'm in my service and I need to provide credentials via a webview. When I want to show this webview I need to pass a View Controller that will handle the presenting. How do I provide a viewcontroller here?
Approaches I found:
Call the appdelegate singleton and get the current presenting
viewcontroller (I find this dirty but correct me if I'm wrong).
Since I'm injecting my service into my controller in
appdelegate.didFinishLaunchingWithOptions I could inject the UIWindow
of the appdelegate and ask for the current presenting viewcontroller
(Is almost the same as the first approach)
Create a protocol implemented by a viewcontroller. The service has a property that is equal to that protocol and in my app delegate inject the
viewcontroller into the service.
Have a property in your controller
that will be the presentingviewcontroller and let your controller
implement the approach #3 protocol. When a function of that protocol
is fired, the controller will handle it and use the
presentingviewcontroller property for the webview. I only need to
inject a viewcontroller into my controller in the appdelegate.
Don't implement anything view related in that service.
My current implementation is approach #3.
If some things are not clear, please let me know.
Any help is appreciated!
Thanks in advance!
I was hoping this question would of got more attention, I was interested to know how other people would handle this situation.
As you have already stated, there are a few ways to achieve what you need, but the answer depends on having knowledge of the application.
I would definitely try to keep business logic and UI as separate as possible, there are two methods that I can think of to do this, but they are pretty much the same thing.
Make the (non UI) controller responsible for the login check with a callback function, you can then leave the controller responsible for business logic and the calling ViewController responsible for rendering any UI as a result of that check.
As you suggested, using protocols, your controller could have a delegate that will be a ViewController that conforms to your protocol. Then usage would just be getting your shared instance, setting the delegate and calling the required fuctionality.
I would likely favor option 2 to be more Swift-like as it is a protocol orientated language.
If the controller is acting globally and accessed from anywhere within the application you could potentially end up duplicating a lot of code to make these checks, you could get around this by creating an extension of UIViewController which provides the functionality to interact with the controller.
I hope this helps, Would definitely be interesting to see the way other people would approach this.
I have a UIView subclass acting as an internal "notification" system, that has a label inside that displays the notification text and animates down from the top of the view and back up. I need to create a system that will create a queue of these notifications (that can be added to from anywhere within my app), and display them one by one, but wondering how I should structure it.
Should I use a singleton that manages a queue of these UIViews? or should there be a UIViewController that has a queue? Or something else?
Thanks!
This is usually managed by a data persistence class. You want to separate data layer from view layer in order to maintain it properly. Implement the notification logic by creating a class that manages the notification data itself, in a queue, and just present said data in a view, in any viewcontroller that should display said notifications.
After you create the class that manages notification data, you can either:
Check inside viewDidLoad() if there is a notification in the queue. If true, present it.
Create a timer and check for the queue every couple of seconds/minutes
Get fancy and implement observer pattern so that every ViewController would subscribe to your notification manager class so that it notifies the VC that new data is available. When that happens, it will delegate through a protocol the presentation logic to the view controller (Preffered)
EDIT: If you go for #3 (and you probably should), remember to use weak for the delegate, as you don't want leaked VCs
I would like to display a local message (generated by WatchKit code) on the Apple Watch. My problem is that the message may be triggered by a code segment outside of the currently active interface controller.
What is the best way to modally present a new interface controller independent of the currently active (top-most) interface controller?
One way would be to get a pointer to the currently active interface controller. But how to do this in an easy way?
One possible solution is to use a global property that holds a pointer to the currently active interface controller. It gets updated in the willActivate methods of all interface controllers.
Another solution would be to always pass the pointer to the currently active interface controller to all methods that may want to show a message.
Is there an easier way to get a pointer to the top-most interface controller?
Well, I'm not even convinced that the above approach is a good one. What if the top-most controller is dismissed shortly after presenting the interface controller with the message? Then the message is probably not shown very long or not at all.
Is it possible to modally present the message interface controller on top of everything independent of the currently active (top-most) interface controller?
Should I use local notifications? Is there something like UIAlertView?
What is the best and easiest way to solve this problem?
There is not any UIAlertView or WKAlertView in WatchKit. You must initialize a new view controller with a text view, and pass it the string you want to show.
You can use this method to do so:
Swift:
presentControllerWithName([Name] , context: [String])
Objective-C:
- presentControllerWithName:context:
To show a message independently of the active interface controller, it is possible to present an interface controller using presentControllerWithName:context: from the main interface controller (the one with the arrow in the storyboard). This works even if the main interface controller is not currently active.
For this solution to work, it is necessary that the method that calls presentControllerWithName:context: has a pointer to the main interface controller. This can be achieved by passing self from the main interface controller to other interface controllers and methods.
However, I sometimes want to show a message from an object deep down in the hierarchy. And I do not want to pass the pointer to the main interface controller to every method that possibly wants to display a message to the user.
So, my current solution is to store a pointer to the main interface controller in a global variable (using extern) and then presenting from this main interface controller.
Acknowledgements: I would like to thank "Schemetrical" and "Mike Swanson" for the comments that solved this problem.
I have many different views in app. While the application state is active I would like to have a generic response to remotenotifications that is not an alertview. One way to do this would be to place the notification observer in uinavigationcontroller rather than in the different view controllers and then place the notification element in navigationcontroller.view. However, thus far nothing appears in navigationcontroller.view when I try to add a label there. Has anyone had success doing this?
If I understand correctly, it seems like you want to show a view whenever your app receives a remote notification and you want to be able to display the view from anywhere inside the app. If this is correct, the best approach would be to create a new UIWindow object and display that as an overlay on top of your app's main window. This answer describes how to create a UIWindow and display it. Additionally, this library does something similar to what you're trying to accomplish.