AssociatedObject
๐ Swift Macro for allowing variable declarations even in class extensions
Install / Use
/learn @p-x9/AssociatedObjectREADME
AssociatedObject
Swift Macro for allowing variable declarations even in class extensions.
It is implemented by wrapping objc_getAssociatedObject/objc_setAssociatedObject.
Installation
SPM
.package(url: "https://github.com/p-x9/AssociatedObject", from: "0.10.3")
CocoaPods
Add below to your Podfile.
pod 'AssociatedObject', git: 'https://github.com/p-x9/AssociatedObject', tag: '0.10.3'
After pod install, you can use this Macro in your project.
Additionally, if you encounter build error like Expansion of macro 'AssociatedObject' did not produce a non-observing accessor. You should check your project setting Build Settings-OTHER_SWIFT_FLAGS.
There should be additional flags like so.

If not, you can add these two lines by yourself.
-load-plugin-executable
${PODS_ROOT}/AssociatedObject/Binary/AssociatedObjectPlugin#AssociatedObjectPlugin
Usage
For example, you can add a new stored property to UIViewController by declaring the following
import AssociatedObject
extension UIViewController {
@AssociatedObject(.retain(nonatomic))
var text = "text"
/* OR */
@AssociatedObject(.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
var text = "text"
static var customKey = ""
@AssociatedObject(.OBJC_ASSOCIATION_RETAIN_NONATOMIC, key: customKey)
var somevar = "text"
}
Declared properties can be used as follows
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(text) // => "text"
text = "hello"
print(text) // => "hello"
}
}
willSet/didSet
Properties defined using @AssociatedObject can implement willSet and didSet.
In swift, it is not possible to implement willSet and didSet at the same time as setter, so they are expanded as follows.
@AssociatedObject(.copy(nonatomic))
public var hello: String = "ใใใซใกใฏ" {
didSet {
print("didSet")
}
willSet {
print("willSet: \(newValue)")
}
}
// โโโ expand to ... โโโ
public var hello: String = "ใใใซใกใฏ" {
get {
objc_getAssociatedObject(
self,
&Self.__associated_helloKey
) as? String
?? "ใใใซใกใฏ"
}
set {
let willSet: (String) -> Void = { [self] newValue in
print("willSet: \(newValue)")
}
willSet(newValue)
let oldValue = hello
objc_setAssociatedObject(
self,
&Self.__associated_helloKey,
newValue,
.copy(nonatomic)
)
let didSet: (String) -> Void = { [self] oldValue in
print("didSet")
}
didSet(oldValue)
}
}
License
AssociatedObject is released under the MIT License. See LICENSE
Related Skills
node-connect
341.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
341.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.4kCommit, push, and open a PR
