Skip to content

Instantly share code, notes, and snippets.

@bobspryn
Created October 29, 2014 18:07
Show Gist options
  • Save bobspryn/757825aed9c1ffaf75b7 to your computer and use it in GitHub Desktop.
Save bobspryn/757825aed9c1ffaf75b7 to your computer and use it in GitHub Desktop.
//
// 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