user6631314
user6631314

Reputation: 1976

Best way to represent Objective-C properties as optionals in Swift

I am working on a hybrid Objective-C/Swift project containing many legacy Objective-C NSObjects with properties.

In Objective-C, the values of the properties can be nil. However, when accessed from Swift, they are ingested as non-optional. I don't want to change the legacy Objective-C code as it is used throughout the project in many places.

What Swift code can I write to access the properties given that they may be nil? Here is a stripped down version of the code with two things I have tried:

Objective-C:

@interface myObject : NSObject

@property (nonatomic, retain) NSData * video;

Swift

//object with property is sent in Notification

if let latest = notification.userInfo?["incoming"] as? myObject {
    // Approach 1...compare to nil gives compiler warning
    let thevideo = latest.video 
    if theVideo != nil { //thows compiler warning Comparing non-optional value of type 'Data' to 'nil' always returns true
        //do something with video
    } else {
        //handle nil case
    }
          
    // Approach 2..treat it like optional gives compiler error 
    if let aVideo = latest.video {
        //compiler error: initializer for conditional binding must have Optional type, not 'Data'
            
        //Do something with the video if it exists
    } else {
        //handle nil case
    }

How can I check if the property is nil given that it is not an optional in Swift?

Upvotes: 0

Views: 99

Answers (1)

matt
matt

Reputation: 535890

The best way is HangarRash's way: you modify the headers in your Objective-C code to say that things that can be nil (what Swift would call an Optional) are nullable.

If you can't do that, you can use the following absolutely horrible approach. Suppose theVideo has arrived as a Data, but you know that it might in fact be nil. Then say

if let theVideo = theVideo as Any as? Optional<Data>, let theVideo {

Here you are casting theVideo up to an Any so that you can cast it down to anything it all, including what you suspect it to be, an Optional wrapping a Data. Now you can (and do) safely unwrap it.

I really can't recommend this trick, though. It's better to update the headers of your Objective-C code to be more friendly to Swift.

Upvotes: 0

Related Questions