7

I'm attempting to compile the following Swift class:

class Waypoint: NSObject {
    dynamic var coordinate: CLLocationCoordinate2D?
}

But I get the following compiler error:

Property cannot be marked dynamic because its type cannot be represented in Objective-C

If I change coordinate to be non-optional everything works just fine. I suppose this makes sense, since Objective-C has no concept of optionals. Is there any known solution or workaround?

bloudermilk
  • 17,820
  • 15
  • 68
  • 98
  • I'm not sure what you are trying to do. You probably want an observer on that property ? For what purpose (just to know when the property changed) ? _Maybe I'll be able to suggest you an alternative._ – lchamp Mar 13 '15 at 08:39
  • @lchamp correct, I want an observer for integration with ReactiveCocoa – bloudermilk Mar 13 '15 at 09:49

1 Answers1

13

In Objective-C, you can use nil to signal the absence of value, but only on object types. Swift generalizes this (and makes it type-safe) with the Optional generic type: you can have an Optional<NSObject>, a.k.a. NSObject?, but you can also have an Int? or a CLLocationCoordinate2D?.

But CLLocationCoordinate2D is a struct — if you use it in Objective-C, you can't assign nil to a variable of type CLLocationCoordinate2D. This is why you get this error.

As for an (ugly) workaround, you could wrap CLLocationCoordinate2D in a object:

class CLLocationCoordinate2DObj: NSObject {
    let val: CLLocationCoordinate2D
    init(_ val: CLLocationCoordinate2D) {
        self.val = val
    }
}

class Waypoint: NSObject {
    dynamic var coordinate: CLLocationCoordinate2DObj?
}

Unfortunately, you can't find a more general solution with a generic object wrapper class for structs, as Objective-C doesn't have generics… An alternative would be to use NSValue as object type as described here, but I doubt that it would be more elegant.

Community
  • 1
  • 1
Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234
  • Thanks for the quick answer. I think I'll create my own `Coordinate` class as you recommend and give it a `toCLLocationCoordinate2D` method unless there's a more elegant way to support typecasting it like: `coordinate as CLLocationCoordinate2D` – bloudermilk Mar 13 '15 at 09:54