1. Safe Array Subscript:
Safely access array elements in an array without crashing on out-of-bounds indices.
extension Collection {
subscript(safe index: Index) -> Element? {
return startIndex <= index && index < endIndex ? self[index] : nil
// The same, but more performant than this >>>
// return indices.contains(index) ? self[index] : nil
}
}
// Usage:
let names = ["Alice", "Bob"]
let safeName: String = names[safe: 2] ?? "Unknown"
print("Safe name: \(safeName)") // "Safe name: Unknown" No crash
2. UIColor/NSColor from Hex:
Create colors from hex strings (e.g., #FF5733
) for easier design integration.
extension UIColor {
convenience init(hex: String) {
var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines)
hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")
// Handle different hex string formats
switch hexSanitized.count {
case 6: // RRGGBB
let r = CGFloat((rgb & 0xFF0000) >> 16) / 255
let g = CGFloat((rgb & 0x00FF00) >> 8) / 255
let b = CGFloat(rgb & 0x0000FF) / 255
self.init(red: r, green: g, blue: b, alpha: 1)
case 8: // RRGGBBAA
let r = CGFloat((rgb & 0xFF000000) >> 24) / 255
let g = CGFloat((rgb & 0x00FF0000) >> 16) / 255
let b = CGFloat((rgb & 0x0000FF00) >> 8) / 255
let a = CGFloat(rgb & 0x000000FF) / 255
self.init(red: r, green: g, blue: b, alpha: a)
default:
self.init(red: 0, green: 0, blue: 0, alpha: 1)
}
}
}
// Usage:
let backgroundColor: UIColor = UIColor(hex: "#FF5733")
3. String isNumeric:
Quickly check if a string represents a number.
extension String {
var isNumeric: Bool {
return Double(self) != nil
}
}
// Usage:
let input = "123.45"
if input.isNumeric {
print("Valid number") // ✅
}
4. UIView Corner Radius Shortcut:
Quickly round corners of views or make them circular.
extension UIView {
func round(_ radius: CGFloat? = nil) {
self.layer.cornerRadius = radius ?? self.frame.height / 2
self.layer.masksToBounds = true
}
}
// Usage:
let avatar = UIImageView()
avatar.round() // Make circle
5. Debounce function to Closures:
Throttle frequent calls like search inputs or typing events.
class Debouncer {
private var workItem: DispatchWorkItem?
private let queue: DispatchQueue
init(queue: DispatchQueue = .main) {
self.queue = queue
}
func call(delay: TimeInterval, action: @escaping () -> Void) {
workItem?.cancel()
workItem = DispatchWorkItem(block: action)
if let workItem = workItem {
queue.asyncAfter(deadline: .now() + delay, execute: workItem)
}
}
}
// Usage:
let debouncer = Debouncer()
debouncer.call(delay: 0.5) { // Useful for throttling user input
print("Search input processed")
}
6. Optional String Unwrapping Fallback:
Returns an empty string if optional is nil
— reduces optional handling clutter.
extension Optional where Wrapped == String {
var orEmpty: String {
return self ?? ""
}
}
// Usage:
let username: String? = nil
print("Hello, \(username.orEmpty)") // "Hello, "
7. Date to String Formatter:
Format Date
into a readable string with a custom format.
extension Date {
func formatted(_ format: String = "yyyy-MM-dd HH:mm") -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}
// Usage:
let timestamp = Date.now().formatted("MMM d, yyyy")
print(timestamp) // "Apr 13, 2025"
8. DispatchQueue Convenience:
Safely execute code on the main thread (without checking every time).
extension DispatchQueue {
static func mainAsync(_ execute: @escaping () -> Void) {
if Thread.isMainThread {
execute()
} else {
DispatchQueue.main.async { execute() }
}
}
}
// Usage:
DispatchQueue.mainAsync {
self.label.text = "Updated safely on main thread"
}
9. URL Percent Encoding:
Encode strings for safe use in URL
s (e.g., query parameters).
extension String {
var urlEncoded: String {
return addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? self
}
}
// Usage:
let query = "Hello World!"
let encoded = query.urlEncoded
print(encoded) // "Hello%20World%21"
10. UIImage Resize:
Resize images to a specific width while maintaining aspect ratio.
extension UIImage {
func resized(to width: CGFloat) -> UIImage? {
let scale = width / size.width
let height = size.height * scale
let newSize = CGSize(width: width, height: height)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
draw(in: CGRect(origin: .zero, size: newSize))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
// Usage:
if let resizedImage = image.resized(to: 100) {
imageView.image = resizedImage
}
11. Mutate Copy in One Line:
Like SwiftUI’s .modifier()
— configure objects in-line using with.
protocol Withable {}
extension Withable {
@discardableResult
func with(_ configure: (Self) -> Void) -> Self {
configure(self)
return self
}
}
// Make all NSObject subclasses conform to Withable
extension NSObject: Withable {}
// Usage:
let label = UILabel().with { $0.text = "Hello" }
12. UIEdgeInsets Convenience:
Quick constructors for edge insets.
extension UIEdgeInsets {
init(all: CGFloat) {
self.init(top: all, left: all, bottom: all, right: all)
}
init(vertical: CGFloat, horizontal: CGFloat) {
self.init(top: vertical, left: horizontal, bottom: vertical, right: horizontal)
}
}
// Usage:
let padding = UIEdgeInsets(all: 16)
let spacing = UIEdgeInsets(vertical: 8, horizontal: 20)
13. Top Most ViewController:
Fetch the top-most presented view controller, useful for presenting alerts.
extension UIApplication {
var topMostViewController: UIViewController? {
guard let keyWindow = UIApplication.shared.connectedScenes
.compactMap({ ($0 as? UIWindowScene)?.keyWindow })
.first else { return nil }
var topController = keyWindow.rootViewController
while let nav = topController as? UINavigationController {
topController = nav.visibleViewController
}
while let tab = topController as? UITabBarController {
topController = tab.selectedViewController
}
while let presented = topController?.presentedViewController {
topController = presented
}
return topController
}
}
// Usage:
if let topVC = UIApplication.shared.topMostViewController {
topVC.present(alert, animated: true)
}
14. Tap Gesture on Any UIView:
Easily add tap gestures with minimal boilerplate.
extension UIView {
func onTap(_ target: Any, _ selector: Selector) {
isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: target, action: selector)
addGestureRecognizer(tap)
}
}
// Usage:
myView.onTap(self, #selector(viewTapped))
@objc func viewTapped() {
print("View was tapped!")
}
15. Optional Binding Shortcut:
Assign a value only if the left-hand side is still nil.
infix operator ??=: AssignmentPrecedence
func ??=<T>(lhs: inout T?, rhs: @autoclosure () -> T?) {
if lhs == nil {
lhs = rhs()
}
}
// Usage:
var name: String?
name ??= "Guest"
print(name!) // "Guest"