All Projects → ShabanKamell → SwiftUIFormValidator

ShabanKamell / SwiftUIFormValidator

Licence: other
Declarative form validator for SwiftUI.

Programming Languages

swift
15916 projects
ruby
36898 projects - #4 most used programming language
objective c
16641 projects - #2 most used programming language

Projects that are alternatives of or similar to SwiftUIFormValidator

TermiNetwork
🌏 A zero-dependency networking solution for building modern and secure iOS, watchOS, macOS and tvOS applications.
Stars: ✭ 80 (+135.29%)
Mutual labels:  apple, tvos, carthage, swiftui
Xcglogger
A debug log framework for use in Swift projects. Allows you to log details to the console (and optionally a file), just like you would have with NSLog() or print(), but with additional information, such as the date, function name, filename and line number.
Stars: ✭ 3,710 (+10811.76%)
Mutual labels:  tvos, carthage, swiftpm
Columbus
A feature-rich country picker for iOS, tvOS and watchOS.
Stars: ✭ 23 (-32.35%)
Mutual labels:  tvos, carthage, swiftui
Wwdc
You don't have the time to watch all the WWDC session videos yourself? No problem me and many contributors extracted the gist for you 🥳
Stars: ✭ 2,561 (+7432.35%)
Mutual labels:  apple, tvos, swiftui
Open Source Ios Apps
📱 Collaborative List of Open-Source iOS Apps
Stars: ✭ 28,826 (+84682.35%)
Mutual labels:  apple, tvos, swiftui
Rome
Carthage cache for S3, Minio, Ceph, Google Storage, Artifactory and many others
Stars: ✭ 724 (+2029.41%)
Mutual labels:  apple, tvos, carthage
CoreDataToSwiftUI
Rule based CRUD CoreData Frontends for SwiftUI
Stars: ✭ 18 (-47.06%)
Mutual labels:  declarative-ui, declarative-programming, swiftui
data-field
A SwiftUI view that wraps a text field to only accept specific data.
Stars: ✭ 13 (-61.76%)
Mutual labels:  tvos, swiftui
QuoteKit
A framework to use the free APIs provided by https://quotable.io
Stars: ✭ 17 (-50%)
Mutual labels:  tvos, swiftui
tracelog
TraceLog is a highly configurable, flexible, portable, and simple to use debug logging system for Swift and Objective-C applications running on Linux, macOS, iOS, watchOS, and tvOS.
Stars: ✭ 52 (+52.94%)
Mutual labels:  tvos, swiftpm
Dots
Lightweight Concurrent Networking Framework
Stars: ✭ 35 (+2.94%)
Mutual labels:  tvos, carthage
KeyboardKitPro
KeyboardKit Pro extends KeyboardKit with pro features.
Stars: ✭ 42 (+23.53%)
Mutual labels:  tvos, swiftui
SwiftCurrent
A library for managing complex workflows in Swift
Stars: ✭ 286 (+741.18%)
Mutual labels:  tvos, swiftui
Mechanica
A cross-platform library of Swift utils to ease your iOS | macOS | watchOS | tvOS and Linux development.
Stars: ✭ 27 (-20.59%)
Mutual labels:  tvos, carthage
WWDCNotes
WWDCNotes.com content
Stars: ✭ 343 (+908.82%)
Mutual labels:  tvos, swiftui
IrregularGradient
Create animated irregular gradients in SwiftUI.
Stars: ✭ 127 (+273.53%)
Mutual labels:  tvos, swiftui
ScaledFont
ScaledFont - Using custom fonts with dynamic type
Stars: ✭ 50 (+47.06%)
Mutual labels:  tvos, swiftui
Partial
Type-safe wrapper mirroring the wrapped type's properties, making each property optional
Stars: ✭ 61 (+79.41%)
Mutual labels:  carthage, swiftpm
TVKit
UI components for tvOS
Stars: ✭ 20 (-41.18%)
Mutual labels:  tvos, carthage
F1-AppleTV
F1TV app for the Apple TV
Stars: ✭ 16 (-52.94%)
Mutual labels:  tvos, swiftui

Gray shape shifter

SwiftUIFormValidator

The world's easiest, most clean SwiftUI form validation.



Stargazers repo roster for @ShabanKamell/SwiftUIFormValidator

SwiftUIFormValidator

A declarative SwiftUI form validation. Clean, simple, and customizable.

Discuss it on Product Hunt 🦄

Form Screenshot

Table of contents

Usage

Basic Setup

  // 1 
import FormValidator

// 2
class FormInfo: ObservableObject {
    @Published var firstName: String = ""
    // 3
    lazy var form = {
        FormValidation(validationType: .immediate)
    }()
    // 4
    lazy var firstNameValidation: ValidationContainer = {
        $firstName.nonEmptyValidator(form: form, errorMessage: "First name is not valid")
    }()
}

struct ContentView: View {
    // 5
    @ObservedObject var formInfo = FormInfo()

    var body: some View {
        TextField("First Name", text: $formInfo.firstName)
                .validation(formInfo.firstNameValidation) // 6
    }
}
  1. Import FormValidator.
  2. Declare an ObservableObject for the form with any name, for example, FormInfo, LoginInfo, or any name.
  3. Declare FormValidation object and choose a validation type.
  4. Declare a ValidationContainer for the field you need to validate.
  5. In your view, declare the FormValidation object.
  6. Declare validation(formInfo.firstNameValidation) with the validation of the field.

Congratulation!! your field is now validated for you!

Custom Error View

You can provide your own custom error view by providing the view with the validation modifier

TextField("First Name", text: $formInfo.firstName)
        .validation(formInfo.firstNameValidation) { message in
            Text(message.uppercased())
                    .foregroundColor(Color.red)
                    .font(.caption)
        }

Inline Validation

For fast validation, you can use InlineValidator and provide your validation logic in line:

 lazy var lastNamesValidation: ValidationContainer = {
    $lastNames.inlineValidator(form: form) { value in
        // Put validation logic here
        !value.isEmpty
    }
}()

Validation Types

You can choose between 2 different validation types: FormValidation(validationType: .immediate) and FormValidation(validationType: .deffered)

  1. immediate: the validation is triggered every time the field is changed. An error message will be shown in case the value is invalid.
  2. deferred: in this case, the validation will be triggered manually only using FormValidation.triggerValidation() The error messages will be displayed only after triggering the validation manually.

Manual Validation

You can trigger the form validation any time by calling FormValidation.triggerValidation(). After the validation, each field in the form will display error message if it's invalid.

React to Validation Change

You can react to validation change using FormValidation.$allValid and FormValidation.$validationMessages

VStack {
} // parent view of the form
        .onReceive(formInfo.form.$allValid) { isValid in
            self.isSaveDisabled = !isValid
        }
        .onReceive(formInfo.form.$validationMessages) { messages in
            print(messages)
        }

🎉 Installation

Swift Package Manager

Xcode Projects

Select File -> Swift Packages -> Add Package Dependency and enter https://github.com/ShabanKamell/SwiftUIFormValidator.git.

Swift Package Manager Projects

You can add SwiftUIFormValidator as a package dependency in your Package.swift file:

let package = Package(
        //...
        dependencies: [
            .package(url: "https://github.com/ShabanKamell/SwiftUIFormValidator.git", .upToNextMajor(from: "0.14.0"))
        ]
        //...
)

From there, refer to SwiftUIFormValidator in target dependencies:

targets: [
    .target(
            name: "YourLibrary",
            dependencies: [
                .product(name: "FormValidator", package: "SwiftUIFormValidator"),
            ]
            //...
    ),
    // ...
]

Then simply import SwiftUIFormValidator wherever you’d like to use the library.

CocoaPods

Use the following entry in your Podfile:

pod 'SwiftUIFormValidator'

Then run pod install.

Accio

Accio is a dependency manager based on SwiftPM which can build frameworks for iOS/macOS/tvOS/watchOS. Therefore the integration steps of SwiftUIFormValidator are exactly the same as described above. Once your Package.swift file is configured, run accio update instead of swift package update.

Don't forget to add import FormValidator to use the framework.

Carthage

Carthage users can point to this repository and use generated SwiftUIFormValidator framework.

Make the following entry in your Cartfile:

github "ShabanKamell/SwiftUIFormValidator"

Then run carthage update.

If this is your first time using Carthage in the project, you'll need to go through some additional steps as explained over at Carthage.

Validators

Validator Description
NonEmptyValidator Validates if a string is empty or blank
EmailValidator Validates if the email is valid.
DateValidator Validates if a date falls within after & before dates.
PatternValidator Validates if a patten is matched.
InlineValidator Validates if a condition is valid.
PasswordValidator Validates if a password is valid.
PrefixValidator Validates if the text has a prefix.
SuffixValidator Validates if the text has a suffix.

Custom Validators

In easy steps, you can add a custom validator:

// 1
public class NonEmptyValidator: StringValidator {
    public var publisher: ValidationPublisher!
    public var subject: ValidationSubject = .init()
    public var onChanged: [OnValidationChange] = []

    public var errorMessage: StringProducerClosure = {
        ""
    }
    public var value: String = ""

    public func validate() -> Validation {
        if value.trimmingCharacters(in: .whitespaces).isEmpty {
            return .failure(message: errorMessage())
        }
        return .success
    }
}

// 2
extension Published.Publisher where Value == String {
    func nonEmptyValidator(
            form: FormValidation,
            errorMessage: @autoclosure @escaping StringProducerClosure = ""
    ) -> ValidationContainer {
        let validator = NonEmptyValidator()
        let message = errorMessage()
        return ValidationPublishers.create(
                form: form,
                validator: validator,
                for: self.eraseToAnyPublisher(),
                errorMessage: !message.isEmpty ? message : form.messages.required)
    }
}
  1. Implement FormValidator protocol.
  2. Add the validator logic in an extension to Published.Publisher.

Note

NonEmptyValidator is a built-in validator in the library.

Validation Messages

You can provide a validation message for every field by providing errorMessage

$firstName.nonEmptyValidator(form: form, errorMessage: "First name is not valid")

If you don't provide a message, a default one will be used for built-in providers. All default messages are located in DefaultValidationMessages class.

$firstName.nonEmptyValidator(form: form) // will use the default message

In this example, DefaultValidationMessages.required will be used.

Overriding Default Validation Messages

You can override the default validation messages by inheriting from DefaultValidationMessages

class ValidationMessages: DefaultValidationMessages {
    public override var required: String {
        "Required field"
    }
    // Override any message ...
}

Or if you need to override all the messages, you can implement ValidationMessagesProtocol.

And provide the messages to FormValidation

FormValidation(validationType: .immediate, messages: ValidationMessages())

Credit

Validation with SwiftUI & Combine

👏 Contribution

All Pull Requests (PRs) are welcome. Help us make this library better.

Changelog

Look at Changelog for release notes.

License

click to reveal License
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].