diff --git a/FMC Planner 2.xcodeproj/project.pbxproj b/FMC Planner 2.xcodeproj/project.pbxproj index b080f5f..a2283da 100644 --- a/FMC Planner 2.xcodeproj/project.pbxproj +++ b/FMC Planner 2.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ E28E10731CA0375F006E2C6B /* ROUTE.plist in Resources */ = {isa = PBXBuildFile; fileRef = E28E10721CA0375F006E2C6B /* ROUTE.plist */; }; E29391CE1CA444F4008EB590 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E29391CD1CA444F4008EB590 /* LaunchScreen.storyboard */; }; E2A927161CA30CEE00606E07 /* SharedDeclerations.m in Sources */ = {isa = PBXBuildFile; fileRef = E2A927151CA30CEE00606E07 /* SharedDeclerations.m */; }; + E2B694BC1CAC0C56007B28EF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2B694BB1CAC0C56007B28EF /* Security.framework */; }; E2CC73E31CA2B7C7005B786E /* PERF INIT.plist in Resources */ = {isa = PBXBuildFile; fileRef = E2CC73E21CA2B7C7005B786E /* PERF INIT.plist */; }; /* End PBXBuildFile section */ @@ -78,6 +79,7 @@ E29391CD1CA444F4008EB590 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; E2A927141CA30CEE00606E07 /* SharedDeclerations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedDeclerations.h; sourceTree = ""; }; E2A927151CA30CEE00606E07 /* SharedDeclerations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SharedDeclerations.m; sourceTree = ""; }; + E2B694BB1CAC0C56007B28EF /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; E2CC73E21CA2B7C7005B786E /* PERF INIT.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "PERF INIT.plist"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -86,6 +88,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E2B694BC1CAC0C56007B28EF /* Security.framework in Frameworks */, E28E106D1C9FF93D006E2C6B /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -110,6 +113,7 @@ E22EE9C31C9DB7B3001F5BC0 = { isa = PBXGroup; children = ( + E2B694BB1CAC0C56007B28EF /* Security.framework */, E28E106C1C9FF93D006E2C6B /* QuartzCore.framework */, E22EE9CE1C9DB7B3001F5BC0 /* FMC Planner 2 */, E22EE9E81C9DB7B4001F5BC0 /* FMC Planner 2Tests */, @@ -173,8 +177,6 @@ children = ( E2A9270C1CA2FD6D00606E07 /* Implementation */, E2A9270B1CA2FD6000606E07 /* Header */, - E2549C741CAB2D3F00562602 /* DropboxV2ObjC.h */, - E2549C751CAB2D3F00562602 /* DropboxV2ObjC.m */, ); name = ViewControllers; sourceTree = ""; @@ -226,8 +228,9 @@ E2A9270E1CA2FE5200606E07 /* Header */ = { isa = PBXGroup; children = ( - E2A927141CA30CEE00606E07 /* SharedDeclerations.h */, E22EE9D21C9DB7B3001F5BC0 /* AppDelegate.h */, + E2549C741CAB2D3F00562602 /* DropboxV2ObjC.h */, + E2A927141CA30CEE00606E07 /* SharedDeclerations.h */, ); name = Header; sourceTree = ""; @@ -235,9 +238,10 @@ E2A9270F1CA2FE5900606E07 /* Implementation */ = { isa = PBXGroup; children = ( - E2A927151CA30CEE00606E07 /* SharedDeclerations.m */, E22EE9D31C9DB7B3001F5BC0 /* AppDelegate.m */, + E2549C751CAB2D3F00562602 /* DropboxV2ObjC.m */, E22EE9D01C9DB7B3001F5BC0 /* main.m */, + E2A927151CA30CEE00606E07 /* SharedDeclerations.m */, ); name = Implementation; sourceTree = ""; diff --git a/FMC Planner 2.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/FMC Planner 2.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 238ec92..fe2b454 100644 --- a/FMC Planner 2.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/FMC Planner 2.xcodeproj/xcuserdata/Kili2.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -2,22 +2,4 @@ - - - - - - diff --git a/FMC Planner 2/AppDelegate.h b/FMC Planner 2/AppDelegate.h index bc028d4..ab984c0 100644 --- a/FMC Planner 2/AppDelegate.h +++ b/FMC Planner 2/AppDelegate.h @@ -7,11 +7,13 @@ // #import "DropboxV2ObjC.h" +#import "ViewControllerServiceMenu.h" #import @interface AppDelegate : UIResponder @property(strong, nonatomic) UIWindow *window; @property(strong, nonatomic) DropboxV2ObjC *dbClient; +@property(strong, nonatomic) UIViewController *smWebView; @end diff --git a/FMC Planner 2/AppDelegate.m b/FMC Planner 2/AppDelegate.m index 43b672e..a45e248 100644 --- a/FMC Planner 2/AppDelegate.m +++ b/FMC Planner 2/AppDelegate.m @@ -14,6 +14,11 @@ didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. _dbClient = [[DropboxV2ObjC alloc] init]; + NSDictionary *credentials = + [[NSURLCredentialStorage sharedCredentialStorage] + credentialsForProtectionSpace:_dbClient.kDropboxProtectionSpace]; + NSURLCredential *credential = [credentials.objectEnumerator nextObject]; + _dbClient.token = credential.password; return YES; } @@ -53,7 +58,11 @@ - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { // Display text - [_dbClient authorizeUserWithToke:url]; + [_dbClient authorizeUserWithToke:url + completion:^(void) { + [_smWebView.navigationController + popViewControllerAnimated:YES]; + }]; return YES; } diff --git a/FMC Planner 2/Base.lproj/Main.storyboard b/FMC Planner 2/Base.lproj/Main.storyboard index b5555ec..a7bfb72 100644 --- a/FMC Planner 2/Base.lproj/Main.storyboard +++ b/FMC Planner 2/Base.lproj/Main.storyboard @@ -82,17 +82,6 @@ - + + + - - + + + + @@ -144,6 +154,9 @@ + + + diff --git a/FMC Planner 2/DropboxV2ObjC.h b/FMC Planner 2/DropboxV2ObjC.h index a2de35c..71788d1 100644 --- a/FMC Planner 2/DropboxV2ObjC.h +++ b/FMC Planner 2/DropboxV2ObjC.h @@ -6,16 +6,22 @@ // Copyright © 2016 Kilian Hofmann. All rights reserved. // +#import "SharedDeclerations.h" #import +#import @interface DropboxV2ObjC : NSObject @property(strong, nonatomic) NSString *token; @property(strong, nonatomic) NSString *rootDirectory; +@property(strong, nonatomic) NSData *kJSONNullObject; +@property(strong, nonatomic) NSURLProtectionSpace *kDropboxProtectionSpace; -- (BOOL)authorizeUserWithToke:(NSURL *)token; +- (BOOL)authorizeUserWithToke:(NSURL *)token completion:(void (^)(void))handler; - (NSData *)downloadFromDropbox; - (void)uploadToDropbox:(NSData *)data; - (NSArray *)contentsOfPath:(NSString *)path; +- (NSDictionary *)getUserInfo; +- (BOOL)deauthorizeUser; @end diff --git a/FMC Planner 2/DropboxV2ObjC.m b/FMC Planner 2/DropboxV2ObjC.m index bd5be4d..2dd937a 100644 --- a/FMC Planner 2/DropboxV2ObjC.m +++ b/FMC Planner 2/DropboxV2ObjC.m @@ -13,23 +13,100 @@ - (DropboxV2ObjC *)init { self = [super init]; self.rootDirectory = @"/Apps/FMC Planner 2/"; + self.kJSONNullObject = [@"null" dataUsingEncoding:NSASCIIStringEncoding]; + self.kDropboxProtectionSpace = + [[NSURLProtectionSpace alloc] initWithHost:@"dropbox" + port:443 + protocol:@"HTTP" + realm:nil + authenticationMethod:@"OAuth2"]; return self; } -- (BOOL)authorizeUserWithToke:(NSURL *)token { - NSScanner *scan = [NSScanner scannerWithString:[token absoluteString]]; +#pragma mark - OAuth stuff + +- (BOOL)authorizeUserWithToke:(NSURL *)token + completion:(void (^)(void))handler { + NSScanner *scan = [NSScanner scannerWithString:token.absoluteString]; NSString *error = [[NSString alloc] init]; [scan scanUpToString:@"&error=" intoString:&error]; - if (![error isEqualToString:[token absoluteString]]) { + if (![error isEqualToString:token.absoluteString]) { + handler(); return false; } // No error, refine token NSString *tokenUnrefined = [[NSString alloc] init]; + scan = [NSScanner scannerWithString:token.absoluteString]; [scan scanUpToString:@"&" intoString:&tokenUnrefined]; NSString *tokenRefined = [tokenUnrefined substringFromIndex:21]; _token = tokenRefined; + NSURLCredential *credential = [NSURLCredential + credentialWithUser:@"Dropbox" + password:_token + persistence:NSURLCredentialPersistencePermanent]; + [[NSURLCredentialStorage sharedCredentialStorage] + setCredential:credential + forProtectionSpace:_kDropboxProtectionSpace]; + handler(); return true; } +- (BOOL)deauthorizeUser { + NSDictionary *credentials = + [[NSURLCredentialStorage sharedCredentialStorage] + credentialsForProtectionSpace:_kDropboxProtectionSpace]; + NSURLCredential *credential = [credentials.objectEnumerator nextObject]; + [[NSURLCredentialStorage sharedCredentialStorage] + removeCredential:credential + forProtectionSpace:_kDropboxProtectionSpace]; + return true; +} + +#pragma mark - File and directory operations + +#pragma mark - Other operations + +- (NSDictionary *)getUserInfo { + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; + request.URL = + [NSURL URLWithString: + @"https://api.dropboxapi.com/2/users/get_current_account"]; + [request addValue:[NSString stringWithFormat:@"Bearer %@", _token] + .precomposedStringWithCanonicalMapping + forHTTPHeaderField:(@"Authorization") + .precomposedStringWithCanonicalMapping]; + [request addValue:(@"application/json") + .precomposedStringWithCanonicalMapping + forHTTPHeaderField:(@"Content-Type") + .precomposedStringWithCanonicalMapping]; + request.HTTPMethod = @"POST"; + request.HTTPBody = _kJSONNullObject; + + NSURLResponse *response = nil; + NSError *error = nil; + id data = [self parseJSON:[NSURLConnection sendSynchronousRequest:request + returningResponse:&response + error:&error]]; + if ([data isKindOfClass:[NSDictionary class]]) { + return data; + } else { + return nil; + } +} + +#pragma mark - Helper methods + +- (id)parseJSON:(NSData *)data { + NSError *error = nil; + id object = + [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + if (error == nil) { + return object; + } else { + return + [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; + } +} + @end diff --git a/FMC Planner 2/SharedDeclerations.m b/FMC Planner 2/SharedDeclerations.m index c03239e..54c2bef 100644 --- a/FMC Planner 2/SharedDeclerations.m +++ b/FMC Planner 2/SharedDeclerations.m @@ -52,7 +52,7 @@ + (NSString *)savePathForFile:(NSString *)file { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *documentsPath = [paths objectAtIndex:0]; + NSString *documentsPath = paths[0]; return [documentsPath stringByAppendingString:[NSString stringWithFormat:@"/%@", file]]; } diff --git a/FMC Planner 2/ViewControllerScreen.m b/FMC Planner 2/ViewControllerScreen.m index 741b7cf..0b90333 100644 --- a/FMC Planner 2/ViewControllerScreen.m +++ b/FMC Planner 2/ViewControllerScreen.m @@ -109,7 +109,7 @@ .restorationIdentifier isEqualToString:@"LSKR6"]) { UINavigationController *sm = [self.storyboard instantiateViewControllerWithIdentifier:@"ServiceMenu"]; - ((ViewControllerServiceMenu *)[sm.childViewControllers firstObject]) + ((ViewControllerServiceMenu *)(sm.childViewControllers).firstObject) .main = _main; [self presentViewController:sm animated:YES completion:nil]; } else { @@ -135,11 +135,9 @@ (unsigned long) _maxNumRoutePages]]; } - [_main.save - setObject:((UILabel *)tapReg.view).text - forKey:[NSString stringWithFormat:@"%@@%@", _Header.text, + (_main.save)[[NSString stringWithFormat:@"%@@%@", _Header.text, ((UILabel *)tapReg.view) - .restorationIdentifier]]; + .restorationIdentifier]] = ((UILabel *)tapReg.view).text; _Scratchpad.text = @""; [_main saveToFile:_main.save]; } @@ -153,7 +151,7 @@ ofType:@"plist"]]; for (UILabel *label in _Desc) { for (int j = 0; j < screen.count; j++) { - if ([label.restorationIdentifier intValue] == j) { + if ((label.restorationIdentifier).intValue == j) { label.text = screen[j]; } if (![screen[j] isEqualToString:@""] || diff --git a/FMC Planner 2/ViewControllerServiceMenu.h b/FMC Planner 2/ViewControllerServiceMenu.h index 02f429b..042aeaf 100644 --- a/FMC Planner 2/ViewControllerServiceMenu.h +++ b/FMC Planner 2/ViewControllerServiceMenu.h @@ -16,7 +16,12 @@ @interface ViewControllerServiceMenu : UIViewController @property(strong, nonatomic) ViewController *main; +@property(strong, nonatomic) IBOutlet UIButton *dbConnectButton; - (IBAction)dbConnect:(UIButton *)sender; +- (IBAction)dbDisconnect:(UIButton *)sender; + +#warning TESTING GROUNDS +- (IBAction)testing:(id)sender; @end diff --git a/FMC Planner 2/ViewControllerServiceMenu.m b/FMC Planner 2/ViewControllerServiceMenu.m index 07cee72..7726c1c 100644 --- a/FMC Planner 2/ViewControllerServiceMenu.m +++ b/FMC Planner 2/ViewControllerServiceMenu.m @@ -19,24 +19,43 @@ action:@selector(back)]; } +- (void)viewWillAppear:(BOOL)animated { + DropboxV2ObjC *dbClient = + ((AppDelegate *)[UIApplication sharedApplication].delegate).dbClient; + if (dbClient.token != nil) { + [_dbConnectButton setTitle:@"Disconnect from Dropbox" + forState:UIControlStateNormal]; + [_dbConnectButton removeTarget:self + action:@selector(dbConnect:) + forControlEvents:UIControlEventTouchUpInside]; + [_dbConnectButton addTarget:self + action:@selector(dbDisconnect:) + forControlEvents:UIControlEventTouchUpInside]; + } +} + - (void)back { [self dismissViewControllerAnimated:YES completion:nil]; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { - ((TableViewController *)[segue destinationViewController]).title = + ((TableViewController *)segue.destinationViewController).title = segue.identifier; - ((TableViewController *)[segue destinationViewController]).main = _main; + ((TableViewController *)segue.destinationViewController).main = _main; } +#pragma mark - Dropbox Button + - (IBAction)dbConnect:(UIButton *)sender { - DropboxV2ObjC *db_client = - ((AppDelegate *)[[UIApplication sharedApplication] delegate]).dbClient; + DropboxV2ObjC *dbClient = + ((AppDelegate *)[UIApplication sharedApplication].delegate).dbClient; UIViewController *webController = [[UIViewController alloc] init]; webController.title = @"Dropbox"; UIWebView *web = [[UIWebView alloc] initWithFrame:webController.view.frame]; [webController.view addSubview:web]; [self.navigationController pushViewController:webController animated:YES]; + ((AppDelegate *)[UIApplication sharedApplication].delegate).smWebView = + webController; [web loadRequest: [NSURLRequest requestWithURL: @@ -46,4 +65,25 @@ @"uri=x-fmc:/"]]]; } +- (IBAction)dbDisconnect:(UIButton *)sender { + DropboxV2ObjC *dbClient = + ((AppDelegate *)[UIApplication sharedApplication].delegate).dbClient; + [dbClient deauthorizeUser]; + [_dbConnectButton setTitle:@"Connect to Dropbox" + forState:UIControlStateNormal]; + [_dbConnectButton removeTarget:self + action:@selector(dbDisconnect:) + forControlEvents:UIControlEventTouchUpInside]; + [_dbConnectButton addTarget:self + action:@selector(dbConnect:) + forControlEvents:UIControlEventTouchUpInside]; +} + +#warning TESTING GROUNDS +- (IBAction)testing:(id)sender { + DropboxV2ObjC *dbClient = + ((AppDelegate *)[UIApplication sharedApplication].delegate).dbClient; + [dbClient getUserInfo]; +} + @end