Statistics
| Branch: | Tag: | Revision:

root / Classes / OpenStackAppDelegate.m @ f14ddbf9

History | View | Annotate | Download (13 kB)

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 "SettingsPluginHandler.h"
21
#import "AddServerPluginHandler.h"
22
#import "OpenStackAccount.h"
23

    
24
#import "RSSFeedViewController.h"
25
#import "PithosImageViewController.h"
26

    
27
#import "RootViewController.h"
28
#import "PasscodeViewController.h"
29
#import "UIViewController+Conveniences.h"
30
#import "HTNotifier.h"
31
#import "Analytics.h"
32
#import "ProvidersViewController.h"
33

    
34
@implementation OpenStackAppDelegate
35

    
36
@synthesize window;
37
@synthesize navigationController;
38
@synthesize splitViewController;
39
@synthesize masterNavigationController;
40
@synthesize barButtonItem;
41
@synthesize rootViewController;
42

    
43
- (void)loadSettingsDefaults {
44
    
45
    // if settings haven't been set up yet, let's go ahead and set some sensible defaults
46
    
47
    // passcode settings are ALL sensitive, so they will all go in the keychain
48
    if (![Keychain getStringForKey:@"passcode_lock_passcode_on"]) {
49
        [Keychain setString:@"NO" forKey:@"passcode_lock_passcode_on"];
50
    }
51
    
52
    if (![Keychain getStringForKey:@"passcode_lock_simple_passcode_on"]) {
53
        [Keychain setString:@"YES" forKey:@"passcode_lock_simple_passcode_on"];
54
    }
55
    
56
    if (![Keychain getStringForKey:@"passcode_lock_erase_data_on"]) {
57
        [Keychain setString:@"NO" forKey:@"passcode_lock_erase_data_on"];
58
    }
59
    
60
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
61
    
62
    if (![defaults stringForKey:@"api_logging_level"]) {
63
        [defaults setValue:@"all" forKey:@"api_logging_level"];
64
    }
65
    
66
    if (![defaults stringForKey:@"aboutURL"]) {
67
        [defaults setValue:@"https://plus.pithos.grnet.gr" forKey:@"aboutURL"];
68
    } 
69
    
70
    [defaults synchronize];
71
    
72
}
73

    
74
- (void)presentAndRelease:(NSTimer *)timer {
75
    UIViewController *vc = [timer.userInfo objectForKey:@"vc"];
76
    [[self.navigationController topViewController] presentModalViewControllerWithNavigation:vc animated:NO];
77
    [vc release];
78
}
79

    
80
- (void)showPasscodeLock {
81
    if ([[Keychain getStringForKey:@"passcode_lock_passcode_on"] isEqualToString:@"YES"]) {
82
        PasscodeViewController *vc = [[PasscodeViewController alloc] initWithNibName:@"PasscodeViewController" bundle:nil];
83
        vc.mode = kModeEnterPasscode;
84
        //vc.rootViewController = self;
85
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
86
            vc.modalPresentationStyle = UIModalPresentationFullScreen;
87
        }                
88
        
89
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
90
            OpenStackAppDelegate *app = [[UIApplication sharedApplication] delegate];
91
            for (UIViewController *svc in app.splitViewController.viewControllers) {
92
                svc.view.alpha = 0.0;
93
            }
94
            
95
            // for some reason, this needs to be delayed
96
            [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(presentAndRelease:) userInfo:[NSDictionary dictionaryWithObject:vc forKey:@"vc"] repeats:NO];
97
            
98
        } else {
99
            [[self.navigationController topViewController] presentModalViewControllerWithNavigation:vc animated:NO];
100
            [vc release];
101
        }
102
    }
103
}
104

    
105
#pragma mark -
106
#pragma mark Application lifecycle
107

    
108
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
109
    // Override point for customization after application launch.
110
//    [self setupDependencies];
111
        
112
    [self loadSettingsDefaults];
113
        
114
    rootViewController = [navigationController.viewControllers objectAtIndex:0];
115
    OpenStackAppDelegate <UINavigationControllerDelegate> *delegate = (OpenStackAppDelegate <UINavigationControllerDelegate> *)self;
116
    navigationController.delegate = delegate;
117
        
118
    // Add the navigation controller's view to the window and display.
119
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
120
        
121
        /*RSSFeedViewController *vc = [[RSSFeedViewController alloc] initWithNibName:@"RSSFeedViewController" bundle:nil];
122
        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]];*/
123
        
124
        PithosImageViewController *vc = [[PithosImageViewController alloc] initWithNibName:@"PithosImageViewController" bundle:nil];
125
        self.masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease];
126
        self.masterNavigationController.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
127
        self.masterNavigationController.navigationBar.translucent = self.navigationController.navigationBar.translucent;
128
        self.masterNavigationController.navigationBar.opaque = self.navigationController.navigationBar.opaque;
129
        self.masterNavigationController.navigationBar.barStyle = self.navigationController.navigationBar.barStyle;
130
        
131
        self.splitViewController.delegate = [navigationController.viewControllers objectAtIndex:0];
132
        self.splitViewController.viewControllers = [NSArray arrayWithObjects:self.navigationController, self.masterNavigationController, nil];
133
        
134
        [window addSubview:splitViewController.view];
135
        [window makeKeyAndVisible];
136
        [vc release];
137
    } else {
138
        
139
        [window addSubview:navigationController.view];
140
        [window makeKeyAndVisible];
141
    }
142

    
143
    serviceUnavailableObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"serviceUnavailable" object:nil
144
                                                                           queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification* notification) 
145
    {
146
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Service Unavailable" message:@"The API is currently unavailable.  Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
147
        [alert show];
148
        [alert release];
149
        [[NSNotificationCenter defaultCenter] removeObserver:serviceUnavailableObserver];
150
    }];
151
        
152
    return YES;
153
}
154

    
155
//- (void) setupDependencies {
156
//#if TARGET_OS_EMBEDDED
157
//    
158
//    NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"Constants" ofType:@"plist"];
159
//    
160
//    if ([[NSFileManager defaultManager] fileExistsAtPath:path]){
161
//        
162
//        NSDictionary *constants = [NSDictionary dictionaryWithContentsOfFile:path];
163
//        
164
//        [HTNotifier startNotifierWithAPIKey:[constants objectForKey:@"HOPTOAD_ACCOUNT_KEY"]
165
//                            environmentName:HTNotifierAppStoreEnvironment];
166
//        [[GANTracker sharedTracker] startTrackerWithAccountID:[constants objectForKey:@"ANALYTICS_ACCOUNT_KEY"] dispatchPeriod:10 delegate:nil];
167
//        
168
//        // track the app version
169
//        NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
170
//        [[GANTracker sharedTracker] setCustomVariableAtIndex:1 name:@"app_version" value:version withError:nil];
171
//        
172
//        DispatchAnalytics();
173
//
174
//    } else {
175
//        [HTNotifier startNotifierWithAPIKey:@"HOPTOAD_ACCOUNT_KEY" environmentName:HTNotifierAppStoreEnvironment];
176
//        [[GANTracker sharedTracker] startTrackerWithAccountID:@"ANALYTICS_ACCOUNT_KEY" dispatchPeriod:10 delegate:nil];
177
//    }
178
//    
179
//#endif
180
//}
181

    
182

    
183
- (void)applicationWillResignActive:(UIApplication *)application {
184
    
185
//    DispatchAnalytics();
186
}
187

    
188

    
189
- (void)applicationDidEnterBackground:(UIApplication *)application {
190
    /*
191
     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. 
192
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
193
     */
194
}
195

    
196

    
197
- (void)applicationWillEnterForeground:(UIApplication *)application {
198
    /*
199
     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.
200
     */
201
}
202

    
203

    
204
- (void)applicationDidBecomeActive:(UIApplication *)application {
205
    /*
206
     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.
207
     */
208
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
209
    [defaults setBool:NO forKey:@"already_failed_on_connection"];
210
    [defaults synchronize];
211
    
212
    [self showPasscodeLock];
213
    //DispatchAnalytics();
214
}
215

    
216

    
217
- (void)applicationWillTerminate:(UIApplication *)application {    
218
    /*
219
     Called when the application is about to terminate.
220
     See also applicationDidEnterBackground:.
221
     */
222
    // TODO: perhaps this is a good place to release all the stuff allocated in
223
    // +(void)initialize methods all over the place
224
//    [[SettingsPluginHandler plugins] release];
225
//    [[AddServerPluginHandler plugins] release];
226
//    [[OpenStackAccount accounts] release];
227
}
228

    
229
- (void) navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
230
    
231
    TrackViewController(viewController);
232
}
233

    
234
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
235
    if (!url)
236
        return NO;
237

    
238
    NSString *host = [url host];
239
	NSString *query = [url query];
240

    
241
    if ([host hasPrefix:@"login"] && query) {
242
        // user=
243
        NSString *authUser;
244
        NSRange userRange = [query rangeOfString:@"user=" options:NSCaseInsensitiveSearch];
245
        if (userRange.length == 0)
246
            // XXX maybe show an error message?
247
            return NO;
248
        NSUInteger authUserStartLocation = userRange.location + userRange.length;
249
        NSRange userEndRange = [query rangeOfString:@"-" options:NSCaseInsensitiveSearch 
250
                                              range:NSMakeRange(authUserStartLocation, [query length] - authUserStartLocation)];
251
        if (userEndRange.length) {
252
            authUser = [[query substringWithRange:NSMakeRange(authUserStartLocation, userEndRange.location - authUserStartLocation)]
253
                        stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
254
        } else {
255
            authUser = [[query substringFromIndex:authUserStartLocation]
256
                        stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
257
        }
258
        // token=
259
        NSString *authToken;
260
        NSRange tokenRange = [query rangeOfString:@"token=" options:NSCaseInsensitiveSearch];
261
        if (tokenRange.length == 0)
262
            // XXX maybe show an error message?
263
            return NO;
264
        NSUInteger authTokenStartLocation = tokenRange.location + tokenRange.length;
265
        NSRange tokenEndRange = [query rangeOfString:@"&" options:NSCaseInsensitiveSearch 
266
                                               range:NSMakeRange(authTokenStartLocation, [query length] - authTokenStartLocation)];
267
        if (tokenEndRange.length) {
268
            authToken = [[query substringWithRange:NSMakeRange(authTokenStartLocation, tokenEndRange.location - authTokenStartLocation)]
269
                         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
270
        } else {
271
            authToken = [[query substringFromIndex:authTokenStartLocation]
272
                         stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
273
        }
274
        
275
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
276
            if (authToken)
277
                [masterNavigationController.visibleViewController setValue:authToken forKey:@"apiKey"];
278
            if (authUser)
279
                [masterNavigationController.visibleViewController setValue:authUser forKey:@"userName"];
280
            [((UITableViewController *)masterNavigationController.visibleViewController).tableView reloadData];        
281
        } else {
282
            if (authToken)
283
                [navigationController.visibleViewController setValue:authToken forKey:@"apiKey"];
284
            if (authUser)
285
                [navigationController.visibleViewController setValue:authUser forKey:@"userName"];
286
            [((UITableViewController *)navigationController.visibleViewController).tableView reloadData];        
287
        }
288
    }
289
    // XXX else maybe show an error message?
290
    
291
    return YES;
292
}
293

    
294

    
295
#pragma mark -
296
#pragma mark Memory management
297

    
298
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
299
    /*
300
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
301
     */
302
}
303

    
304

    
305
- (void)dealloc {
306
	[navigationController release];
307
    [splitViewController release];
308
    [masterNavigationController release];
309
    [barButtonItem release];
310
    [rootViewController release];
311
	[window release];
312
	[super dealloc];
313
}
314

    
315

    
316
@end
317