Skip to content

Commit 1288c10

Browse files
committed
updating readme
1 parent e2d88ee commit 1288c10

23 files changed

+749
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='3.0' sdk='iphonesimulator'>
3+
<sections>
4+
<code source-file-name='section-1.swift'/>
5+
</sections>
6+
<timeline fileName='timeline.xctimeline'/>
7+
</playground>
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Playground - noun: a place where people can play
2+
3+
import UIKit
4+
5+
var str = "Hello, playground"
6+
7+
var errors[String:Int] = ["This":1, "Is": 2, "A": 3, "Test": 4]
8+
9+
println(errors.values)
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Timeline
3+
version = "3.0">
4+
<TimelineItems>
5+
</TimelineItems>
6+
</Timeline>

README.md

+200-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,202 @@
1-
swift-validator
1+
Swift-validator
22
===============
33

4-
A rule-based validation library for Swift
4+
Swift Validator is a rule-based validation library for Swift.
5+
6+
Core Concepts
7+
8+
* ```UITextField``` and ```ValidationRule``` go into the ```Validator```, ```UITextFields``` and ```ValidationErrors``` come out of ```Validator```
9+
* ```UITextField``` is registered to ```Validator```
10+
* ```Validator``` evaluates ```ValidationRules``` sequentially and stops evaluating when a ```ValidationRule``` fails.
11+
12+
## Quick Start
13+
14+
Initialize the ```Validator``` by setting a delegate to a View Controller or other object.
15+
16+
```swift
17+
18+
// ViewController.swift
19+
20+
override func viewDidLoad() {
21+
super.viewDidLoad()
22+
23+
var validator = Validator(delegate: self)
24+
}
25+
26+
```
27+
28+
Register the fields that you want to validate
29+
30+
```swift
31+
32+
var fields:[String] = ["FullName", "Email", "Phone"]
33+
34+
// Validation Rules are evaluated from left to right. The first rule is ValidationRuleType.Required the second is ValidationRuleType.FullName.
35+
validator.registerField(fields[0], textField:nameTextField, rules: [.Required, .FullName])
36+
validator.registerField(fields[1], textField:emailTextField, rules: [.Required, .Email])
37+
validator.registerField(fields[2], textField:phoneTextField, rules: [.Required, .PhoneNumber])
38+
39+
```
40+
41+
Validate Individual Field
42+
43+
```swift
44+
45+
func validator.validateFieldBy(fields[0], delegate:self)
46+
47+
// ValidationFieldDelegate methods
48+
func validationFieldSuccess(key:String, validField:UITextField){
49+
validField.backgroundColor = UIColor.greenColor()
50+
}
51+
52+
func validationFieldFailure(key:String, error:ValidationError){
53+
println(error.error.description)
54+
}
55+
56+
```
57+
58+
Validate All Fields
59+
60+
```swift
61+
62+
validator.validateAllBy(fields, delegate:self)
63+
64+
// ValidationDelegate methods
65+
66+
func validationWasSuccessful(){
67+
// submit the form
68+
}
69+
70+
func validationFailed(key:String, errors[String:ValidationError]){
71+
// turn the fields to red
72+
for error in errors.values {
73+
error.textField.backgroundColor = UIColor.redColor()
74+
println("error -> \(error.error.description)")
75+
}
76+
}
77+
78+
```
79+
80+
## Custom Validation
81+
82+
We will create a ```SSNValidation``` class to show how to create your own Validation. A United States Social Security Number (or SSN) is a field that consists of XXX-XX-XXXX.
83+
84+
Create a class that implements the Validation protocol
85+
86+
```swift
87+
88+
class SSNValidation: Validation {
89+
let SSN_REGEX = "^\\d{3}-\\d{2}-\\d{4}$"
90+
91+
func validate(value: String) -> (Bool, ValidationErrorType) {
92+
if let ssnTest = NSPredicate(format: "SELF MATCHES %@", SSN_REGEX) {
93+
if ssnTest.evaluateWithObject(value) {
94+
return (true, .NoError)
95+
}
96+
return (false, .SocialSecurity) // We will create this later ValidationErrorTYpe
97+
}
98+
return (false, .SocialSecurity)
99+
}
100+
101+
}
102+
103+
```
104+
105+
Add the ```.SocialSecurity``` ValidationRuleType
106+
107+
```swift
108+
109+
enum ValidationRuleType {
110+
case Required,
111+
Email,
112+
Password,
113+
MinLength,
114+
MaxLength,
115+
ZipCode,
116+
PhoneNumber,
117+
FullName,
118+
SocialSecurity // Added to the Rule Types
119+
}
120+
121+
```
122+
123+
Add the ```.SocialSecurity``` ValidationErrorType and description()
124+
125+
```swift
126+
127+
enum ValidationErrorType {
128+
case Required,
129+
Email,
130+
Password,
131+
MinLength,
132+
MaxLength,
133+
ZipCode,
134+
PhoneNumber,
135+
FullName,
136+
SocialSecurity, // Added to the Error Types
137+
NoError
138+
139+
func description() -> String {
140+
switch self {
141+
case .Required:
142+
return "Required field"
143+
case .Email:
144+
return "Must be a valid email"
145+
case .MaxLength:
146+
return "This field should be less than"
147+
case .ZipCode:
148+
return "5 digit zipcode"
149+
case .PhoneNumber:
150+
return "10 digit phone number"
151+
case .Password:
152+
return "Must be at least 8 characters"
153+
case .FullName:
154+
return "Provide a first & last name"
155+
// Adding the desired error message
156+
case .SocialSecurity:
157+
return "SSN is XXX-XX-XXXX"
158+
default:
159+
return ""
160+
}
161+
}
162+
163+
}
164+
165+
```
166+
Register the Validation with the ValidationFactory
167+
168+
```swift
169+
170+
class ValidationFactory {
171+
class func validationForRule(rule:ValidationRuleType) -> Validation {
172+
switch rule {
173+
case .Required:
174+
return RequiredValidation()
175+
case .Email:
176+
return EmailValidation()
177+
case .MinLength:
178+
return MinLengthValidation()
179+
case .MaxLength:
180+
return MaxLengthValidation()
181+
case .PhoneNumber:
182+
return PhoneNumberValidation()
183+
case .ZipCode:
184+
return ZipCodeValidation()
185+
case .FullName:
186+
return FullNameValidation()
187+
// Add Validation to allow Factory to create one on the fly for you
188+
case .SocialSecurity:
189+
return SSNValidation()
190+
default:
191+
return RequiredValidation()
192+
}
193+
}
194+
}
195+
196+
```
197+
198+
199+
200+
201+
202+

Validator.xcodeproj/project.pbxproj

+78
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@
1313
62D1AE241A1E6D4400E4DFF8 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 62D1AE231A1E6D4400E4DFF8 /* Images.xcassets */; };
1414
62D1AE271A1E6D4400E4DFF8 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 62D1AE251A1E6D4400E4DFF8 /* LaunchScreen.xib */; };
1515
62D1AE331A1E6D4500E4DFF8 /* ValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE321A1E6D4500E4DFF8 /* ValidatorTests.swift */; };
16+
62D1AE3E1A1E6FEF00E4DFF8 /* FullNameValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE3D1A1E6FEF00E4DFF8 /* FullNameValidation.swift */; };
17+
62D1AE491A1E6FF800E4DFF8 /* EmailValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE3F1A1E6FF800E4DFF8 /* EmailValidation.swift */; };
18+
62D1AE4A1A1E6FF800E4DFF8 /* MaxLengthValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE401A1E6FF800E4DFF8 /* MaxLengthValidation.swift */; };
19+
62D1AE4B1A1E6FF800E4DFF8 /* MinLengthValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE411A1E6FF800E4DFF8 /* MinLengthValidation.swift */; };
20+
62D1AE4C1A1E6FF800E4DFF8 /* PhoneNumberValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE421A1E6FF800E4DFF8 /* PhoneNumberValidation.swift */; };
21+
62D1AE4D1A1E6FF800E4DFF8 /* RequiredValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE431A1E6FF800E4DFF8 /* RequiredValidation.swift */; };
22+
62D1AE4E1A1E6FF800E4DFF8 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE441A1E6FF800E4DFF8 /* Validation.swift */; };
23+
62D1AE4F1A1E6FF800E4DFF8 /* ValidationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE451A1E6FF800E4DFF8 /* ValidationError.swift */; };
24+
62D1AE501A1E6FF800E4DFF8 /* ValidationErrorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE461A1E6FF800E4DFF8 /* ValidationErrorType.swift */; };
25+
62D1AE511A1E6FF800E4DFF8 /* ValidationFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE471A1E6FF800E4DFF8 /* ValidationFactory.swift */; };
26+
62D1AE521A1E6FF800E4DFF8 /* ValidationRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE481A1E6FF800E4DFF8 /* ValidationRule.swift */; };
27+
62D1AE571A1E700200E4DFF8 /* ValidationRuleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE531A1E700200E4DFF8 /* ValidationRuleType.swift */; };
28+
62D1AE581A1E700200E4DFF8 /* Validator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE541A1E700200E4DFF8 /* Validator.swift */; };
29+
62D1AE591A1E700200E4DFF8 /* ZipCodeValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE551A1E700200E4DFF8 /* ZipCodeValidation.swift */; };
30+
62D1AE5A1A1E700200E4DFF8 /* PasswordValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62D1AE561A1E700200E4DFF8 /* PasswordValidation.swift */; };
1631
/* End PBXBuildFile section */
1732

1833
/* Begin PBXContainerItemProxy section */
@@ -36,6 +51,22 @@
3651
62D1AE2C1A1E6D4500E4DFF8 /* ValidatorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ValidatorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3752
62D1AE311A1E6D4500E4DFF8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3853
62D1AE321A1E6D4500E4DFF8 /* ValidatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidatorTests.swift; sourceTree = "<group>"; };
54+
62D1AE3D1A1E6FEF00E4DFF8 /* FullNameValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FullNameValidation.swift; sourceTree = "<group>"; };
55+
62D1AE3F1A1E6FF800E4DFF8 /* EmailValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmailValidation.swift; sourceTree = "<group>"; };
56+
62D1AE401A1E6FF800E4DFF8 /* MaxLengthValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaxLengthValidation.swift; sourceTree = "<group>"; };
57+
62D1AE411A1E6FF800E4DFF8 /* MinLengthValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinLengthValidation.swift; sourceTree = "<group>"; };
58+
62D1AE421A1E6FF800E4DFF8 /* PhoneNumberValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhoneNumberValidation.swift; sourceTree = "<group>"; };
59+
62D1AE431A1E6FF800E4DFF8 /* RequiredValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequiredValidation.swift; sourceTree = "<group>"; };
60+
62D1AE441A1E6FF800E4DFF8 /* Validation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Validation.swift; sourceTree = "<group>"; };
61+
62D1AE451A1E6FF800E4DFF8 /* ValidationError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationError.swift; sourceTree = "<group>"; };
62+
62D1AE461A1E6FF800E4DFF8 /* ValidationErrorType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationErrorType.swift; sourceTree = "<group>"; };
63+
62D1AE471A1E6FF800E4DFF8 /* ValidationFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationFactory.swift; sourceTree = "<group>"; };
64+
62D1AE481A1E6FF800E4DFF8 /* ValidationRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationRule.swift; sourceTree = "<group>"; };
65+
62D1AE531A1E700200E4DFF8 /* ValidationRuleType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationRuleType.swift; sourceTree = "<group>"; };
66+
62D1AE541A1E700200E4DFF8 /* Validator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Validator.swift; sourceTree = "<group>"; };
67+
62D1AE551A1E700200E4DFF8 /* ZipCodeValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipCodeValidation.swift; sourceTree = "<group>"; };
68+
62D1AE561A1E700200E4DFF8 /* PasswordValidation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordValidation.swift; sourceTree = "<group>"; };
69+
62D1AE5C1A1E78EE00E4DFF8 /* MyPlayground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = MyPlayground.playground; sourceTree = "<group>"; };
3970
/* End PBXFileReference section */
4071

4172
/* Begin PBXFrameworksBuildPhase section */
@@ -59,6 +90,7 @@
5990
62D1AE0E1A1E6D4400E4DFF8 = {
6091
isa = PBXGroup;
6192
children = (
93+
62D1AE5C1A1E78EE00E4DFF8 /* MyPlayground.playground */,
6294
62D1AE191A1E6D4400E4DFF8 /* Validator */,
6395
62D1AE2F1A1E6D4500E4DFF8 /* ValidatorTests */,
6496
62D1AE181A1E6D4400E4DFF8 /* Products */,
@@ -77,6 +109,7 @@
77109
62D1AE191A1E6D4400E4DFF8 /* Validator */ = {
78110
isa = PBXGroup;
79111
children = (
112+
62D1AE3C1A1E6FAF00E4DFF8 /* lib */,
80113
62D1AE1C1A1E6D4400E4DFF8 /* AppDelegate.swift */,
81114
62D1AE1E1A1E6D4400E4DFF8 /* ViewController.swift */,
82115
62D1AE201A1E6D4400E4DFF8 /* Main.storyboard */,
@@ -112,6 +145,36 @@
112145
name = "Supporting Files";
113146
sourceTree = "<group>";
114147
};
148+
62D1AE3C1A1E6FAF00E4DFF8 /* lib */ = {
149+
isa = PBXGroup;
150+
children = (
151+
62D1AE5B1A1E701B00E4DFF8 /* Validations */,
152+
62D1AE531A1E700200E4DFF8 /* ValidationRuleType.swift */,
153+
62D1AE541A1E700200E4DFF8 /* Validator.swift */,
154+
62D1AE451A1E6FF800E4DFF8 /* ValidationError.swift */,
155+
62D1AE461A1E6FF800E4DFF8 /* ValidationErrorType.swift */,
156+
62D1AE471A1E6FF800E4DFF8 /* ValidationFactory.swift */,
157+
62D1AE481A1E6FF800E4DFF8 /* ValidationRule.swift */,
158+
);
159+
name = lib;
160+
sourceTree = "<group>";
161+
};
162+
62D1AE5B1A1E701B00E4DFF8 /* Validations */ = {
163+
isa = PBXGroup;
164+
children = (
165+
62D1AE441A1E6FF800E4DFF8 /* Validation.swift */,
166+
62D1AE3D1A1E6FEF00E4DFF8 /* FullNameValidation.swift */,
167+
62D1AE421A1E6FF800E4DFF8 /* PhoneNumberValidation.swift */,
168+
62D1AE431A1E6FF800E4DFF8 /* RequiredValidation.swift */,
169+
62D1AE3F1A1E6FF800E4DFF8 /* EmailValidation.swift */,
170+
62D1AE411A1E6FF800E4DFF8 /* MinLengthValidation.swift */,
171+
62D1AE401A1E6FF800E4DFF8 /* MaxLengthValidation.swift */,
172+
62D1AE561A1E700200E4DFF8 /* PasswordValidation.swift */,
173+
62D1AE551A1E700200E4DFF8 /* ZipCodeValidation.swift */,
174+
);
175+
name = Validations;
176+
sourceTree = "<group>";
177+
};
115178
/* End PBXGroup section */
116179

117180
/* Begin PBXNativeTarget section */
@@ -212,8 +275,23 @@
212275
isa = PBXSourcesBuildPhase;
213276
buildActionMask = 2147483647;
214277
files = (
278+
62D1AE4C1A1E6FF800E4DFF8 /* PhoneNumberValidation.swift in Sources */,
279+
62D1AE5A1A1E700200E4DFF8 /* PasswordValidation.swift in Sources */,
280+
62D1AE4F1A1E6FF800E4DFF8 /* ValidationError.swift in Sources */,
281+
62D1AE3E1A1E6FEF00E4DFF8 /* FullNameValidation.swift in Sources */,
282+
62D1AE4B1A1E6FF800E4DFF8 /* MinLengthValidation.swift in Sources */,
215283
62D1AE1F1A1E6D4400E4DFF8 /* ViewController.swift in Sources */,
284+
62D1AE4E1A1E6FF800E4DFF8 /* Validation.swift in Sources */,
216285
62D1AE1D1A1E6D4400E4DFF8 /* AppDelegate.swift in Sources */,
286+
62D1AE581A1E700200E4DFF8 /* Validator.swift in Sources */,
287+
62D1AE501A1E6FF800E4DFF8 /* ValidationErrorType.swift in Sources */,
288+
62D1AE491A1E6FF800E4DFF8 /* EmailValidation.swift in Sources */,
289+
62D1AE511A1E6FF800E4DFF8 /* ValidationFactory.swift in Sources */,
290+
62D1AE591A1E700200E4DFF8 /* ZipCodeValidation.swift in Sources */,
291+
62D1AE571A1E700200E4DFF8 /* ValidationRuleType.swift in Sources */,
292+
62D1AE521A1E6FF800E4DFF8 /* ValidationRule.swift in Sources */,
293+
62D1AE4A1A1E6FF800E4DFF8 /* MaxLengthValidation.swift in Sources */,
294+
62D1AE4D1A1E6FF800E4DFF8 /* RequiredValidation.swift in Sources */,
217295
);
218296
runOnlyForDeploymentPostprocessing = 0;
219297
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
6+
<false/>
7+
<key>IDESourceControlProjectIdentifier</key>
8+
<string>41CB4003-1551-4C4C-B53F-78A56D1DFBE5</string>
9+
<key>IDESourceControlProjectName</key>
10+
<string>Validator</string>
11+
<key>IDESourceControlProjectOriginsDictionary</key>
12+
<dict>
13+
<key>44BA2A1DF8B8E3EE0CCBE8F37625F38B9979A032</key>
14+
<string>github.com:jpotts18/swift-validator.git</string>
15+
</dict>
16+
<key>IDESourceControlProjectPath</key>
17+
<string>Validator.xcodeproj</string>
18+
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
19+
<dict>
20+
<key>44BA2A1DF8B8E3EE0CCBE8F37625F38B9979A032</key>
21+
<string>../..</string>
22+
</dict>
23+
<key>IDESourceControlProjectURL</key>
24+
<string>github.com:jpotts18/swift-validator.git</string>
25+
<key>IDESourceControlProjectVersion</key>
26+
<integer>111</integer>
27+
<key>IDESourceControlProjectWCCIdentifier</key>
28+
<string>44BA2A1DF8B8E3EE0CCBE8F37625F38B9979A032</string>
29+
<key>IDESourceControlProjectWCConfigurations</key>
30+
<array>
31+
<dict>
32+
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
33+
<string>public.vcs.git</string>
34+
<key>IDESourceControlWCCIdentifierKey</key>
35+
<string>44BA2A1DF8B8E3EE0CCBE8F37625F38B9979A032</string>
36+
<key>IDESourceControlWCCName</key>
37+
<string>Validator</string>
38+
</dict>
39+
</array>
40+
</dict>
41+
</plist>

0 commit comments

Comments
 (0)