Pheepster
Pheepster

Reputation: 6347

Confusion about adopting Objective-C protocols in Swift

I am relatively new to Swift but am experienced in Objective-C.

I am in the beginning stages of integrating Swift into an existing Objective-C based app. I have written a class in Swift to mimic the behavior of one of our existing classes. In the new Swift class I implemented a protocol written in Obj-C.

In the protocol there is a required method defined as follows:

-(NSString*)getWName;

In my Swift class I have implemented it as follows:

func getWName() -> String! {
    return "some string"
}

The method signature is what XCode code completion produced. So here's my question: in Swift String is not an object, but NSString is. If I replace the return type of this method with NSString rather than String, my Swift class no longer conforms to the protocol and I get an error.

As I said, I'm fairly new to Swift and am trying to wrap my head around some of these concepts. Can anyone clarify this?

Upvotes: 3

Views: 321

Answers (1)

Jiri Trecak
Jiri Trecak

Reputation: 5122

Basic objects in Obj-C have their counterpart in Swift as well. Those are seamlessly bridged between each other. From Apple docs for String:

Swift automatically bridges between the String type and the NSString class. This means that anywhere you use an NSString object, you can use a Swift String type instead and gain the benefits of both the String type’s interpolation and Swift-designed APIs, as well as the NSString class’s broad functionality. For this reason, you should almost never need to use the NSString class directly in your own code. In fact, when Swift imports Objective-C APIs, it replaces all of the NSString types with String types. When your Objective-C code uses a Swift class, the importer replaces all of the String types with NSString in imported API.

Now to answer your question about why it actually does not work, read one paragraph more:

To enable string bridging, just import Foundation. For example, you can access capitalizedString—a property on the NSString class—on a Swift string, and Swift automatically bridges the Swift String to an NSString object and accesses the property. The property even returns a Swift String type, because it was converted during import.

The main problem there is that during the import, it actually internally changes that data type and so definition changes from -> NSString to String. Analyzer then thinks that you have data type mismatch.

Usually, there is no advantage to use old data types. I used NSString for some time because in earlier version of swift there were problems with character-based operations on String object, but right now that is all resolved.

If you really need to use it, you can just force type-cast it:

let myNSString = myString as! NSString

You can read more about data types here. Hope it helps!

Upvotes: 4

Related Questions