didFinishLaunching is never called - iphone

I created a new window-based project and couldn't figure out why it wasn't doing anything. Eventually I put an NSLog right after didFinishLaunching and it's never logged when I run it. Here is all of the code I have written:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(#"didFinishLaunching");
// Get the device object and turn proximity monitoring on
UIDevice *d = [UIDevice currentDevice];
[d setProximityMonitoringEnabled:YES];
// Get the NSNotificationCenter object
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// Sign up to receive notifications when the proximity state changes
[nc addObserver:self selector:#selector(proximityChanged:) name:UIDeviceProximityStateDidChangeNotification object:d];
NSLog(#"Observing...");
[self.window makeKeyAndVisible];
return YES;
}
- (void)proximityChanged:(NSNotification *)note {
// Print out the changes of proximity state
NSLog(#"Proximity Changed: %d", [[note object] proximityState]);
}
That's the entirety of what I've written and nothing is logged when I run it on the simulator or on my device. Any thoughts?

Well, you are talking about Application Delegate. The obvious reason - your object is not set as an application delegate.
Looking at Apple documentation there is quite a few ways to accomplish it:
Remove application delegate binding in Interface Builder (.xib file for the window)
Set 4th parameter of UIApplicationMain in main.h to something else than nil.
Check you nib file in Interface Builder and see if the App Delegate is setup.
Reference to documentation
Core Application Design
The application delegate is a custom object that you provide at
application launch time, usually by embedding it in your application’s
main nib file. The primary job of this object is to initialize the
application and present its window onscreen. The UIApplication object
also notifies this object when specific application-level events
occur, such as when the application needs to be interrupted (because
of an incoming message) or moved to the background (because the user
tapped the Home button).
The fourth parameter identifies the class of the application delegate.
The application delegate is responsible for managing the high-level
interactions between the system and your custom code. Specifying nil
tells UIKit that the application delegate object is located in the
application’s main nib file (which is the case for applications built
using the Xcode templates).

Try removing doing a Build/Clean All Targets, remove the Build/ directory and delete the app from the simulator and/or the device. Then run it again.
As another check, try logging something in applicationDidBecomeActive:. This method will be called whether on the initial launch or resuming from the background.

Related

App resumed from Background, nil property of NSManagedObject

Conditions
Getting a notification (txt message)
or Opening/Closing Notification Center
or Switch to another app, come back
Basically, the app comes back from background for a short period.
Issue
Layout is ok, but some of my properties that I get from CoreData are empty after resuming from Background. This issue is there on pretty much all of my view controllers.
The project
This is an app that has a main tabbar controller, with two navigationcontrollers within the tabs and maybe two levels of viewcontrollers, that have themselves child UIViews (that use some of the informations). The back-end is made of Parse and CoreData.
The weird part
Back from background -> properties are ok on viewWillAppear (Create a backup of the id) -> they are nil seconds after -> I need to manually get them back (from the ID I just stored)
Here is a screenshot, when putting a break point within a function called every 5sec to check the current time (link to bigger) :
What I did
NSCoder implemented for state restoration and every view controllers have a restoration ID, however it doesn't get called when app is becoming active. I don't think NSCoder is the issue here since from the documentation it is used when the OS will kill it on its own, or a force quit from the user.
I tried to manually refresh the content in the appropriate ViewControllers from NSNotificationCenter if the NSManagedObjects are nil, but it is not future-proof, and is never the same logic on each view.
Any thoughts? Thank you!
My AppDelegate :
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(#"Will Resign Active");
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"Entered Background");
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(#"Will enter Foreground");
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[NSNotificationCenter defaultCenter] postNotificationName:#"needsRefresh" object:self userInfo:nil]; // Helpful in some viewcontrollers to save variables that are not nil.
[PF_FBSession.activeSession handleDidBecomeActive];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
NSLog(#"Will Terminate");
}
For those finding this thread, here is the solution I found.
My issue and answer was specific to my project.
I had another controller, the one that takes care of all my database connections, that was listening to applicationDidBecomeActive.
This was calling up a refresh of my data, but also a "cleanup", that was deleting/editing some NSManagedObjects, then saving.
Conclusion : the memory address wasn't the same, the object wasn't considered the same, and therefore was empty on my current page.
I fixed it by stopping cleaning up on each AppDidBecomeActive, but move that logic to AppDidFinishLaunching instead.
Hope that helped!

Xcode default one page ios project - Why isn't the delegate responsible for loading the controller

I'm new to xcode and ios development. I'm learning using Brad Larson online courses. Now, he doesn't use storyboard to create interface. In his delegate file, he's using code for loading the rootViewController.
Now, when I create a new one page ios project, its seems like it's not the XYZAppDelegate that is responsible for loading the controller.
I know that in the mainstoryboard.storyboard file, my XYZViewController appears in there. I'm just wondering why it's not the XYZAppDelegate that is in charge of loading the viewController ?
In the appDelegate, there is nothing in the didFinishLaunchingWithOptions method but the program still loads?
However, the main.m file indicates that XYZAppDelegate is the delegateClassName.
Finally, my question is who's in charge in that case for loading the XYZViewController if it's not the AppDelegate ?
These are the default xcode generated files
main.m
return UIApplicationMain(argc, argv, nil, NSStringFromClass([XYZAppDelegate class]));
XYZAppDelegate
#import "XYZAppDelegate.h"
#implementation XYZAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
The answer lies in your Info.plist file. If you look, you'll see two keys called Main storyboard file base name and Main storyboard file base name (iPad) for which the values should be the name of your storyboard files for the respective devices. If these keys are present at launch, the OS will automatically load the storyboard file and insert the first view controller from the storyboard into the app's window. Docs here for the Info.plist key explanations (the raw key is called UIMainStoryboardFile).

Xcode4, iOS: Certain parts of instance method being ignored, no errors, just passed by

new iOS guy here. I have a problem that Googling and searching on here has not shed any light on. I'm assuming this is basic. I have a simple app (app delegate and 1 view controller), and as part of it I'm using local notification. So, in the app delegate I use the 'didReceiveLocalNotification' to watch for the notifications. Depending on which one comes in, I then call one of several instance methods in my main view controller.
ie in the AppDelegate.m
- (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification {
MyViewController* controller = [[MyViewController alloc] autorelease];
if ([[notification.userInfo objectForKey:#"id"] isEqualToString:#"myKey"]) {
[controller checkActive];
}
}
Through logging and watching some breakpoints, this is all working. If the app is in the background, the notification comes in, app opens, and the correct instance method is called.
What I cannot figure out at all is why some parts of the instance method are simply being passed by, with no effect. For a simple example, if we have this:
-(void)checkActive {
ViewThing.alpha = 1.0;
NSLog(#"checkActive ran");
}
The log statement will show up fine, but the ViewThing will not change. Elsewhere in the main view controller I'm calling the same checkActive method with no problems and it changes the ViewThing. (via another interface button IBAction method in that case).
There are no errors, no warnings, the console shows nothing, putting a breakpoint on ViewThing shows that it hits the line. I'm stumped, cannot see what is different from trying to calling the method from the delegate vs. on an IBAction.
Thanks for any tips!
If the alpha is not correctly changing there a few possible issues with 1 and 2 being the most likely.
ViewThing is nil. Reasons could be is the view unloaded and you set it to nil or checkActive was called before the outlets were set.
ViewThing.alpha is being set on a thread that is not the main thread. Attempting to change UI elements on a separate thread will caused undefined behavior such as never updating the change or taking an extended amount of time to update the change. You can check if it is the main thread using [NSThread isMainThread].
ViewThing is pointing a different view.
1 & 2 can easily be checked by logging view
NSLog(#"checkActive ran %#", ViewThing);

applicationWillTerminate, delegate or view?

I am looking to save some settings when my application exits and I am a little confused about the 2 different versions below. My feeling is that to better fit the MVC pattern I should be using the version in the viewController. I am just curious as most folks don't seem to do much in the appDelegate when that call would be used?
AppDelegate
-(void)applicationWillTerminate:(UIApplication *)application {
NSLog(#"_deli: applicationWillTerminate");
}
ViewController
-(void)applicationWillTerminate:(NSNotification *)notification {
NSLog(#"_view: applicationWillTerminate");
}
many thanks
EDIT_001:
Sorry, I should claifiy, you would also need to add (see below) to the ViewController to make the above work.
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:app];
gary
Use whichever one has access to the data you want to save. So if the ViewController can see the data but the AppDelegate can't, use that.
Well, to flog my personal hobby horse, I would say that settings are a form of preferences that should be saved in a dedicated data model. NSUserDefaults, for example, is a data model built on the singleton pattern. You could, of course roll your own. There is no problem with having multiple data models in the same app if they manage unrelated information.
The key is to save defaults/preference/state as they are made. Then when the application quits the defaults are already automatically saved. Remember that on the iPhone you never know when the app will be interrupted or quit. Save as you go is really the only option.
Also, in the code examples you provided, how will the view controller know when the application quits? IIRC, UIViewController does not have a applicationWillTerminate: method and does not automatically receive a specific app will quit message. (Edit: In the comments, KennyTM points out that the view controller can register and listen for UIApplicationWillTerminateNotification) You would have to put this functionality in -viewWillUnload. Otherwise, you would have to track your view controllers from the app delegate have the delegate send the active view controller a message when the app quit.

Where does UIApplication's handleOpenURL 'Return' to exactly?

I'm working on a handling a custom URL Scheme in an app and am trying to sort out:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
I'm passing and successfully parsing a URL into an NSDictionary in my app but wondering "what now?" handleOpenURL returns a BOOL but to what? It's hard for me to debug as I haven't figure out how to have debugger running on device when it fires.
All I do know is that applicationDidFinishLaunching completes before handleOpenURL and it appears as though my rootViewController is on screen.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Load data
[self initializeData];
// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
Anyway, so, now I have this NSDictionary object in my appDelegate, how would you pass it to the rootViewController so it can do something with it in its detail view? Would I call
[[navigationController topViewController] addItemWithDictionary:theDictionary];
before handleOpenURL's return YES; Or, should I create an NSDictionary property in my appDelegate and then after "Return YES;" retrieve it from my rootViewController (or detailViewController - haven't worked out which yet). If so what's the trigger? It's not clear to me where handleOpenUrl's returns are heading...and what, if any, value they have to me.
Thanks!
Take a look at the suggestion here about didFinishLaunchingWithOptions
http://www.iphonedevsdk.com/forum/iphone-sdk-development/31742-handleopenurl-not-called.html
There are a couple of approaches I've used to pass data around, and depending on the conditions I mix it up.
Keep a global around so you don't have to worry about passing.
Register/post your data using the Observer pattern with a Notification object using the notification message center.
Save URLs to NSUserDefaults (also a dictionary, but you don't have to manage it).
Recently I had to do something similar on a UIWebView and the handling of filtering some URL data. I had to subclass WebViewCache and setSharedCache on the NSURL. I strongly suspect this would apply to your problem as well by retrieving the data with shouldStartLoadWithRequest.
a handy tip for debugging openurl from other apps or mobile safari (non jailbroken device) is to subclass UIApplication and override a few undocumented methods, sorry i dont remember names offhand but you can dig them up at ericasadun.com, the names will be fairly obvious.
when you launch the app through xcode and hit home springboard doesnt kill the process because it was started by xcode (afaik) so you can launch other apps and call openurl while still being attached to the debugger.
I think I may have answered my own question but if you have other ideas I'd love to hear them!
I think I need to continue processing in handleOpenURL and turn the dictionary into an object that is then added to my appDelegate's array that rootViewController is using to build it's table view. Obviously need to work out some validation & confirmation on user's part before auto populating array. I guess that would also happen within confines of handleOpenURL?