Skip to content

Commit

Permalink
Add multi-login
Browse files Browse the repository at this point in the history
  • Loading branch information
drewconner committed Mar 24, 2014
1 parent 7e066e0 commit 4f05e7c
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 94 deletions.
9 changes: 3 additions & 6 deletions ChimpKit3/Helper Objects/CKAuthViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#import <UIKit/UIKit.h>


#define kCKAuthDebug 0
#define kCKAuthDebug 1

#define kAuthorizeUrl @"https://login.mailchimp.com/oauth2/authorize"
#define kAccessTokenUrl @"https://login.mailchimp.com/oauth2/token"
Expand All @@ -31,6 +31,8 @@

@property (unsafe_unretained, readwrite) id<CKAuthViewControllerDelegate> delegate;

@property (nonatomic, assign) BOOL enableMultipleLogin;

@property (nonatomic, assign) BOOL disableCancelling;
@property (nonatomic, assign) BOOL disableAPIKeyScanning;
@property (nonatomic, assign) BOOL disableAccountDataFetching;
Expand All @@ -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;

Expand Down
175 changes: 89 additions & 86 deletions ChimpKit3/Helper Objects/CKAuthViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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;
Expand All @@ -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)) {
Expand Down Expand Up @@ -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"];

Expand All @@ -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 {
Expand Down Expand Up @@ -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 - <UIWebViewDelegate> Methods

Expand Down Expand Up @@ -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
15 changes: 13 additions & 2 deletions Sample App/ChimpKitSampleApp/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,13 @@ - (IBAction)subscribeButtonTapped:(id)sender {
}

- (IBAction)loginButtonTapped:(id)sender {
CKAuthViewController *authViewController = [[CKAuthViewController alloc] initWithClientId:@"<YOUR CLIENT ID>"
andClientSecret:@"<YOUR CLIENT SECRET>"];
// CKAuthViewController *authViewController = [[CKAuthViewController alloc] initWithClientId:@"<YOUR CLIENT ID>"
// andClientSecret:@"<YOUR CLIENT SECRET>"];

CKAuthViewController *authViewController = [[CKAuthViewController alloc] initWithClientId:@"***REMOVED***"
andClientSecret:@"***REMOVED***"];

authViewController.enableMultipleLogin = YES;

authViewController.delegate = self;

Expand Down Expand Up @@ -80,14 +85,20 @@ - (IBAction)scanBarcodeButtonTapped:(id)sender {
#pragma mark - <CKAuthViewControllerDelegate> 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];
}

Expand Down

0 comments on commit 4f05e7c

Please sign in to comment.