Skip to content

Commit

Permalink
Update SDK.
Browse files Browse the repository at this point in the history
- Returns user ID. Updated delegate methods.
- Added method for sending invites.
  • Loading branch information
berg committed Apr 22, 2013
1 parent 33f9062 commit affc7b0
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 27 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ In your app delegate's .m file, instantiate the SDK:
Ensure that the login SDK has the opportunity to handle any open URL which comes back:
```objc
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [self.adn handleOpenURL:url];
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [self.adn openURL:url sourceApplication:sourceApplication annotation:annotation];
}
```

Expand All @@ -56,11 +56,11 @@ Implement the ADNLoginDelegate protocol methods:
```objc
#pragma mark - ADNLoginDelegate

- (void)adnLoginDidSucceedWithToken:(NSString *)accessToken {
- (void)adnLoginDidSucceedForUserWithID:(NSString *)userID token:(NSString *)accessToken {
// ... do some stuff
}

- (void)adnLoginDidFailWithMessage:(NSString *)errorMessage {
- (void)adnLoginDidFailWithError:(NSError *)error {
// ... and here too
}
```
Expand Down
78 changes: 74 additions & 4 deletions Source/ADNLogin.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,93 @@

@class ADNLogin;

typedef void (^ADNLoginSignupAvailableCompletionBlock)(BOOL available);

static NSString *const kADNLoginErrorDomain = @"ADNLoginErrorDomain";

/**
The `ADNLoginDelegate` protocol defines the methods the ADNLogin SDK will use to communicate state with your app. Typically this will be implemented by your app delegate.
*/
@protocol ADNLoginDelegate <NSObject>

- (void)adnLoginDidSucceedWithToken:(NSString *)accessToken;
- (void)adnLoginDidFailWithMessage:(NSString *)errorMessage;
/**
Called when fast-switching back from the App.net app with valid login credentials.
@param userID The user ID of the logged-in user.
@param accessToken An access token authorized with the requested permissions.
*/
- (void)adnLoginDidSucceedForUserWithID:(NSString *)userID token:(NSString *)accessToken;

/**
Called when login has failed.
@param error An error describing the reason for failure.
*/
- (void)adnLoginDidFailWithError:(NSError *)error;

@end

typedef void (^ADNLoginSignupAvailableCompletionBlock)(BOOL available);

/**
The primary object in the ADNLogin SDK. Generally, you will create an instance of this and store it on your app delegate.
*/
@interface ADNLogin : NSObject

/**
The SDK delegate.
*/
@property (weak, nonatomic) NSObject<ADNLoginDelegate> *delegate;

/**
Whether or not ADNLogin-assisted authentication is available. This can be used to detect whether the App.net app is installed. If this is `NO`, your app should fall back to another login method, like the password flow.
*/
@property (readonly, nonatomic, getter=isLoginAvailable) BOOL loginAvailable;


/**
Request login.
@param scopes A list of the requested authentication scopes.
@return `YES` if the App.net was launched to request login, `NO` if it was not installed or unable to open
*/
- (BOOL)loginWithScopes:(NSArray *)scopes;
- (BOOL)handleOpenURL:(NSURL *)url;

/**
Call this method from your app delegate's `application:openURL:sourceApplication:annotation:` method.
@param url The URL of the request
@param sourceApplication The bundle ID of the opening application
@param annotation The supplied annotation
@return `YES` if the ADNLogin SDK handled the request, `NO` if it did not
*/
- (BOOL)openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;

/**
Determine whether signup (without an invite) is currently available. Signup with invite link is always available in the app.
@param completionBlock Block to be called with the result of the signup availability check.
@discussion Makes a network call on a background thread.
*/
- (void)pollForSignupAvailableWithCompletionBlock:(ADNLoginSignupAvailableCompletionBlock)completionBlock;

/**
Request that the App.net app be installed. Right now, this is designed to open the App Store app via a URL scheme, but may be extended to use StoreKit in the future.
@return `YES` if the App Store app was launched, `NO` if it was unable to open
*/
- (BOOL)installLoginApp;

/**
Request that the App.net app send an invite to a user. The user will have the opportunity to edit the message before sending.
@param message A message to the recipient (or nil for a default message)
@param email The email address of the user (or nil)
@return `YES` if the App.net app was able to be launched, `NO` if it was not.
*/
- (BOOL)sendInviteWithMessage:(NSString *)message toEmail:(NSString *)email;

@end
60 changes: 41 additions & 19 deletions Source/ADNLogin.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,23 @@ @implementation ADNLogin
static NSString *queryStringForParameters(NSDictionary *parameters) {
NSMutableArray *a = [NSMutableArray arrayWithCapacity:[parameters count]];
[parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[a addObject:[NSString stringWithFormat:@"%@=%@",
queryStringEscape(key, NSUTF8StringEncoding),
queryStringEscape(obj, NSUTF8StringEncoding)]];
if (obj == [NSNull null]) {
return;
}

if ([obj isKindOfClass:[NSValue class]]) {
obj = [obj stringValue];
}

if (![obj isKindOfClass:[NSString class]]) {
return;
}

if ([obj length]) {
[a addObject:[NSString stringWithFormat:@"%@=%@",
queryStringEscape(key, NSUTF8StringEncoding),
queryStringEscape(obj, NSUTF8StringEncoding)]];
}
}];

return [a componentsJoinedByString:@"&"];
Expand Down Expand Up @@ -186,34 +200,35 @@ - (void)pollForSignupAvailableWithCompletionBlock:(ADNLoginSignupAvailableComple

- (BOOL)loginWithScopes:(NSArray *)scopes {
NSString *scopeString = [scopes componentsJoinedByString:@" "] ?: @"";
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:self.clientID, @"client_id",
scopeString, @"scope",
[NSString stringWithFormat:@"%u", self.appPK], @"app_pk",
self.schemeSuffix, @"suffix", nil];

NSDictionary *parameters = @{@"client_id": self.clientID, @"app_pk": @(self.appPK), @"suffix": self.schemeSuffix ?: [NSNull null], @"scope": scopeString};
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://token?%@", self.loginScheme, queryStringForParameters(parameters)]];

if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];

return YES;
}

return NO;
return [[UIApplication sharedApplication] openURL:url];
}

- (BOOL)handleOpenURL:(NSURL *)url {
- (BOOL)openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if ([url.scheme isEqualToString:self.primaryScheme]) {
if (sourceApplication != nil && !([sourceApplication isEqualToString:@"net.app.moana"] || [sourceApplication hasPrefix:@"net.app.moana."])) {
return NO;
}

NSDictionary *parameters = parametersForQueryString(url.fragment);
NSString *accessToken = parameters[@"access_token"];
NSString *userID = parameters[@"user_id"];
if (accessToken) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate adnLoginDidSucceedWithToken:accessToken];
if ([self.delegate respondsToSelector:@selector(adnLoginDidSucceedForUserWithID:token:)]) {
[self.delegate adnLoginDidSucceedForUserWithID:userID token:accessToken];
}
});
} else {
NSString *error = parameters[@"error"] ?: @"Error logging in.";
NSString *errorMessage = parameters[@"error"] ?: @"Error logging in.";
NSError *error = [NSError errorWithDomain:kADNLoginErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey: errorMessage}];

dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate adnLoginDidFailWithMessage:error];
if ([self.delegate respondsToSelector:@selector(adnLoginDidFailWithError:)]) {
[self.delegate adnLoginDidFailWithError:error];
}
});
}

Expand All @@ -229,4 +244,11 @@ - (BOOL)installLoginApp {
return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:kADNLoginAppInstallURL]];
}

- (BOOL)sendInviteWithMessage:(NSString *)message toEmail:(NSString *)email {
NSDictionary *parameters = @{@"client_id": self.clientID, @"app_pk": @(self.appPK), @"suffix": self.schemeSuffix ?: [NSNull null], @"message": message ?: [NSNull null], @"email": email ?: [NSNull null]};
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@://invite/send?%@", self.loginScheme, queryStringForParameters(parameters)]];

return [[UIApplication sharedApplication] openURL:url];
}

@end

0 comments on commit affc7b0

Please sign in to comment.