CaptureContext/swift-foundation-extensions
Standard extensions for Foundation framework
Contents
Coding
- RawCodingKey allows you to create CodingKeys from literals
- Extensions for encoder and decoder allow you to create an object with a contextual container
- Extensions for coding containers automatically infer type from context
init(from decoder: Decoder) throws {
self = try container.decode(RawCodingKey.self) { container in
return .init(
someProperty1: container.decode("someProperty1"),
someProperty2: container.decode("some_property_2")
)
}
}
func encode(to encoder: encoder) throws {
try encoder.encode(RawCodingKey.self) { container in
try container.encode(someProperty1, forKey: "someProperty1")
try container.encode(someProperty2, forKey: "some_property_2")
}
}NSLocking
store(_:in:)- stores value in some variable in locked contextmutate(_:with:)- passes given object to locked contextassign(_:to:on:)- stores value in object property in locked contextexecute(_:)- provides new locked context
Optional
orThrow(_:)- unwraps an optional or throws specified errorisNil/isNotNil/isNilOrEmptyor()- coalesing aliasunwrap()- returns unwrapping Resultassign(to:on:)- assigns wrapped value to a specified target property by the keyPathifLetAssign(to:on:)- assigns wrapped value to a specified target property by the keyPath if an optional was not nil
Indirect
CoW container, which allows you to recursively include single instances of value types
struct ListNode<Value> {
var value: Value
@Indirect
var next: ListNode<Value>?
}PropertyProxy
class MyView: UIView {
private let label: UILabel
@PropertyProxy(\MyView.label.text)
var text: String?
@ReadonlyPropertyProxy(\MyView.label.text)
var readonlyText: String?
}
let view: MyView = .init()
view.label.text // ❌
view.text = "Hello, World!"Swizzling
This package also provides some sugar for objc method swizzling
[!NOTE]
The package is compatible with non-Apple platforms, however it uses conditional compilation, so
SwizzlingAPIs are only available on Apple platforms
extension UIViewController {
// Runs once in app lifetime
// Repeated calls do nothing
private static let swizzle: Void = {
// This example is not really representative since these methods
// can be simply globally overriden, but it's just an example
// for the readme and you can find live example at
// https://github.com/capturecontext/combine-cocoa-navigation
objc_exchangeImplementations(
#selector(viewWillAppear)
#selector(__swizzledViewWillAppear)
)
objc_exchangeImplementations(
#selector(viewDidAppear)
#selector(__swizzledViewDidAppear)
)
}()
@objc dynamic
private func __swizzledViewWillAppear(_ animated: Bool) {
__swizzledViewWillAppear(animated) // calls original method
print(type(of: self), ObjectIdentifier(self), "will appear")
}
@objc dynamic
private func __swizzledViewDidAppear(_ animated: Bool) {
__swizzledViewDidAppear(animated) // calls original method
print(type(of: self), ObjectIdentifier(self), "did appear")
}
}More
More extensions can be found in sources.
Equated
[!WARNING]
FoundationExtensionssimply exportsEquatedfor backwards compatibilityIt's likely to be removed in favor of a separate package swift-equated, see it's readme for more info
Undo/Redo management
[!WARNING]
FoundationExtensionssimply exportsResettablefor backwards compatibilityIt's likely to be removed in favor of a separate package swift-resettable, see it's readme for more info
Object Association
[!WARNING]
FoundationExtensionssimply exportsAssociatedObjects
FoundationExtensionsMacrossimply exportsAssociatedObjectsMacrosLikely to be removed in favor of a separate package swift-associated-objects
Installation
Basic
You can add swift-foundation-extensions to an Xcode project by adding it as a package dependency.
- From the File menu, select Swift Packages › Add Package Dependency…
- Enter
"https://github.com/capturecontext/swift-foundation-extensions"into the package repository URL text field - Choose products you need to link to your project.
Recommended
If you use SwiftPM for your project structure, add swift-foundation-extensions dependency to your package file
.package(
url: "https://github.com/capturecontext/swift-foundation-extensions.git",
.upToNextMinor("0.7.0")
)Do not forget about target dependencies
.product(
name: "<#Product#>",
package: "swift-foundation-extensions"
)License
This library is released under the MIT license. See LICENSE for details.
Package Metadata
Repository: CaptureContext/swift-foundation-extensions
Homepage: https://swiftpackageindex.com/CaptureContext/swift-foundation-extensions/0.4.2/documentation/foundationextensions
Stars: 19
Forks: 0
Open issues: 0
Default branch: main
Primary language: swift
License: MIT
Topics: associated-objects, associatedobject, async, coding, essentials, extensions, foundation, macros, runtime, spm, swift, swift-macro, swift-macros, swift-package-manager, swizzling, undo-redo
README: README.md