2 // OpenStackAppDelegate.m
5 // Created by Mike Mayo on 9/30/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "OpenStackAppDelegate.h"
10 #import "RootViewController.h"
11 #import "OpenStackAccount.h"
21 #import "SettingsPluginHandler.h"
22 #import "AddServerPluginHandler.h"
23 #import "OpenStackAccount.h"
25 #import "RSSFeedViewController.h"
27 #import "RootViewController.h"
28 #import "PasscodeViewController.h"
29 #import "UIViewController+Conveniences.h"
30 #import "HTNotifier.h"
33 @implementation OpenStackAppDelegate
36 @synthesize navigationController;
37 @synthesize splitViewController;
38 @synthesize masterNavigationController;
39 @synthesize barButtonItem;
40 @synthesize rootViewController;
42 - (void)loadSettingsDefaults {
44 // if settings haven't been set up yet, let's go ahead and set some sensible defaults
46 // passcode settings are ALL sensitive, so they will all go in the keychain
47 if (![Keychain getStringForKey:@"passcode_lock_passcode_on"]) {
48 [Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"];
51 if (![Keychain getStringForKey:@"passcode_lock_simple_passcode_on"]) {
52 [Keychain setString:@"YES" forKey:@"passcode_lock_simple_passcode_on"];
55 if (![Keychain getStringForKey:@"passcode_lock_erase_data_on"]) {
56 [Keychain setString:@"NO" forKey:@"passcode_lock_erase_data_on"];
59 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
61 if (![defaults stringForKey:@"api_logging_level"]) {
62 [defaults setValue:@"all" forKey:@"api_logging_level"];
65 [defaults synchronize];
69 - (void)presentAndRelease:(NSTimer *)timer {
70 UIViewController *vc = [timer.userInfo objectForKey:@"vc"];
71 [[self.navigationController topViewController] presentModalViewControllerWithNavigation:vc animated:NO];
75 - (void)showPasscodeLock {
76 if ([[Keychain getStringForKey:@"passcode_lock_passcode_on"] isEqualToString:@"YES"]) {
77 PasscodeViewController *vc = [[PasscodeViewController alloc] initWithNibName:@"PasscodeViewController" bundle:nil];
78 vc.mode = kModeEnterPasscode;
79 //vc.rootViewController = self;
80 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
81 vc.modalPresentationStyle = UIModalPresentationFullScreen;
84 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
85 OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
86 for (UIViewController *svc in app.splitViewController.viewControllers) {
90 // for some reason, this needs to be delayed
91 [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(presentAndRelease:) userInfo:[NSDictionary dictionaryWithObject:vc forKey:@"vc"] repeats:NO];
94 [[self.navigationController topViewController] presentModalViewControllerWithNavigation:vc animated:NO];
101 #pragma mark Application lifecycle
103 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
105 // Override point for customization after application launch.
107 [self setupDependencies];
109 [self loadSettingsDefaults];
111 rootViewController = [navigationController.viewControllers objectAtIndex:0];
112 OpenStackAppDelegate <UINavigationControllerDelegate> *delegate = self;
113 navigationController.delegate = delegate;
115 // Add the navigation controller's view to the window and display.
116 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
118 RSSFeedViewController *vc = [[RSSFeedViewController alloc] initWithNibName:@"RSSFeedViewController" bundle:nil];
119 vc.feed = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"Cloud Servers Status", @"feed://status.rackspacecloud.com/cloudservers/rss.xml", kCloudServersIcon, nil] forKeys:[NSArray arrayWithObjects:@"name", @"url", @"logo", nil]];
121 self.masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease];
122 self.masterNavigationController.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
123 self.masterNavigationController.navigationBar.translucent = self.navigationController.navigationBar.translucent;
124 self.masterNavigationController.navigationBar.opaque = self.navigationController.navigationBar.opaque;
125 self.masterNavigationController.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
127 self.splitViewController.delegate = [navigationController.viewControllers objectAtIndex:0];
128 self.splitViewController.viewControllers = [NSArray arrayWithObjects:self.navigationController, self.masterNavigationController, nil];
130 [window addSubview:splitViewController.view];
131 [window makeKeyAndVisible];
134 [window addSubview:navigationController.view];
135 [window makeKeyAndVisible];
138 serviceUnavailableObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"serviceUnavailable" object:nil
139 queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification)
141 UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Service Unavailable" message:@"The API is currently unavailable. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
144 [[NSNotificationCenter defaultCenter] removeObserver:serviceUnavailableObserver];
150 - (void) setupDependencies {
151 #if TARGET_OS_EMBEDDED
153 NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"Constants" ofType:@"plist"];
155 if ([[NSFileManager defaultManager] fileExistsAtPath:path]){
157 NSDictionary *constants = [NSDictionary dictionaryWithContentsOfFile:path];
159 [HTNotifier startNotifierWithAPIKey:[constants objectForKey:@"HOPTOAD_ACCOUNT_KEY"]
160 environmentName:HTNotifierAppStoreEnvironment];
161 [[GANTracker sharedTracker] startTrackerWithAccountID:[constants objectForKey:@"ANALYTICS_ACCOUNT_KEY"] dispatchPeriod:10 delegate:nil];
163 // track the app version
164 NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
165 [[GANTracker sharedTracker] setCustomVariableAtIndex:1 name:@"app_version" value:version withError:nil];
170 [HTNotifier startNotifierWithAPIKey:@"HOPTOAD_ACCOUNT_KEY" environmentName:HTNotifierAppStoreEnvironment];
171 [[GANTracker sharedTracker] startTrackerWithAccountID:@"ANALYTICS_ACCOUNT_KEY" dispatchPeriod:10 delegate:nil];
178 - (void)applicationWillResignActive:(UIApplication *)application {
180 // DispatchAnalytics();
184 - (void)applicationDidEnterBackground:(UIApplication *)application {
186 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.
187 If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
192 - (void)applicationWillEnterForeground:(UIApplication *)application {
194 Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
199 - (void)applicationDidBecomeActive:(UIApplication *)application {
201 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.
203 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
204 [defaults setBool:NO forKey:@"already_failed_on_connection"];
205 [defaults synchronize];
207 [self showPasscodeLock];
208 //DispatchAnalytics();
212 - (void)applicationWillTerminate:(UIApplication *)application {
214 Called when the application is about to terminate.
215 See also applicationDidEnterBackground:.
217 // TODO: perhaps this is a good place to release all the stuff allocated in
218 // +(void)initialize methods all over the place
219 // [[APILogger loggerEntries] release];
220 // [[SettingsPluginHandler plugins] release];
221 // [[AddServerPluginHandler plugins] release];
222 // [[OpenStackAccount accounts] release];
225 - (void) navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
227 TrackViewController(viewController);
232 #pragma mark Memory management
234 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
236 Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
242 [navigationController release];
243 [splitViewController release];
244 [masterNavigationController release];
245 [barButtonItem release];
246 [rootViewController release];