2

When using Swift 3, I was defining my model like so

class Model: NSObject {
    var prop1: String
} 

When I wanted to access the static string value of the property name prop1, I would use let sad = #keyPath(Model.prop1) and it would give me "prop1" printed out. Happy days.

The problem is, that since upgrading to Swift 4, I am having trouble doing the above. I see in other posts that we can use the new \Model.prop1 syntax but that seems to be providing the value of property rather than the string representation of the name.

I am also refactoring out the need for NSObject on my Swift models, but I would have thought I can still get this functionality.

Any help here would be appreciated!

Harry Bloom
  • 2,359
  • 25
  • 17

1 Answers1

3

Swift properties do not necessarily retain the strings of the property names at runtime. Therefore, if the Swift key path syntax were able to give you this string value, it would only be able to be used on NSObject-derived classes. The Swift key path syntax doesn't only work with those, though; it can also be used to refer to properties of non-@objc classes and structs. Therefore, this is not possible. The #keyPath syntax remains available, however, to get the string key path of an Objective-C property.

Charles Srstka
  • 16,665
  • 3
  • 34
  • 60
  • Did you mean "it *can't* be used to refer…" here? – Rob Napier Sep 21 '17 at 16:31
  • Okay that was wishful thinking of me. Thanks for the explanation Charles! – Harry Bloom Sep 21 '17 at 16:44
  • I'm also seeing a warning message: 'Argument of '#keyPath' refers to property 'method' in 'Model' that depends on '@objc' inference deprecated in Swift 4' Is that what you mean when you say the syntax is still available? – Harry Bloom Sep 21 '17 at 16:55
  • 1
    @RobNapier Nope! You can absolutely use Swift 4 key paths to refer to any property of anything, class or struct. – Charles Srstka Sep 21 '17 at 18:45
  • 1
    @HarryBloom In Swift 3, any method or property on an `NSObject` that was compatible with Objective-C would be automatically inferred to be `@objc`. This is not true anymore in Swift 4, and methods will only be exposed to Objective-C if you put the `@objc` keyword on them. Therefore, if you use features that require Objective-C support, such as `#selector` or `#keyPath`, the method you're passing needs to have `@objc` in its declaration. – Charles Srstka Sep 21 '17 at 18:46
  • @CharlesSrstka Thanks; I had to read it a couple of times, but yeah, you're totally right. I just didn't understand the sentence. – Rob Napier Sep 21 '17 at 19:49