Created
October 29, 2014 18:07
-
-
Save bobspryn/757825aed9c1ffaf75b7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TCAppDelegate.m | |
// Three Cents | |
// | |
// Created by Shaun Parker on 11/5/12. | |
// Copyright (c) 2012 Three Cents, Inc. All rights reserved. | |
// | |
#if DEBUG | |
//#import <SparkInspector/SparkInspector.h> | |
#endif | |
#import "TCAppDelegate.h" | |
#import "TCLoginRegisterViewController.h" | |
#import "TCSidebarNavigationController.h" | |
#import "TCQuestionDetailViewController.h" | |
#import "TCNotificationHelper.h" | |
#import "TMCache.h" | |
#import "TCAppearanceHelper.h" | |
#import "TCPortraitNavigationController.h" | |
#include "Emulos.h" | |
@interface TCAppDelegate () <UIApplicationDelegate> | |
@property (nonatomic, assign) BOOL questionModalShowing; | |
@end | |
@implementation TCAppDelegate | |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions | |
{ | |
// Enable the Spark Inspector | |
#if DEBUG | |
// [SparkInspector enableObservation]; | |
#else | |
[Crashlytics startWithAPIKey:@"f49534b780942f5b9090bb0cc29853032692176c"]; | |
// [Emulos startWithAPIKey:@"78dbfe5d-7984-454a-83ed-47130194fdf5"]; | |
// NSString *bundleNumberString = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)kCFBundleVersionKey]; | |
// NSString *versionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString*)@"CFBundleShortVersionString"]; | |
// [Emulos addTagToCurrentDevice:[NSString stringWithFormat:@"%@-%@", versionString, bundleNumberString]]; | |
#endif | |
self.deckController = (TCViewDeckController *)self.window.rootViewController; | |
// Override point for customization after application launch. | |
[self initRestKit]; | |
#if defined (CONFIGURATION_DEBUG) | |
#elif defined (CONFIGURATION_BETA) | |
#elif defined (CONFIGURATION_RELEASE) | |
#endif | |
[TCAppearanceHelper customizeAppAppearance]; | |
__weak TCAppDelegate *weakself = self; | |
[[NSNotificationCenter defaultCenter] addObserverForName:TC_DID_LOGIN_NOTIFICATION object:nil queue:nil usingBlock:^(NSNotification *note) { | |
[weakself syncRemoteData]; | |
[weakself loadMyQuestions]; | |
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: | |
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; | |
// [Emulos addTagToCurrentDevice:[NSString stringWithFormat:@"%@", [TCUser me].userId.stringValue]]; | |
}]; | |
[[TMCache sharedCache] removeAllObjects]; | |
if (launchOptions != nil) | |
{ | |
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; | |
if (dictionary != nil) | |
{ | |
NSString *notificationKey = [dictionary valueForKeyPath:@"aps.alert.loc-key"]; | |
NSMutableSet * matches = [NSMutableSet setWithArray:@[@"Q_CMT", @"Q_ASK", @"Q_ANS"]]; | |
[matches filterUsingPredicate:[NSPredicate predicateWithFormat:@"SELF contains[c] %@", notificationKey]]; | |
if (matches.count > 0) { | |
// [self handleNotificationWithUserInfo:dictionary showModal:YES]; | |
} | |
} | |
} | |
self.questionModalShowing = NO; | |
return YES; | |
} | |
- (void)initRestKit | |
{ | |
// TCObjectManager *objectManager = [TCObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://localhost:8000/api/v1"]]; | |
TCObjectManager *objectManager = [TCObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://three-cents.herokuapp.com/api/v1"]]; | |
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; | |
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel]; | |
objectManager.managedObjectStore = managedObjectStore; | |
[managedObjectStore createPersistentStoreCoordinator]; | |
NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"ThreeCents.sqlite"]; | |
NSError *error; | |
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:&error]; | |
NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error); | |
[managedObjectStore createManagedObjectContexts]; | |
// commented out until we find fixes for this. | |
// managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext]; | |
[objectManager setupRestkitMapping]; | |
if ([TCUser me]) { | |
[objectManager.HTTPClient setDefaultHeader:@"X-AUTH-TOKEN" value:[TCUser me].userId.stringValue]; | |
// [Emulos addTagToCurrentDevice:[NSString stringWithFormat:@"%@", [TCUser me].userId.stringValue]]; | |
} | |
} | |
- (void)syncRemoteData | |
{ | |
//TODO: put this in a better place? | |
[TCAPI getCategoriesModifiedSince:nil onComplete:^(NSArray *objects, RKObjectRequestOperation *operation, NSError *error) { | |
if (error) { | |
//TODO: Handle error | |
CLS_LOG(@"Failed to load categories: [%@]", error); | |
} else { | |
CLS_LOG(@"Loaded categories"); | |
[TCAPI getQuestionTemplatesModifiedSince:nil | |
onComplete:^(NSArray *objects, RKObjectRequestOperation *operation, NSError *error) { | |
if (error) { | |
//TODO: Handle error | |
CLS_LOG(@"Failed to load templates: [%@]", error); | |
} else { | |
CLS_LOG(@"Loaded templates"); | |
} | |
}]; | |
} | |
}]; | |
} | |
- (void) loadMyQuestions { | |
// We load in the answered and asked questions to make sure we create any notifications for modified ones | |
if ([TCUser me]) { | |
[TCAPI getQuestionsAskedAfterQuestion:nil onComplete:^(NSArray *objects, RKObjectRequestOperation *operation, NSError *error) { | |
}]; | |
[TCAPI getQuestionsAnsweredAfterQuestion:nil onComplete:^(NSArray *objects, RKObjectRequestOperation *operation, NSError *error) { | |
}]; | |
} | |
} | |
- (void)applicationWillResignActive:(UIApplication *)application | |
{ | |
} | |
- (void)applicationDidEnterBackground:(UIApplication *)application | |
{ | |
} | |
- (void)applicationWillEnterForeground:(UIApplication *)application | |
{ | |
} | |
- (void)applicationDidBecomeActive:(UIApplication *)application | |
{ | |
// We need to properly handle activation of the application with regards to Facebook Login | |
// (e.g., returning from iOS 6.0 Login Dialog or from fast app switching). | |
[self checkUserAndPresentLoginIfNecessary]; | |
[FBSession.activeSession handleDidBecomeActive]; | |
// [self loadMyQuestions]; | |
} | |
- (void)applicationWillTerminate:(UIApplication *)application | |
{ | |
[FBSession.activeSession close]; | |
} | |
/* | |
* If we have a valid session at the time of openURL call, we handle | |
* Facebook transitions by passing the url argument to handleOpenURL | |
* Probably don't need this with iOS6, but won't hurt anything | |
*/ | |
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { | |
// attempt to extract a token from the url | |
return [FBSession.activeSession handleOpenURL:url]; | |
} | |
- (void) checkUserAndPresentLoginIfNecessary { | |
TCUser *me = [TCUser me]; | |
if (IsEmpty(me) && ![self.loginViewController isBeingPresented]) { | |
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; | |
self.loginViewController = [storyboard instantiateViewControllerWithIdentifier:@"TCLoginRegisterViewController"]; | |
[self.deckController presentViewController:self.loginViewController animated:NO completion:nil]; | |
} else { | |
[self syncRemoteData]; | |
[self loadMyQuestions]; | |
// refresh facebook login | |
[TCAPI openSessionWithAllowLoginUI:YES withCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) { | |
if (!error && status == FBSessionStateOpen) { | |
} else { | |
//TODO: Add alert here | |
} | |
}]; | |
} | |
} | |
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken | |
{ | |
NSString *newToken = [deviceToken description]; | |
newToken = [newToken stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; | |
newToken = [newToken stringByReplacingOccurrencesOfString:@" " withString:@""]; | |
NSString * appVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; | |
NSString * appBuildString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; | |
NSString *fullVersion = [NSString stringWithFormat:@"%@ (%@)", appVersionString, appBuildString]; | |
[TCAPI postDeviceToken:newToken forEnvironment:@"development" appVersion:fullVersion]; | |
} | |
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error | |
{ | |
NSLog(@"Failed to get token, error: %@", error); | |
} | |
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo | |
{ | |
NSString *notificationKey = [userInfo valueForKeyPath:@"aps.alert.loc-key"]; | |
NSMutableSet * matches = [NSMutableSet setWithArray:@[@"Q_CMT", @"Q_ASK", @"Q_ANS"]]; | |
[matches filterUsingPredicate:[NSPredicate predicateWithFormat:@"SELF contains[c] %@", notificationKey]]; | |
if (matches.count > 0) { | |
// [self handleNotificationWithUserInfo:userInfo showModal:[application applicationState] == UIApplicationStateInactive]; | |
} | |
} | |
// always fetch the new stuff | |
- (void) handleNotificationWithUserInfo:(NSDictionary *)userInfo showModal:(BOOL)showModal { | |
NSNumber *questionId = (NSNumber *)[userInfo valueForKey:@"q"]; | |
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[TCQuestion entityName]]; | |
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"questionId == %d", questionId]; | |
fetchRequest.fetchLimit = 1; | |
NSError *error; | |
NSArray *result = [TCMainContext executeFetchRequest:fetchRequest error:&error]; | |
BOOL alreadyShowing = NO; | |
if (!IsEmpty(result)) { | |
[self showQuestionModalWithQuestion:(TCQuestion *)result[0]]; | |
alreadyShowing = YES; | |
} | |
[TCAPI getQuestionWithQuestionId:questionId onComplete:^(NSArray *objects, RKObjectRequestOperation *operation, NSError *error) { | |
if (error) { | |
//TODO: Show Error | |
} else { | |
if (objects.count > 0 && !alreadyShowing && showModal) { | |
[TCNotificationHelper checkAndRegisterNotificationForQuestion:(TCQuestion *)objects[0] inManagedObjectContext:TCMainContext showUnreadIfNew:YES]; | |
[self showQuestionModalWithQuestion:(TCQuestion *)objects[0]]; | |
} | |
} | |
}]; | |
} | |
- (void) showQuestionModalWithQuestion:(TCQuestion *)question { | |
if (self.questionModalShowing) { | |
return; | |
} | |
self.questionModalShowing = YES; | |
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; | |
TCQuestionDetailViewController *questionDetail = (TCQuestionDetailViewController *)[sb instantiateViewControllerWithIdentifier:@"TCQuestionDetailViewController"]; | |
UINavigationController *questionDetailNav = [[TCPortraitNavigationController alloc] initWithRootViewController:questionDetail]; | |
questionDetail.isInModal = YES; | |
[questionDetail configureWithQuestion:question]; | |
[questionDetail setActiveState]; | |
questionDetail.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone handler:^(id sender) { | |
[self.deckController dismissViewControllerAnimated:YES completion:^{ | |
self.questionModalShowing = NO; | |
}]; | |
}]; | |
questionDetail.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction handler:^(id sender) { | |
}]; | |
questionDetail.navigationItem.rightBarButtonItem.enabled = NO; | |
[self.deckController presentViewController:questionDetailNav animated:YES completion:nil]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment