CocoaPods trunk is moving to be read-only. Read more on the blog, there are 14 months to go.
| TestsTested | ✓ |
| LangLanguage | Obj-CObjective C |
| License | MIT |
| ReleasedLast Release | Jul 2015 |
Maintained by Patryk Kaczmarek, Radosław Szeja.
| Depends on: | |
| UICKeyChainStore | ~> 1.1 |
| ngrvalidator | ~> 1.1.0 |
| XLForm | ~> 2.1 |
devise-ios is a simple client which automates connection with Devise. Specially created to work with devise-ios backend gem to make your job easier and faster!
devise-ios handles:
gem install cocoapods to grab it!)Use #import <Devise/Devise.h> whenever you want to use devise-ios.
[DVSConfiguration sharedConfiguration] is a singleton to keep configuration in one place. At the very beginning, somewhere in application:didFinishLaunchingWithOptions: in your AppDelegate use:
[[DVSConfiguration sharedConfiguration] setServerURL:<#NSURL#>];devise-ios is also able to inform you about encountered problems. Logging is especially useful during debug process. There are 3 designed log levels:
DVSLoggingModeNone - Don't log anything, ignore all messages.DVSLoggingModeWarning - Print all messages using NSLog.DVSLoggingModeAssert - Abort the code with the message.To specify logging mode use:
[[DVSConfiguration sharedConfiguration] setLoggingMode:<#DVSLoggingMode#>];devise-ios takes care about network problems and is able to automatically retry requests in case of connection issues. You can specify a number and time between retries using numberOfRetries and retryTresholdDuration properties of DVSConfiguration.
Devise uses AFNetworking under the hood. If needed network activity indicator can be enable through AFNetworkActivityIndicatorManager in AppDelegate application:didFinishLaunchingWithOptions:.
The main class of devise-ios is DVSUserManager. Provided implementation is enough for login, registration, edition and any other features offered by devise-ios.
Functions are pretty straightforward and self-explanatory.
User registration:
- (void)registerWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;Profile update:
- (void)updateWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;Signing in:
- (void)loginWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;Signing in with Facebook account:
- (void)signInUsingFacebookWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;Signing in with Google Plus account:
- (void)signInUsingGoogleWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;To handle callback from Google Plus authorization implement one of AppDelegate method as following:
- (BOOL)application: (UIApplication *)application openURL: (NSURL *)url sourceApplication: (NSString *)sourceApplication annotation: (id)annotation {
return [[DVSUserManager defaultManager] handleURL:url sourceApplication:sourceApplication annotation:annotation];
//or instance of other DVSUserManager used to sign in via g+.
}This guarantees that one of passed callbacks will be invoked as authorization result.
Password reminder:
- (void)remindPasswordWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;Password update:
- (void)changePasswordWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;Account deleting:
- (void)deleteAccountWithSuccess:(DVSVoidBlock)success failure:(DVSErrorBlock)failure;Although DVSUser implementation is enough for a basic usage, you can customize it as well.
If it's needed to persist locally more info about DVSUser subclass (other than email, sessionToken and identifier - these are stored by default) conform DVSUserPersisting protocol. You can choose which properties should be persist by invoking:
- (NSArray *)propertiesToPersistByName;Just remember to pass property names as NSString.
devise-ios under the hood uses NGRValidator to validate data. On top of it devise-ios delivers a possibility to add your own or modify default validation rules. If you wish to take benefit from it, conform DVSUserManagerDelegate protocol and implement - (void)userManager:(DVSUserManager *)manager didPrepareValidationRules:(NSMutableArray *)validationRules forAction:(DVSActionType)action; method.
Let's say a subclass of DVSUser has an additional property NSString *registrationUsername you want to validate during registration process to fulfill conditions:
and display appropriate messages when validation fails:
Moreover registrationUsername doesn't sound very well for a user, so it should be displayed as a "Username":
- (void)userManager:(DVSUserManager *)manager didPrepareValidationRules:(NSMutableArray *)validationRules forAction:(DVSActionType)action {
NGRPropertyValidator *validator = NGRValidate(@"registrationUsername").required().lengthRange(5, 20).msgTooShort(@"should have at least 4 signs.").msgTooLong(@"should have at most 20 signs").localizedName(@"Username");
[validationRules addObject:validator];
}When user will provide string foo for registrationUsername property, devise-ios will return an NSError with localized description:
NSLog(@"%@", error.localizedDescription);
// Username should have at least 4 characters.Simple as that! For more info please refer to NGRValidator.
All right. But you didn't create subclass of DVSUser only for local purposes, did you? To attach own parameters to request, please conform DVSUserJSONSerializerDataSource like below:
- (void)setupManager {
TestUser *user = [[TestUser alloc] init]; //TestUser is subclass of DVSUser with "foo" property
self.manager = [[DVSUserManager alloc] initWithUser:user]; //manager is an ivar here
self.manager.serializer.dataSource = self;
}
#pragma mark - DVSUserJSONSerializerDataSource
- (NSDictionary *)additionalRequestParametersForAction:(DVSActionType)action {
//use action to distinguish type of request
TestUser *user = (TestUser *)self.manager.user;
//make sure that foo is not nil. Eg. add own validation rule in userManager:didPrepareValidationRules:forAction: method
return @{@"foo" : user.foo};
}devise-ios will take care of the rest.
At some point in your app you might want to prepare a quick setup for your users and allow them to log in and sign up. devise-ios provides a handy view controller, called DVSAccountRetrieverViewController, which simplifies that process. Here is a simple example of usage:
DVSAccountRetrieverViewController *logInController = [[DVSAccountRetrieverViewController alloc] initWithType:DVSRetrieverTypeLogIn fields:DVSAccountRetrieverFieldEmailAndPassword | DVSAccountRetrieverFieldProceedButton];
logInController.delegate = self;
[self.navigationController pushViewController:logInController animated:YES];Simple, right? As you can see initializer takes two parameters:type and fields. First one is defining how your view controller will act and look. If you want to perform log in action, you should pass DVSRetrieverTypeLogIn. Using it with DVSAccountRetrieverViewController will automatically configure proceed button title and tap event to perform log in request. For sign up action you can use DVSRetrieverTypeSignUp type.
fields is options parameter that defines which parts of view should be visible. For example, if you want to use simple form with only text fields and proceed button, you should define fields like:
DVSAccountRetrieverFields logInFields = DVSAccountRetrieverFieldEmailAndPassword | DVSAccountRetrieverFieldProceedButton;And the result will be:
If you want to add a password reminder to form, just use following combination:
DVSAccountRetrieverFields logInFields = DVSAccountRetrieverFieldEmailAndPassword | DVSAccountRetrieverFieldProceedButton | DVSAccountRetrieverFieldPasswordReminder;Result:
In order to handle result of performed action, your class should override two DVSAccountRetrieverViewControllerDelegate protocol methods:
// for success
- (void)accountRetrieverViewController:(DVSAccountRetrieverViewController *)controller didSuccessForAction:(DVSRetrieverAction)action user:(DVSUser *)user;
// for failure
- (void)accountRetrieverViewController:(DVSAccountRetrieverViewController *)controller didFailWithError:(NSError *)error forAction:(DVSRetrieverAction)action;In both cases view controller will return action variable, that defines type of finished action and can have one of values: DVSRetrieverActionLogIn, DVSRetrieverActionSignUp, DVSRetrieverActionPasswordRemind. Success callback additionally will return corresponded user object saved in user.
DVSAccountRetrieverViewController doesn't implement autoclose feature. A developer is responsible for deciding when to close a view. To help with this task, devise-ios provides additional callback in DVSAccountRetrieverViewControllerDelegate that is executed when a user tapps a dismiss button:
- (void)accountRetrieverViewControllerDidTapDismiss:(DVSAccountRetrieverViewController *)controller;Implements full account lifecycle. Contains also an example with simple DVSUser subclassing and validation. To run demo please follow the instructions below:
$ git clone --recursive [email protected]:netguru/devise-ios.git
$ pod installor if you already cloned the project without --recursive:
$ git submodule update --init --recursive
$ pod installdevise-ios is available under the MIT license.
First, thank you for contributing!
Here's a few guidelines to follow:
Have a question? Please open an issue! You can also read our blog post announcing devise-iOS for simplified auth.
Copyright © 2014-2015 Netguru