How can I restart my iphone application [duplicate] - iphone

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Force iphone app to restart programmatically
How can I restart/reopen my iphone/iPad application programmatically

Note:
Although this has been down-voted I think it is a perfectly valid question for a new iOS developer to ask. There is a way to 'restart' your app from the user's perspective which is not technically restarting or exiting the iOS App. As pointed out by other answers an iOS App should never explicitly exit because this is not allowed on iOS.
My Answer:
If you want your app to go back to the state it was in at launch this is not 100% possible but I will explain a way to get most of the way there that should be sufficient for all valid purposes.
The first thing to do is to re-create your root view controller. I recommend doing this from a method in the app delegate like this:
- (void)resetAppToFirstController
{
self.window.rootViewController = [[MyMainViewController alloc] initWithNibName:nil bundle:nil];
}
In many cases this will be enough, but any app-state that you have should also be reset in this method. For example log out a user, reset any non-persistent state, and nullify (release) all objects that you can. This method can also be used to initially create your first view controller from application:didFinishLaunchingWithOptions.
Framework classes and Singletons:
You will not be able to completely reset the state of any framework singletons or per-app instances, such as these:
[UIApplication sharedApplication];
[NSNotificationCenter defaultCenter];
[NSUserDefaults standardUserDefaults];
[UIScreen screens];
// etc...
That is probably fine as you shouldn't be storing any non-persistent state in these anyway (except NSNotificationCenter, but all registered observers should have been removed when the objects were released). If you do want to initialise or reset any framework state you can do it in the same resetAppToFirstController method. Anyway, there should be no need to re-create these, or the window object.
If you have any of your own singletons, you can re-create these by storing them in a singleton-holder class (which is itself a real singleton). Conceptually, this is a simple singleton class with properties for each of your other singletons and a reset method to nullify and release them all. Your other singletons should use this class (instead of a static or global variable) to store singleton instances. Be careful if you use any third party libraries as they may also employ singletons and you will need to ensure these also use your singleton-holder so that you can reset them as needed. I think this technique is good practice anyway, because in some cases (for example unit testing) you do want objects which are usually singletons to go away and reinitialise to a pristine state. However, you don't want to couple the singleton implementations with your singleton-holder, so a good way to implement this is by using an NSMutableDictionary as an associated object on [UIApplication sharedApplication] with the singleton class names as keys. However, I'm going off topic a bit as this is a more advanced technique beyond the scope of this question.
The above should be sufficient to 'reset' your application as far as the user is concerned. You can even show the splash screen again if you want as your first view controller.

No, there is no way to restart an iOS application programmatically. The application's lifecycle is controlled by the OS.

Related

How do I tie up appDelegate to the rest of the app?

I am a relative beginner to iOS development, but I managed to get my app to do everything I want it to. However, I have some questions about tying the app up together.
The only code I have currently inside my appDelegate handles remote notifications; when I receive a remote notification I send out the alerts, messages, and so on to the user. I also generate notifications for the notification center which cause different methods to run inside different view controllers.
What about all the different functions in the appDelegate? DidEnterBackground, WillEnterForeground, etc.? My app starts on one view (view1), which creates an object (stream1), which has a method stopStream. I have buttons to start and stop the streams ([self.stream1 stopStream]). My question in, how do I call these methods to stop that particular instance of the object in one of the appDelegate methods? Do I need to create a notification for the notification center inside the appDelegate, and handle it triggering in the view? Or is there a simpler method? Or am I doing things completely wrong and not according to best practices?
Any help would be appreciated! Also a link to a guide about the architecture of apps, or a link to your favorite book about building apps in iOS would be great!
Your app delegate only needs to implement the various app delegate methods if the app delegate actually needs to do something with those events.
If a given view controller or other class is interested in the various app delegate notifications (such as enter background, or return to foreground, etc.), then the view controller or other class should register for the corresponding notification. See the docs for UIApplication for the different notifications.
Do not have the app delegate method post a custom notification.
All the methods you're looking for can be found listed here in the docs.
As for what to do about them thats definitely up to your app. It is best practice to handle at least going in and out of the background properly so at least use the methods for those and take the appropriate action in your app.
Its very common for apps to simply blast out NSNotifications like you mention. Its perfectly acceptable in most circumstances.

Is setting a pointer from a singleton to a viewController and updating GUI a violation of MVC

I'd like to ask a theoretical question pertaining to good code practice and the MVC model, Here is the case:
The design contains a RootViewController and a singleton class. The singleton acts as a controller with a timer objects that should be available throughout the app. The timer object consists of a UISwitch and an NSTimer, they are both owned by the singleton controller so the UISwitch can be added to new viewControllers on demand and the timer object is accessible throughout the app.
In order to update the RootViewController's screen with the current timer's count i created a pointer in the singleton to the RootViewController and have the RootViewController set itself to that pointer, similar to [singeltonOBject setDelegate:self].
Using this design the UILabel of the RootViewController can be accessed and updated from the singleton when the timer ticks. I chose to do that because i didn't have time to implement a regular delegate.
Note that the RootViewController is owned by the AppDelegate and the the singleton class is obviously NOT owned by the RootViewController. Therefore there is no retain cycle.
Question:
Is the setting of a pointer from the singleton to the RootViewController and updating the UILable from the singleton controller a violation of good coding practice, are there any basic principles that are not fulfilled?
Thanks for your answer!
Problem
Generally when something doesn't feel quite right, thats because it's not.
While your code will work it is not going to be easy to maintain in the future and is liable to breaking. Even if you never plan on looking at this code again, it is always good to practice good coding conventions.
I recommend reading The Pragmatic Programmer which contains lots of tips for programmers on how to write better code. One of those tips is Minimize Coupling Between Modules. Right now your RootViewController knows about your Singleton and your Singleton knows about your RootViewController so they are both coupled to each other. In the future, when you change one you are likely to have to change the other one as well.
What if you want to add another label?
You will have to add the label in the RootViewController and then change your singleton to update that label as well.
What if you remove the label altogether? Lets say you go back to this in a years time and remove the label, suddenly there is another class that is not compiling and you might not remember why. You have broken code in a completely separate part of your application.
As for following MVC, this is in violation of that. Your view is being modified by something separate. If MVC is setup correctly you should be able to put on as many views as you want without having to change any code that is controlling data, in this case your timer.
Now as for memory management, your RootViewController is now being retained by this Singleton. Singleton's exist for the entire life of an application. You are right that you do not technically have a retain cycle however your RootViewController will now never be deallocated. In most applications this does not matter as the RootViewController always remains at the bottom of the stack but it is a coincidence and thus cannot be reliably programmed on. This is actually another tip from The Pragmatic Programmer, Don’t Program by Coincidence.
Solution
A better solution would be to use a notifications if you really need a global timer like you say (another story is that your global timer singleton does not sound like a good idea). Whenever you were updating your label from within your singleton you can fire a notification instead. Your RootViewController will receive this notification and can update its label. You can pass data in a notification if needs be. Now in the future if you make a change to the view and want to update something else you only need to change code in one location (The RootViewController).

How to communicate with UI views from app delegate?

I am currently using the AppDelegate in my first iPhone app to handle application level events.
In my app I have an enabled and disabled state, so when the user selects disabled some of the buttons on the application should be set to disabled.
My AppDelegate gets notified of the state. But what is the best approach to let my UIViews know that they should disable some of their buttons?
What is the standard approach to communicate events from the AppDelegate to the UI screens?
EDIT:
My description is slightly wrong, the user can disable the buttons in my app but conditions such as lack of Wi-Fi can as well, so I need to be dynamically able to change the UI state also.
Use NSNotification class to notify to your views.
Communicate using NSNotification
Communicate using NSNotificationCenter
I would say AppDelegate is always not the best approach. In my apps, rather I prefer Singleton class, they are quite easy to use.
eg Singleton approach:
AppConfig* config = [AppConfig sharedInstance]; // AppConfig is my singleton instance
[[self usernameTextField] setText:[config studentName]];
[toggle setOn:[config alwaysShow]]; // toggle is UISwitch
hope this helps.

Difference between AppDelegate.m and View Controller.m

Could anyone tell me when we use the AppDelegate.m and AppDelegate.h during iPhone programming? I have used only the ViewController.m and ViewController.h for basic learning. I just want to know when and why AppDelegate is used.
Both define classes, but the classes are used for different things. ViewController.h/m define a view controller class that manages a hierarchy of views -- basically, one screen of an application. You might have multiple screens that each have their own view controller.
AppDelegate.h/m define a class that manages the application overall. The app will create one instance of that class and send that object messages that let the delegate influence the app's behavior at well-defined times. For example, -application:didFinishLaunchingWithOptions: is sent when the app has finished launching and is ready to do something interesting. Take a look at the UIApplicationDelegate reference page for a list of messages that the app delegate can implement to modify the behavior of the application.
I would like to add the following to #Caleb's answer.
If care is not taken, the AppDelegate could easily become one of the most accessed objects in the application. I usually refrain from calling methods in the AppDelegate from any of my ViewControllers. Unless, something needs to be reported to the AppDelegate that would influence the behaviour of the whole application.
I keep my AppDelegate for the following:
initialization: whatever needs to be done on the very first launch (after an install or an update)
data migration from version to version (e.g. if you use CoreData and migrations)
configuration of objects linked via IBOutlets from MainWindow.xib
determining the initial orientation to launch in
saving uncommitted data / state prior to the application being terminated or entering background mode
registering for the Apple Push Notification Service and sending the device token to our server
opening one of the supported application URLs (e.g. maps://)
For other use case scenarios and a more thourough description of the AppDelegate, see the iOS Application Programming Guide.
The view-controller. h/m is responsible of controlling the connection between your model and your view (more on MVC here).
AppDelegate. h/m is responsible for the life-cycle of your application. What to do when the user press the home button and exit your app, what to do when the app enter background. Things like this.

Application Design and AppDelegate

I am developing an iPhone app for some sweet undergrad research I've been working on. Sadly, my school doesn't offer software engineering / design classes so when it comes to questions of best practices in OO Design, I do a lot of reading.
My Dilemma:
My application loads a view (v1) where, upon user's button click, v1's controller class executes an action method. This action method should fill an array with objects. After that, the user will either execute the action again or click a different tab to load another view. Other views in the application will use the array that v1 populated.
So, where should this shared array be declared? Right now, it's in the AppDelegate class from when I was testing features without a GUI. Should I grab the AppDelegate singleton and add items to it in the v1ViewController? Should it be declared as static?
Thanks for the help!
^Buffalo
EDIT:
Follow-up Question: When interacting with a singleton, which is the better way to talk to it:
[[MyAwesomeSingleton sharedInstance] gimmeSomePizza];
or
MySingleton *s = [MySingleton sharedInstance];
[s gimmeSomePizza];
I guess what I'm wondering is, do you make the sharedInstance method call every time or do you define a pointer to the sharedInstance and then reference the pointer?
Using the app delegate to store data that's shared between views and view controllers is reasonable and appropriate.
In my apps, I view the app delegate as the controller part of MVC, with UIViews and view controllers all being part of the "view". I prefer to use a variant of MVC called Passive View that keeps the model and view parts of my app strictly segregated with only the controller connecting them.
I'm assuming that the array of objects you're storing is your app's model, so storing them on your app delegate makes sense. As Daniel D said, there's no need to make it static.
The app delegate is really the heart of your program. You create and initialize your model and views in your -applicationDidFinishLaunching: method and save your model data and view state in -applicationWillTerminate:. When your view controllers receive events that changes your model, you can call methods on your app delegate to make those changes.
You could store it in an ivar in the app delegate. You don't need to make it static since the app delegate is a singleton anyways (there's never more than 1 instance).
If the app delegate is getting a bit complicated, you can factor out the data storage into a separate model object or perhaps use Core Data.