Added account groups functionality.
[pithos-ios] / Classes / OpenStackAppDelegate.m
1 //
2 //  OpenStackAppDelegate.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 9/30/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "OpenStackAppDelegate.h"
10 #import "RootViewController.h"
11 #import "OpenStackAccount.h"
12 #import "Keychain.h"
13
14 #import "JSON.h"
15 #import "Server.h"
16 #import "Archiver.h"
17 #import "Provider.h"
18 #import "Image.h"
19
20 #import "APILogger.h"
21 #import "SettingsPluginHandler.h"
22 #import "AddServerPluginHandler.h"
23 #import "OpenStackAccount.h"
24
25 #import "RSSFeedViewController.h"
26
27 #import "RootViewController.h"
28 #import "PasscodeViewController.h"
29 #import "UIViewController+Conveniences.h"
30 #import "HTNotifier.h"
31 #import "Analytics.h"
32
33 @implementation OpenStackAppDelegate
34
35 @synthesize window;
36 @synthesize navigationController;
37 @synthesize splitViewController;
38 @synthesize masterNavigationController;
39 @synthesize barButtonItem;
40 @synthesize rootViewController;
41
42 - (void)loadSettingsDefaults {
43     
44     // if settings haven't been set up yet, let's go ahead and set some sensible defaults
45     
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"];
49     }
50     
51     if (![Keychain getStringForKey:@"passcode_lock_simple_passcode_on"]) {
52         [Keychain setString:@"YES" forKey:@"passcode_lock_simple_passcode_on"];
53     }
54     
55     if (![Keychain getStringForKey:@"passcode_lock_erase_data_on"]) {
56         [Keychain setString:@"NO" forKey:@"passcode_lock_erase_data_on"];
57     }
58     
59     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
60     
61     if (![defaults stringForKey:@"api_logging_level"]) {
62         [defaults setValue:@"all" forKey:@"api_logging_level"];
63     }
64
65     [defaults synchronize];
66     
67 }
68
69 - (void)presentAndRelease:(NSTimer *)timer {
70     UIViewController *vc = [timer.userInfo objectForKey:@"vc"];
71     [[self.navigationController topViewController] presentModalViewControllerWithNavigation:vc animated:NO];
72     [vc release];
73 }
74
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;
82         }                
83         
84         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
85             OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
86             for (UIViewController *svc in app.splitViewController.viewControllers) {
87                 svc.view.alpha = 0.0;
88             }
89             
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];
92             
93         } else {
94             [[self.navigationController topViewController] presentModalViewControllerWithNavigation:vc animated:NO];
95             [vc release];
96         }
97     }
98 }
99
100 #pragma mark -
101 #pragma mark Application lifecycle
102
103 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
104     
105     // Override point for customization after application launch.
106     
107     [self setupDependencies];
108         
109     [self loadSettingsDefaults];
110         
111     rootViewController = [navigationController.viewControllers objectAtIndex:0];
112     OpenStackAppDelegate <UINavigationControllerDelegate> *delegate = self;
113     navigationController.delegate = delegate;
114         
115     // Add the navigation controller's view to the window and display.
116     if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
117         
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]];
120         
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;
126         
127         self.splitViewController.delegate = [navigationController.viewControllers objectAtIndex:0];
128         self.splitViewController.viewControllers = [NSArray arrayWithObjects:self.navigationController, self.masterNavigationController, nil];
129         
130         [window addSubview:splitViewController.view];
131         [window makeKeyAndVisible];
132         [vc release];
133     } else {
134         [window addSubview:navigationController.view];
135         [window makeKeyAndVisible];
136     }
137     
138     serviceUnavailableObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"serviceUnavailable" object:nil
139                                                                            queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) 
140     {
141         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Service Unavailable" message:@"The API is currently unavailable.  Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
142         [alert show];
143         [alert release];
144         [[NSNotificationCenter defaultCenter] removeObserver:serviceUnavailableObserver];
145     }];
146     
147     return YES;
148 }
149
150 - (void) setupDependencies {
151 #if TARGET_OS_EMBEDDED
152     
153     NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"Constants" ofType:@"plist"];
154     
155     if ([[NSFileManager defaultManager] fileExistsAtPath:path]){
156         
157         NSDictionary *constants = [NSDictionary dictionaryWithContentsOfFile:path];
158         
159         [HTNotifier startNotifierWithAPIKey:[constants objectForKey:@"HOPTOAD_ACCOUNT_KEY"]
160                             environmentName:HTNotifierAppStoreEnvironment];
161         [[GANTracker sharedTracker] startTrackerWithAccountID:[constants objectForKey:@"ANALYTICS_ACCOUNT_KEY"] dispatchPeriod:10 delegate:nil];
162         
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];
166         
167         DispatchAnalytics();
168
169     } else {
170         [HTNotifier startNotifierWithAPIKey:@"HOPTOAD_ACCOUNT_KEY" environmentName:HTNotifierAppStoreEnvironment];
171         [[GANTracker sharedTracker] startTrackerWithAccountID:@"ANALYTICS_ACCOUNT_KEY" dispatchPeriod:10 delegate:nil];
172     }
173     
174 #endif
175 }
176
177
178 - (void)applicationWillResignActive:(UIApplication *)application {
179     
180 //    DispatchAnalytics();
181 }
182
183
184 - (void)applicationDidEnterBackground:(UIApplication *)application {
185     /*
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.
188      */
189 }
190
191
192 - (void)applicationWillEnterForeground:(UIApplication *)application {
193     /*
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.
195      */
196 }
197
198
199 - (void)applicationDidBecomeActive:(UIApplication *)application {
200     /*
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.
202      */
203     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
204     [defaults setBool:NO forKey:@"already_failed_on_connection"];
205     [defaults synchronize];
206     
207     [self showPasscodeLock];
208     //DispatchAnalytics();
209 }
210
211
212 - (void)applicationWillTerminate:(UIApplication *)application {    
213     /*
214      Called when the application is about to terminate.
215      See also applicationDidEnterBackground:.
216      */
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];
223 }
224
225 - (void) navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
226     
227     TrackViewController(viewController);
228 }
229
230
231 #pragma mark -
232 #pragma mark Memory management
233
234 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
235     /*
236      Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
237      */
238 }
239
240
241 - (void)dealloc {
242         [navigationController release];
243     [splitViewController release];
244     [masterNavigationController release];
245     [barButtonItem release];
246     [rootViewController release];
247         [window release];
248         [super dealloc];
249 }
250
251
252 @end
253