Date
Jul. 14th, 2024
 
2024年 6月 9日

Post: iOS: Easy cast with _ObjectiveCBridgeable

iOS: Easy cast with _ObjectiveCBridgeable

Published 12:07 Jul 12, 2016.

Created by @ezra. Categorized in #Programming, and tagged as #iOS.

Source format: Markdown

Table of Content

Swift is out there for about a year and it’s a great programming language. I think that almost every iOS/OSX developer out there has already written couple of things in Swift (if you haven’t, go ahead and try, you won’t regret it, I promise). Although, we have many years of libs and frameworks built using Objective-C and sooner or later a project may have both Swift and Objective-C working together.

Fortunately, Apple gave us a book and a couple of WWDC session (here and here) with the intent to help developers on this task.

For those who have some experience with this integration knows that casting plays an important role. So, todays hint will dig into an poor documented protocol called _ObjectiveCBridgeable.

The documentation, which is only founded in header files says:

A Swift Array or Dictionary of types conforming to ObjectiveCBridgeable can be passed to Objective-C as an NSArray or NSDictionary, respectively. The elements of the resulting NSArray or NSDictionary will be the result of calling bridgeToObjectiveC on each element of the source container.

Ok, but there is something else you can do with that, which is very handy.

Suppose that you have this class in Objective-C:

@interface OPerson: NSObject

- (instancetype)initWithName:(NSString *)name surname:(NSString *)surname;

@property (nonatomic, copy) (NSString *)name;
@property (nonatomic, copy) (NSString *)surname;

@end

Now you want to easily cast this class into a Swift struct. Yes, we can! All you have to do is conform to _ObjectiveCBridgeable, like so:

struct Person {
        let name: String
        let surname: String
}

extension Person: _ObjectiveCBridgeable {

    typealias _ObjectiveCType = OPerson

    static func _isBridgedToObjectiveC() -> Bool {
            return type
    }

    static func _getObjectiveCType() -> Any.Type {
            return ObjectiveCType.self
    }

    func _bridgeToObjectiveC() -> _ObjectiveCType {
            return OPerson(name: name, surname: surname)
    }

    static func _forceBridgeFromObjectiveC(source: _ObjectiveCType, inout result: Person?) {
            result = Person(name: source.name, surname: source.name)
    }

    static func _conditionallyBridgeFRomObjectiveC(source: _ObjectiveCType, inout result: Person?) -> Bool {
            _forceBridgeFromObjectiveC(source, result: &result)
            return true
    }
}

And voilá!

let objcPerson = OPerson(name: "John", surname: "Doe")

if let swiftPerson = objcPerson as? Person {
  //will work
}

let swiftPerson = objcPerson as Person //this too!

let swiftPerson2 = Person(name: "Jack", surname:"Doe")
let objcPerson = swiftPerson2 as OPerson //and that

let person: OPerson = Person(name: "Alfred", surname: "Doe") //hooray

That’s so beautiful, don’t you think? :]

Pinned Message
HOTODOGO
I'm looking for a SOFTWARE PROJECT DIRECTOR / SOFTWARE R&D DIRECTOR position in a fresh and dynamic company. I would like to gain the right experience and extend my skills while working in great teams and big projects.
Feel free to contact me.
For more information, please view online résumé or download PDF
本人正在寻求任职 软件项目经理 / 软件技术经理 岗位的机会, 希望加⼊某个新鲜⽽充满活⼒的公司。
如有意向请随时 与我联系
更多信息请 查阅在线简历下载 PDF