├── LICENSE ├── README.md ├── REValidation.podspec └── REValidation ├── NSError+REValidation.h ├── NSError+REValidation.m ├── REValidation.h ├── REValidation.m ├── REValidator.h ├── REValidator.m └── Validators ├── REEmailValidator.h ├── REEmailValidator.m ├── RELengthValidator.h ├── RELengthValidator.m ├── REPresenceValidator.h ├── REPresenceValidator.m ├── REURLValidator.h └── REURLValidator.m /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego). 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # REValidation 2 | 3 | Simple Objective-C object validation. 4 | 5 | Currently available default validators: 6 | 7 | > * Presence validator 8 | * String length validator 9 | * Email validator 10 | 11 | ## Requirements 12 | * Xcode 4.5 or higher 13 | * Apple LLVM compiler 14 | * iOS 5.0 or higher / Mac OS X 10.7 or higher 15 | * ARC 16 | 17 | ## Installation 18 | 19 | ### CocoaPods 20 | 21 | The recommended approach for installating `REValidation` is via the [CocoaPods](http://cocoapods.org/) package manager, as it provides flexible dependency management and dead simple installation. 22 | For best results, it is recommended that you install via CocoaPods >= **0.28.0** using Git >= **1.8.0** installed via Homebrew. 23 | 24 | Install CocoaPods if not already available: 25 | 26 | ``` bash 27 | $ [sudo] gem install cocoapods 28 | $ pod setup 29 | ``` 30 | 31 | Change to the directory of your Xcode project: 32 | 33 | ``` bash 34 | $ cd /path/to/MyProject 35 | $ touch Podfile 36 | $ edit Podfile 37 | ``` 38 | 39 | Edit your Podfile and add REValidation: 40 | 41 | ``` bash 42 | pod 'REValidation', '~> 0.1.4' 43 | ``` 44 | 45 | Install into your Xcode project: 46 | 47 | ``` bash 48 | $ pod install 49 | ``` 50 | 51 | Open your project in Xcode from the .xcworkspace file (not the usual project file) 52 | 53 | ``` bash 54 | $ open MyProject.xcworkspace 55 | ``` 56 | 57 | Please note that if your installation fails, it may be because you are installing with a version of Git lower than CocoaPods is expecting. Please ensure that you are running Git >= **1.8.0** by executing `git --version`. You can get a full picture of the installation details by executing `pod install --verbose`. 58 | 59 | ### Manual Install 60 | 61 | All you need to do is drop `REValidation` files into your project, and add `#include "REValidation.h"` to the top of classes that will use it. 62 | 63 | ## Example Usage 64 | 65 | ``` objective-c 66 | [REValidation registerDefaultValidators]; 67 | [REValidation registerDefaultErrorMessages]; 68 | 69 | NSString *emailString = @"test#@example.com"; 70 | NSArray *errors = [REValidation validateObject:emailString name:@"Email" validators:@[ @"presence", @"length(3, 20)", @"email" ]]; 71 | 72 | for (NSError *error in errors) 73 | NSLog(@"Error: %@", error.localizedDescription); 74 | 75 | // Alternatively you can use REValidator instances 76 | // 77 | NSString *testString = @""; 78 | errors = [REValidation validateObject:testString name:@"Test string" validators:@[ [REPresenceValidator validator], [RELengthValidator validatorWithParameters:@{ @"min": @3, @"max": @10}] ]]; 79 | 80 | for (NSError *error in errors) 81 | NSLog(@"Error: %@", error.localizedDescription); 82 | ``` 83 | 84 | It's easy to implement a custom validator, you need to subclass from `REValidator` and implement three methods: 85 | 86 | ```objective-c 87 | + (NSString *)name; 88 | + (NSDictionary *)parseParameterString:(NSString *)string; 89 | + (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters; 90 | ``` 91 | 92 | For example: 93 | 94 | ```objective-c 95 | + (NSString *)name 96 | { 97 | return @"length"; 98 | } 99 | 100 | + (NSDictionary *)parseParameterString:(NSString *)string 101 | { 102 | NSError *error = NULL; 103 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d+)" options:0 error:&error]; 104 | NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)]; 105 | NSMutableArray *results = [NSMutableArray array]; 106 | for (NSTextCheckingResult *matchResult in matches) { 107 | NSString *match = [string substringWithRange:[matchResult range]]; 108 | [results addObject:match]; 109 | } 110 | if (results.count == 2) { 111 | return @{ @"min": results[0], @"max": results[1]}; 112 | } 113 | 114 | return nil; 115 | } 116 | 117 | + (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters 118 | { 119 | NSUInteger minimumValue = [parameters[@"min"] integerValue]; 120 | NSUInteger maximumValue = [parameters[@"max"] integerValue]; 121 | 122 | if (object.length < minimumValue && minimumValue > 0) 123 | return [NSError re_validationErrorForDomain:@"com.REValidation.minimumLength", name, minimumValue]; 124 | 125 | if (object.length > maximumValue && maximumValue > 0) 126 | return [NSError re_validationErrorForDomain:@"com.REValidation.maximumLength", name, maximumValue]; 127 | 128 | return nil; 129 | } 130 | ``` 131 | 132 | It's possible to add validations without subclassing `REValidator` class using inline validations. Here's an example that shows how to use inline validations with [RETableViewManager](https://github.com/romaonthego/RETableViewManager): 133 | 134 | ```objective-c 135 | REValidator *nameValidator = [REValidator validator]; 136 | nameValidator.inlineValidation = ^NSError *(NSString *string, NSString *name) { 137 | if ([string componentsSeparatedByString:@" "].count < 2) { 138 | return [NSError errorWithDomain:@"" code:0 userInfo:@{NSLocalizedDescriptionKey: @"Please enter first and last name."}]; 139 | } 140 | return nil; 141 | }; 142 | 143 | RETextItem *nameItem = [RETextItem itemWithTitle:@"" value:self.contact.name placeholder:@"First & Last Name"]; 144 | nameItem.autocapitalizationType = UITextAutocapitalizationTypeWords; 145 | nameItem.validators = @[nameValidator]; 146 | ``` 147 | 148 | ## Contact 149 | 150 | Roman Efimov 151 | 152 | - https://github.com/romaonthego 153 | - https://twitter.com/romaonthego 154 | - romefimov@gmail.com 155 | 156 | ## License 157 | 158 | REValidation is available under the MIT license. 159 | 160 | Copyright © 2013 Roman Efimov. 161 | 162 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 163 | 164 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 165 | 166 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 167 | -------------------------------------------------------------------------------- /REValidation.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'REValidation' 3 | s.version = '0.1.4' 4 | s.authors = { 'Roman Efimov' => 'romefimov@gmail.com' } 5 | s.homepage = 'https://github.com/romaonthego/REValidation' 6 | s.summary = 'Simple Objective-C object validation.' 7 | s.source = { :git => 'https://github.com/romaonthego/REValidation.git', 8 | :tag => '0.1.4' } 9 | s.license = { :type => "MIT", :file => "LICENSE" } 10 | 11 | s.requires_arc = true 12 | s.source_files = 'REValidation', 'REValidation/Validators' 13 | s.public_header_files = 'REValidation/*.h', 'REValidation/Validators/*.h' 14 | s.ios.deployment_target = '5.0' 15 | s.osx.deployment_target = '10.7' 16 | end -------------------------------------------------------------------------------- /REValidation/NSError+REValidation.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSError+REValidation.h 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import 27 | 28 | @interface NSError (REValidation) 29 | 30 | + (NSError *)re_validationErrorForDomain:(NSString *)domain, ...; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /REValidation/NSError+REValidation.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSError+REValidation.m 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "NSError+REValidation.h" 27 | #import "REValidation.h" 28 | 29 | @implementation NSError (REValidation) 30 | 31 | + (NSError *)re_validationErrorForDomain:(NSString *)domain, ... 32 | { 33 | va_list args; 34 | va_start(args, domain); 35 | NSError *error = [NSError errorWithDomain:domain code:0 userInfo:@{ NSLocalizedDescriptionKey:[[NSString alloc] initWithFormat:[REValidation errorMessageForDomain:domain] arguments:args] }]; 36 | va_end(args); 37 | return error; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /REValidation/REValidation.h: -------------------------------------------------------------------------------- 1 | // 2 | // REValidation.h 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import 27 | #import "REValidator.h" 28 | #import "NSError+REValidation.h" 29 | #import "REPresenceValidator.h" 30 | #import "RELengthValidator.h" 31 | #import "REEmailValidator.h" 32 | #import "REURLValidator.h" 33 | 34 | @interface REValidation : NSObject 35 | 36 | ///----------------------------- 37 | /// @name Registering Validators 38 | ///----------------------------- 39 | 40 | + (void)registerDefaultValidators; 41 | + (void)registerDefaultErrorMessages; 42 | + (void)registerValidator:(Class)validatorClass; 43 | 44 | ///----------------------------- 45 | /// @name Validating Objects 46 | ///----------------------------- 47 | 48 | + (NSError *)validateObject:(NSObject *)object name:(NSString *)name validatorString:(NSString *)string; 49 | + (NSError *)validateObject:(NSObject *)object name:(NSString *)name validator:(REValidator *)validator; 50 | + (NSArray *)validateObject:(NSObject *)object name:(NSString *)name validators:(NSArray *)validators; 51 | 52 | ///----------------------------- 53 | /// @name Handling Error Messages 54 | ///----------------------------- 55 | 56 | + (NSString *)errorMessageForDomain:(NSString *)domain; 57 | + (void)setErrorMessage:(NSString *)message forDomain:(NSString *)domain; 58 | + (void)setErrorMessages:(NSDictionary *)messages; 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /REValidation/REValidation.m: -------------------------------------------------------------------------------- 1 | // 2 | // REValidation.m 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REValidation.h" 27 | 28 | @interface REValidation () 29 | 30 | @property (strong, readwrite, nonatomic) NSMutableDictionary *registeredValidators; 31 | @property (strong, readwrite, nonatomic) NSMutableDictionary *errorMessages; 32 | 33 | @end 34 | 35 | @implementation REValidation 36 | 37 | + (instancetype)sharedObject 38 | { 39 | static REValidation *_sharedClient = nil; 40 | static dispatch_once_t onceToken; 41 | dispatch_once(&onceToken, ^{ 42 | _sharedClient = [[REValidation alloc] init]; 43 | }); 44 | 45 | return _sharedClient; 46 | } 47 | 48 | + (void)registerValidator:(Class)validatorClass 49 | { 50 | [REValidation sharedObject].registeredValidators[[validatorClass name]] = NSStringFromClass(validatorClass); 51 | } 52 | 53 | + (void)registerDefaultValidators 54 | { 55 | static dispatch_once_t onceToken; 56 | dispatch_once(&onceToken, ^{ 57 | [REValidation registerValidator:[REPresenceValidator class]]; 58 | [REValidation registerValidator:[RELengthValidator class]]; 59 | [REValidation registerValidator:[REEmailValidator class]]; 60 | [REValidation registerValidator:[REURLValidator class]]; 61 | }); 62 | } 63 | 64 | + (void)registerDefaultErrorMessages 65 | { 66 | static dispatch_once_t onceToken; 67 | dispatch_once(&onceToken, ^{ 68 | NSDictionary *messages = @{ 69 | @"com.REValidation.presence": @"%@ can't be blank.", 70 | @"com.REValidation.minimumLength": @"%@ is too short (minimum is %i characters).", 71 | @"com.REValidation.maximumLength": @"%@ is too long (maximum is %i characters).", 72 | @"com.REValidation.email": @"%@ is not a valid email.", 73 | @"com.REValidation.url": @"%@ is not a valid url." 74 | }; 75 | [REValidation sharedObject].errorMessages = [NSMutableDictionary dictionaryWithDictionary:messages]; 76 | }); 77 | } 78 | 79 | + (NSString *)errorMessageForDomain:(NSString *)domain 80 | { 81 | return NSLocalizedString([REValidation sharedObject].errorMessages[domain], [REValidation sharedObject].errorMessages[domain]); 82 | } 83 | 84 | + (void)setErrorMessage:(NSString *)message forDomain:(NSString *)domain 85 | { 86 | [REValidation sharedObject].errorMessages[domain] = message; 87 | } 88 | 89 | + (void)setErrorMessages:(NSDictionary *)messages 90 | { 91 | [REValidation sharedObject].errorMessages = [NSMutableDictionary dictionaryWithDictionary:messages]; 92 | } 93 | 94 | + (NSError *)validateObject:(NSObject *)object name:(NSString *)name validatorString:(NSString *)string 95 | { 96 | NSString *validatorStringName = [string componentsSeparatedByString:@"("][0]; 97 | for (NSString *validatorName in [REValidation sharedObject].registeredValidators) { 98 | if ([validatorName isEqualToString:validatorStringName]) { 99 | Class validator = NSClassFromString([REValidation sharedObject].registeredValidators[validatorName]); 100 | return [[validator class] validateObject:object variableName:name parameters:[validator parseParameterString:string]]; 101 | } 102 | } 103 | return nil; 104 | } 105 | 106 | + (NSError *)validateObject:(NSObject *)object name:(NSString *)name validator:(REValidator *)validator 107 | { 108 | return [[validator class] validateObject:object variableName:name parameters:validator.parameters]; 109 | } 110 | 111 | + (NSArray *)validateObject:(NSObject *)object name:(NSString *)name validators:(NSArray *)validators 112 | { 113 | NSMutableArray *errors = [NSMutableArray array]; 114 | 115 | for (id validator in validators) { 116 | NSError *error; 117 | if ([validator isKindOfClass:[NSString class]]) { 118 | error = [self validateObject:object name:name validatorString:(NSString *)validator]; 119 | } else { 120 | REValidator *v = (REValidator *)validator; 121 | if (v.inlineValidation) { 122 | error = [[v class] validateObject:object variableName:name validation:v.inlineValidation]; 123 | } else { 124 | error = [self validateObject:object name:name validator:validator]; 125 | } 126 | } 127 | if (error) 128 | [errors addObject:error]; 129 | } 130 | 131 | return errors; 132 | } 133 | 134 | 135 | - (id)init 136 | { 137 | self = [super init]; 138 | if (!self) 139 | return nil; 140 | 141 | self.registeredValidators = [[NSMutableDictionary alloc] init]; 142 | 143 | return self; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /REValidation/REValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // REValidator.h 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import 27 | 28 | @interface REValidator : NSObject 29 | 30 | @property (strong, readonly, nonatomic) NSDictionary *parameters; 31 | @property (copy, readwrite, nonatomic) NSError *(^inlineValidation)(id object, NSString *name); 32 | 33 | ///----------------------------- 34 | /// @name Getting Validator Instance 35 | ///----------------------------- 36 | 37 | + (instancetype)validator; 38 | + (instancetype)validatorWithParameters:(NSDictionary *)parameters; 39 | + (instancetype)validatorWithInlineValidation:(NSError *(^)(id object, NSString *name))validation; 40 | 41 | ///----------------------------- 42 | /// @name Configuring Representation 43 | ///----------------------------- 44 | 45 | + (NSString *)name; 46 | + (NSDictionary *)parseParameterString:(NSString *)string; 47 | 48 | ///----------------------------- 49 | /// @name Validating Objects 50 | ///----------------------------- 51 | 52 | + (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters; 53 | + (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name validation:(NSError *(^)(id object, NSString *name))validation; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /REValidation/REValidator.m: -------------------------------------------------------------------------------- 1 | // 2 | // REValidator.m 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REValidator.h" 27 | 28 | @interface REValidator () 29 | 30 | @property (strong, readwrite, nonatomic) NSDictionary *parameters; 31 | 32 | @end 33 | 34 | @implementation REValidator 35 | 36 | + (instancetype)validator 37 | { 38 | return [[self alloc] init]; 39 | } 40 | 41 | + (instancetype)validatorWithParameters:(NSDictionary *)parameters 42 | { 43 | REValidator *validator = [[self alloc] init]; 44 | validator.parameters = parameters; 45 | return validator; 46 | } 47 | 48 | + (instancetype)validatorWithInlineValidation:(NSError *(^)(id object, NSString *name))validation 49 | { 50 | REValidator *validator = [[self alloc] init]; 51 | validator.inlineValidation = validation; 52 | return validator; 53 | } 54 | 55 | + (NSString *)name 56 | { 57 | return @""; 58 | } 59 | 60 | + (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters 61 | { 62 | return nil; 63 | } 64 | 65 | + (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name validation:(NSError *(^)(id object, NSString *name))validation 66 | { 67 | if (validation) 68 | return validation(object, name); 69 | return nil; 70 | } 71 | 72 | + (NSDictionary *)parseParameterString:(NSString *)string 73 | { 74 | return nil; 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /REValidation/Validators/REEmailValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // REEmailValidator.h 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REValidator.h" 27 | 28 | @interface REEmailValidator : REValidator 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /REValidation/Validators/REEmailValidator.m: -------------------------------------------------------------------------------- 1 | // 2 | // REEmailValidator.m 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REEmailValidator.h" 27 | #import "REValidation.h" 28 | 29 | @implementation REEmailValidator 30 | 31 | + (NSString *)name 32 | { 33 | return @"email"; 34 | } 35 | 36 | + (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters 37 | { 38 | NSString *string = object ? object : @""; 39 | if (string.length == 0) 40 | return nil; 41 | 42 | NSError *error = NULL; 43 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" options:NSRegularExpressionCaseInsensitive error:&error]; 44 | NSTextCheckingResult *match = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)]; 45 | 46 | if (!match) 47 | return [NSError re_validationErrorForDomain:@"com.REValidation.email", name]; 48 | 49 | return nil; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /REValidation/Validators/RELengthValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // RELengthValidator.h 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REValidator.h" 27 | 28 | @interface RELengthValidator : REValidator 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /REValidation/Validators/RELengthValidator.m: -------------------------------------------------------------------------------- 1 | // 2 | // RELengthValidator.m 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "RELengthValidator.h" 27 | #import "NSError+REValidation.h" 28 | 29 | @implementation RELengthValidator 30 | 31 | + (NSString *)name 32 | { 33 | return @"length"; 34 | } 35 | 36 | + (NSDictionary *)parseParameterString:(NSString *)string 37 | { 38 | NSError *error = NULL; 39 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\d+)" options:0 error:&error]; 40 | NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)]; 41 | NSMutableArray *results = [NSMutableArray array]; 42 | for (NSTextCheckingResult *matchResult in matches) { 43 | NSString *match = [string substringWithRange:[matchResult range]]; 44 | [results addObject:match]; 45 | } 46 | if (results.count == 2) { 47 | return @{ @"min": results[0], @"max": results[1]}; 48 | } 49 | 50 | return nil; 51 | } 52 | 53 | + (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters 54 | { 55 | NSUInteger minimumValue = [parameters[@"min"] integerValue]; 56 | NSUInteger maximumValue = [parameters[@"max"] integerValue]; 57 | 58 | if (object.length < minimumValue && minimumValue > 0) 59 | return [NSError re_validationErrorForDomain:@"com.REValidation.minimumLength", name, minimumValue]; 60 | 61 | if (object.length > maximumValue && maximumValue > 0) 62 | return [NSError re_validationErrorForDomain:@"com.REValidation.maximumLength", name, maximumValue]; 63 | 64 | return nil; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /REValidation/Validators/REPresenceValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // REPresenceValidator.h 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REValidator.h" 27 | 28 | @interface REPresenceValidator : REValidator 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /REValidation/Validators/REPresenceValidator.m: -------------------------------------------------------------------------------- 1 | // 2 | // REPresenceValidator.m 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REPresenceValidator.h" 27 | #import "NSError+REValidation.h" 28 | 29 | @implementation REPresenceValidator 30 | 31 | + (NSString *)name 32 | { 33 | return @"presence"; 34 | } 35 | 36 | + (NSError *)validateObject:(NSObject *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters 37 | { 38 | if (!object) 39 | return [NSError re_validationErrorForDomain:@"com.REValidation.presence", name]; 40 | 41 | if ([object isKindOfClass:[NSString class]] && [(NSString *)object length] == 0) 42 | return [NSError re_validationErrorForDomain:@"com.REValidation.presence", name]; 43 | 44 | if ([object isKindOfClass:[NSArray class]] && [(NSArray *)object count] == 0) 45 | return [NSError re_validationErrorForDomain:@"com.REValidation.presence", name]; 46 | 47 | return nil; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /REValidation/Validators/REURLValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // REURLValidator.h 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REValidator.h" 27 | 28 | @interface REURLValidator : REValidator 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /REValidation/Validators/REURLValidator.m: -------------------------------------------------------------------------------- 1 | // 2 | // REURLValidator.m 3 | // REValidation 4 | // 5 | // Copyright (c) 2013 Roman Efimov (https://github.com/romaonthego) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | // 25 | 26 | #import "REURLValidator.h" 27 | #import "REValidation.h" 28 | 29 | @implementation REURLValidator 30 | 31 | + (NSString *)name 32 | { 33 | return @"url"; 34 | } 35 | 36 | + (NSError *)validateObject:(NSString *)object variableName:(NSString *)name parameters:(NSDictionary *)parameters 37 | { 38 | NSString *string = object ? object : @""; 39 | if (string.length == 0) 40 | return nil; 41 | 42 | NSError *error = NULL; 43 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^(?i)(?:(?:https?|ftp):\\/\\/)?(?:\\S+(?::\\S*)?@)?(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?$" options:NSRegularExpressionCaseInsensitive error:&error]; 44 | NSTextCheckingResult *match = [regex firstMatchInString:string options:0 range:NSMakeRange(0, string.length)]; 45 | if (!match) 46 | return [NSError re_validationErrorForDomain:@"com.REValidation.url", name]; 47 | 48 | return nil; 49 | } 50 | 51 | @end 52 | --------------------------------------------------------------------------------