From 4f05e7c4c7503ebe7c91eebd9474ac6b18814de1 Mon Sep 17 00:00:00 2001 From: Drew Conner Date: Mon, 24 Mar 2014 08:14:47 -0400 Subject: [PATCH] Add multi-login --- .../Helper Objects/CKAuthViewController.h | 9 +- .../Helper Objects/CKAuthViewController.m | 175 +++++++++--------- Sample App/ChimpKitSampleApp/ViewController.m | 15 +- 3 files changed, 105 insertions(+), 94 deletions(-) diff --git a/ChimpKit3/Helper Objects/CKAuthViewController.h b/ChimpKit3/Helper Objects/CKAuthViewController.h index 04b5963..c5b7910 100644 --- a/ChimpKit3/Helper Objects/CKAuthViewController.h +++ b/ChimpKit3/Helper Objects/CKAuthViewController.h @@ -9,7 +9,7 @@ #import -#define kCKAuthDebug 0 +#define kCKAuthDebug 1 #define kAuthorizeUrl @"https://login.mailchimp.com/oauth2/authorize" #define kAccessTokenUrl @"https://login.mailchimp.com/oauth2/token" @@ -31,6 +31,8 @@ @property (unsafe_unretained, readwrite) id delegate; +@property (nonatomic, assign) BOOL enableMultipleLogin; + @property (nonatomic, assign) BOOL disableCancelling; @property (nonatomic, assign) BOOL disableAPIKeyScanning; @property (nonatomic, assign) BOOL disableAccountDataFetching; @@ -39,11 +41,6 @@ @property (strong, nonatomic) NSString *clientSecret; @property (strong, nonatomic) NSString *redirectUrl; -@property (strong, nonatomic) NSString *accessToken; - -@property (strong, nonatomic) NSURLConnection *connection; -@property (strong, nonatomic) NSMutableData *connectionData; - @property (strong, nonatomic) IBOutlet UIActivityIndicatorView *spinner; @property (strong, nonatomic) IBOutlet UIWebView *webview; diff --git a/ChimpKit3/Helper Objects/CKAuthViewController.m b/ChimpKit3/Helper Objects/CKAuthViewController.m index 533f096..47d5f34 100644 --- a/ChimpKit3/Helper Objects/CKAuthViewController.m +++ b/ChimpKit3/Helper Objects/CKAuthViewController.m @@ -13,9 +13,10 @@ @interface CKAuthViewController() -- (void)authWithClientId:(NSString *)yd andSecret:(NSString *)secret; -- (void)getAccessTokenMetaDataForAccessToken:(NSString *)anAccessToken; -- (void)cleanup; +@property (nonatomic, strong) NSURLSession *urlSession; + +- (void)authWithClientId:(NSString *)clientId andSecret:(NSString *)secret; +- (void)getAccessTokenMetaDataForAccessToken:(NSString *)accessToken; @end @@ -29,6 +30,8 @@ - (id)initWithClientId:(NSString *)cId clientSecret:(NSString *)cSecret andRedir self.clientId = cId; self.clientSecret = cSecret; self.redirectUrl = redirectUrl; + + self.urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; } return self; @@ -45,7 +48,6 @@ - (void)viewDidLoad { [super viewDidLoad]; self.title = @"Connect to MailChimp"; - self.connectionData = [NSMutableData data]; //If presented modally in a new VC, add the cancel button if (([self.navigationController.viewControllers objectAtIndex:0] == self) && (self.disableCancelling == NO)) { @@ -113,23 +115,30 @@ - (void)scanButtonTapped:(id)sender { #pragma mark - Private Methods -- (void)authWithClientId:(NSString *)yd andSecret:(NSString *)secret { - self.clientId = yd; +- (void)authWithClientId:(NSString *)cliendId andSecret:(NSString *)secret { + self.clientId = cliendId; self.clientSecret = secret; + + NSString *extraParam = @""; + if (self.enableMultipleLogin) { + extraParam = @"&multiple=true"; + } //Kick off the auth process - NSString *url = [NSString stringWithFormat:@"%@?response_type=code&client_id=%@&redirect_uri=%@", + NSString *url = [NSString stringWithFormat:@"%@?response_type=code&client_id=%@&redirect_uri=%@%@", kAuthorizeUrl, self.clientId, - self.redirectUrl]; + self.redirectUrl, + extraParam]; + NSURLRequest *request = [[NSURLRequest alloc] initWithURL: [NSURL URLWithString:url]]; [self.webview loadRequest:request]; } - (void)getAccessTokenForAuthCode:(NSString *)authCode { - [self cleanup]; - + [self.spinner setHidden:NO]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kAccessTokenUrl]]; [request setHTTPMethod:@"POST"]; @@ -141,22 +150,68 @@ - (void)getAccessTokenForAuthCode:(NSString *)authCode { [request setHTTPBody:[postBody dataUsingEncoding:NSUTF8StringEncoding]]; - self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; + [[self.urlSession dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + [self connectionFailedWithError:error]; + return; + } + + id jsonValue = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers | NSJSONReadingAllowFragments + error:nil]; + + if (self.enableMultipleLogin) { + for (NSDictionary *accessDictionary in jsonValue) { + NSString *accessToken = [accessDictionary objectForKey:@"access_token"]; + + //Get the access token metadata so we can return a proper API key + [self getAccessTokenMetaDataForAccessToken:accessToken]; + } + } else { + NSString *accessToken = [jsonValue objectForKey:@"access_token"]; + + //Get the access token metadata so we can return a proper API key + [self getAccessTokenMetaDataForAccessToken:accessToken]; + } + }] resume]; } -- (void)getAccessTokenMetaDataForAccessToken:(NSString *)anAccessToken { - [self cleanup]; - +- (void)getAccessTokenMetaDataForAccessToken:(NSString *)accessToken { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:kMetaDataUrl]]; [request setHTTPMethod:@"GET"]; - [request setValue:[NSString stringWithFormat:@"Bearer %@", anAccessToken] forHTTPHeaderField:@"Authorization"]; - - self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; -} - -- (void)cleanup { - self.connection = nil; - [self.connectionData setLength:0]; + [request setValue:[NSString stringWithFormat:@"Bearer %@", accessToken] forHTTPHeaderField:@"Authorization"]; + + [[self.urlSession dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error) { + [self connectionFailedWithError:error]; + return; + } + + id jsonValue = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers | NSJSONReadingAllowFragments + error:nil]; + + [self.spinner setHidden:YES]; + + //And we're done. We can now concat the access token and the data center + //to form the MailChimp API key and notify our delegate + NSString *dataCenter = [jsonValue objectForKey:@"dc"]; + NSString *apiKey = [NSString stringWithFormat:@"%@-%@", accessToken, dataCenter]; + + if (self.disableAccountDataFetching) { + if (self.delegate && [self.delegate respondsToSelector:@selector(ckAuthSucceededWithApiKey:andAccountData:)]) { + [self.delegate ckAuthSucceededWithApiKey:apiKey andAccountData:nil]; + } + + if (self.authSucceeded) { + self.authSucceeded(apiKey, nil); + } + } else { + [self fetchAccountDataForAPIKey:apiKey]; + } + }] resume]; } - (void)fetchAccountDataForAPIKey:(NSString *)apiKey { @@ -202,6 +257,18 @@ - (void)fetchAccountDataForAPIKey:(NSString *)apiKey { }]; } +- (void)connectionFailedWithError:(NSError *)error { + [self.spinner setHidden:YES]; + + if (self.delegate && [self.delegate respondsToSelector:@selector(ckAuthFailedWithError:)]) { + [self.delegate ckAuthFailedWithError:error]; + } + + if (self.authFailed) { + self.authFailed(error); + } +} + #pragma mark - Methods @@ -243,68 +310,4 @@ - (void)webView:(UIWebView *)aWebView didFailLoadWithError:(NSError *)error { } -#pragma mark - NSURLConnection delegate methods - -- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { - [self.spinner setHidden:NO]; - - [self.connectionData setLength:0]; -} - -- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { - [self.connectionData appendData:data]; -} - -- (void)connectionDidFinishLoading:(NSURLConnection *)connection { - NSString *response = [[NSString alloc] initWithData:self.connectionData encoding:NSUTF8StringEncoding]; - if (kCKAuthDebug) NSLog(@"Auth Response: %@", response); - - NSDictionary *jsonValue = [NSJSONSerialization JSONObjectWithData:self.connectionData - options:NSJSONReadingMutableContainers | NSJSONReadingAllowFragments - error:nil]; - - if (!self.accessToken) { - self.accessToken = [jsonValue objectForKey:@"access_token"]; - - //Get the access token metadata so we can return a proper API key - [self getAccessTokenMetaDataForAccessToken:self.accessToken]; - } else { - [self.spinner setHidden:YES]; - - //And we're done. We can now concat the access token and the data center - //to form the MailChimp API key and notify our delegate - NSString *dataCenter = [jsonValue objectForKey:@"dc"]; - NSString *apiKey = [NSString stringWithFormat:@"%@-%@", self.accessToken, dataCenter]; - - if (self.disableAccountDataFetching) { - if (self.delegate && [self.delegate respondsToSelector:@selector(ckAuthSucceededWithApiKey:andAccountData:)]) { - [self.delegate ckAuthSucceededWithApiKey:apiKey andAccountData:nil]; - } - - if (self.authSucceeded) { - self.authSucceeded(apiKey, nil); - } - } else { - [self fetchAccountDataForAPIKey:apiKey]; - } - - [self cleanup]; - } -} - -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { - [self.spinner setHidden:YES]; - - if (self.delegate && [self.delegate respondsToSelector:@selector(ckAuthFailedWithError:)]) { - [self.delegate ckAuthFailedWithError:error]; - } - - if (self.authFailed) { - self.authFailed(error); - } - - [self cleanup]; -} - - @end diff --git a/Sample App/ChimpKitSampleApp/ViewController.m b/Sample App/ChimpKitSampleApp/ViewController.m index 9c53d0b..896d3e0 100644 --- a/Sample App/ChimpKitSampleApp/ViewController.m +++ b/Sample App/ChimpKitSampleApp/ViewController.m @@ -42,8 +42,13 @@ - (IBAction)subscribeButtonTapped:(id)sender { } - (IBAction)loginButtonTapped:(id)sender { - CKAuthViewController *authViewController = [[CKAuthViewController alloc] initWithClientId:@"" - andClientSecret:@""]; +// CKAuthViewController *authViewController = [[CKAuthViewController alloc] initWithClientId:@"" +// andClientSecret:@""]; + + CKAuthViewController *authViewController = [[CKAuthViewController alloc] initWithClientId:@"***REMOVED***" + andClientSecret:@"***REMOVED***"]; + + authViewController.enableMultipleLogin = YES; authViewController.delegate = self; @@ -80,14 +85,20 @@ - (IBAction)scanBarcodeButtonTapped:(id)sender { #pragma mark - Methods - (void)ckAuthUserCanceled { + NSLog(@"Auth Cancelled"); + [self dismissViewControllerAnimated:YES completion:nil]; } - (void)ckAuthSucceededWithApiKey:(NSString *)apiKey andAccountData:(NSDictionary *)accountData { + NSLog(@"%@", accountData); + [self dismissViewControllerAnimated:YES completion:nil]; } - (void)ckAuthFailedWithError:(NSError *)error { + NSLog(@"Auth Failed: %@", [error description]); + [self dismissViewControllerAnimated:YES completion:nil]; }