I have the following form that creates a new "activity":
For which I want to enforce the following requirements:
- Name => minimum # of chars: 1; maximum # of chars: 50
- Description => maximum # of chars: 200
I have written the following code:
// ActivityDetailViewController.swift
import UIKit
private struct Constants {
static let activityNameMaxCharacters = 50
static let activityDescriptionMaxCharacters = 200
}
final class ActivityDetailViewController: NiblessViewController {
/* ... */
// This method is called when user taps on the "Add" bar button item
// from the navigation bar.
@objc
func save(_ sender: UIBarButtonItem) {
do {
try validateInputs()
activity.name = nameField.text ?? ""
activity.activityDescription = descriptionTextView.text
presentingViewController?.dismiss(animated: true, completion: onDismiss)
} catch let error as ErrorMessage {
present(errorMessage: error)
} catch {
// NO-OP
}
}
/* ... */
// This methods applies the input validation rules.
private func validateInputs() throws {
guard let activityName = nameField.text else {
let errorMessage = ErrorMessage(
title: "Activity Creation Error",
message: "Activity name can't be empty."
)
throw errorMessage
}
let activityDescription = descriptionTextView.text ?? ""
if activityName.count > Constants.activityNameMaxCharacters {
let errorMessage = ErrorMessage(
title: "Activity Creation Error",
message: "Activity name exceeds max characters (50)."
)
throw errorMessage
} else if activityDescription.count > Constants.activityDescriptionMaxCharacters {
let errorMessage = ErrorMessage(
title: "Activity Creation Error",
message: "Activity description exceeds max characters (200)."
)
throw errorMessage
}
}
}
Some supporting code:
// ErrorMessage.swift
import Foundation
public struct ErrorMessage: Error {
// MARK: - Properties
public let id: UUID
public let title: String
public let message: String
// MARK: - Methods
public init(title: String, message: String) {
self.id = UUID()
self.title = title
self.message = message
}
}
extension ErrorMessage: Equatable {
public static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.id == rhs.id
}
}
// UIViewController+ErrorPresentation.swift
import UIKit
extension UIViewController {
public func present(errorMessage: ErrorMessage) {
let errorAlertController = UIAlertController(
title: errorMessage.title,
message: errorMessage.message,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: "OK", style: .default)
errorAlertController.addAction(okAction)
present(errorAlertController, animated: true, completion: nil)
}
}
I'd appreciate any feedback on how to improve the current solution.
Things I don't like:
- Having to add an empty
catch
at the end of the try-catch clause located in thesave(_:)
method. Otherwise the compiler complains with: "Errors thrown from here are not handled because the enclosing catch is not exhaustive."