0

I am trying to access a Swift Extension to NSString from an objective-C class using the @objc prefix but can't access an optional.

Now that Swift 4.2 requires @objc before variables or functions called from Objective-C, to access the extension, I have to add the @objc extension.

While this works fine with non optionals--I use it extensively in my project, adding @objc to the following extension is giving the error:

I'm not sure but I think it may be because CLLocationCoordinate is an optional.

Can anyone see what is wrong with the code? Thanks for any suggestions.

If I don't put @objc in following, I can't access it from Objective-C. Error is: Property 'asLocationCoord' not found on object of type 'NSString
If I do put it in, Swift compiler complains 'Property cannot be marked @objc because its type cannot be represented in Objective-C'


public extension NSString {
  @objc public var asLocationCoord: CLLocationCoordinate2D? {
    var mylocation: CLLocationCoordinate2D? = nil
        let geoCoder = CLGeocoder()
        geoCoder.geocodeAddressString(self as String) { (placemarks, error) in
            guard
                let placemarks = placemarks,
                let firstlocation = placemarks.first?.location?.coordinate
                else {
                    // handle no location found
                    return
                    }
            mylocation = firstlocation
        }
        return mylocation
        }//end var
}//end extension
zztop
  • 701
  • 1
  • 7
  • 20
  • 1
    In Objective-C, you can't get an "optional" for a primitive or a struct => It can't be represented error. The only way I know, is to use an Object, either CLLocation (and wrap your CLLocationCoordinate2D inside it), or a NSValue (cf. https://stackoverflow.com/questions/5095333/nsmutablearray-of-cllocationcoordinate2d), the way we used in Objective-C to put CLLocationCoordinate2D into a NSArray which accepts only objects. – Larme May 12 '20 at 17:07
  • So you think I could pass back a CLLocation – zztop May 12 '20 at 17:18
  • 1
    Now that I see it, you know that `geoCoder.geocodeAddressString()` is async, right? – Larme May 12 '20 at 17:21
  • I wasn't sure if it is async. Can you do an extension with an async call. Couldn't find a simple answer to that? – zztop May 12 '20 at 17:34
  • It's in the doc: https://developer.apple.com/documentation/corelocation/clgeocoder/1423509-geocodeaddressstring `This method submits the specified location data to the geocoding server asynchronously and returns. Your completion handler block will be executed on the main thread.`. – Larme May 12 '20 at 17:35
  • So you can do it but it might tie up the main thread?. So I guess should just use a function... – zztop May 12 '20 at 17:35
  • Having gotten this to compile and run, the extension returns a value before the completion handler hears back from Apple's servers so it does not appear an extension works in this case. – zztop May 12 '20 at 18:35

0 Answers0