Latest 1.1.0
Homepage https://github.com/netguru/devise-ios
License MIT
Platforms ios 7.0, requires ARC
Dependencies UICKeyChainStore, ngrvalidator, XLForm
Frameworks AddressBook, AssetsLibrary, Foundation, CoreLocation, CoreMotion, CoreGraphics, CoreText, MediaPlayer, Security, SystemConfiguration, UIKit
Authors , , , ,

devise-ios

Circle CI

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!

Features:

devise-ios handles:

  • user registration
  • signing in / out
  • password reminder
  • form validation
  • profile updating
  • account deleting
  • Facebook and Google+ lightweight signing in

Requirements

  • Xcode 6.0 and iOS 7.0+ SDK
  • CocoaPods 0.37.2 (use gem install cocoapods to grab it!)

CocoaPods

CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party. To use devise-ios via CocoaPods write in your Podfile:

pod 'Devise', '~> 1.1.0'

Configuration

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:.

User manager

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;

User customization

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.

User model validation and messaging

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:

  • cannot be nil
  • length should be at least 4 signs
  • length should be at most 20 signs

and display appropriate messages when validation fails:

  • when has less than 4 signs: "should has at least 4 signs"
  • when has more than 20 signs: "should has at most 20 signs"

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.

Expanding networking

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.

UI Components

Sign up view example

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:

Log in view example

If you want to add a password reminder to form, just use following combination:

DVSAccountRetrieverFields logInFields = DVSAccountRetrieverFieldEmailAndPassword | DVSAccountRetrieverFieldProceedButton | DVSAccountRetrieverFieldPasswordReminder;

Result:

Log in view with reminder example

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;

Demo

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 install

or if you already cloned the project without --recursive:

$ git submodule update --init --recursive
$ pod install

License

devise-ios is available under the MIT license.

Contribution

First, thank you for contributing!

Here’s a few guidelines to follow:

More Info

Have a question? Please open an issue!
You can also read our blog post announcing devise-iOS for simplified auth.

Copyright © 2014-2015 Netguru

Latest podspec

{
    "name": "Devise",
    "summary": "Simple Devise client for iOS",
    "homepage": "https://github.com/netguru/devise-ios",
    "license": {
        "type": "MIT",
        "file": "LICENSE.md"
    },
    "authors": {
        "Patryk Kaczmarek": "[email protected]",
        "Adrian Kashivskyy": "[email protected]",
        "Wojciech Trzasko": "[email protected]",
        "Radosu0142aw Szeja": "[email protected]",
        "Paweu0142 Biau0142ecki": "[email protected]"
    },
    "version": "1.1.0",
    "source": {
        "git": "https://github.com/netguru/devise-ios.git",
        "tag": "1.1.0"
    },
    "platforms": {
        "ios": "7.0"
    },
    "source_files": "Devise/**/*.{h,m}",
    "requires_arc": true,
    "dependencies": {
        "UICKeyChainStore": [
            "~> 1.1"
        ],
        "ngrvalidator": [
            "~> 1.1.0"
        ],
        "XLForm": [
            "~> 2.1"
        ]
    },
    "frameworks": [
        "AddressBook",
        "AssetsLibrary",
        "Foundation",
        "CoreLocation",
        "CoreMotion",
        "CoreGraphics",
        "CoreText",
        "MediaPlayer",
        "Security",
        "SystemConfiguration",
        "UIKit"
    ],
    "vendored_frameworks": [
        "Frameworks/GoogleOpenSource.framework",
        "Frameworks/GooglePlus.framework"
    ],
    "private_header_files": "Devise/**/*Private.h"
}

Pin It on Pinterest

Share This