简体   繁体   中英

How to pass a Swift struct as a parameter to an Objective-C method

I have an Objective-C method that accepts a parameter of type id and I want to pass it a Swift struct.

ObjcClass.m file:

@implementation ObjcClass
+ (void)addListener:(id)listener {
    // Do something with listener
}

DemoStruct.swift file:

struct DemoStruct {
    func registerAsListener() {
        ObjcClass.addListener(self) // Can't find a way to do this
    }
}

The compile error message I get:

Type 'DemoStruct' does not conform to protocol 'AnyObject'

So my question would be, how do I make an Objective-C method accept Any instead of AnyObject and is there such a thing?

You can't do it.

Swift structs are not accessible from Objective-C. This is stated in the "Using Swift With Cocoa and Objective-C" book from Apple:

You'll have access to anything within a class or protocol that's marked with the @objc attribute as long as it's compatible with Objective-C. This excludes Swift-only features such as those listed here:

  • Generics
  • Tuples
  • Enumerations defined in Swift
  • Structures defined in Swift
  • Top-level functions defined in Swift
  • Global variables defined in Swift
  • Typealiases defined in Swift
  • Swift-style variadics
  • Nested types
  • Curried functions

Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C.” iBooks. https://itun.es/gb/1u3-0.l

The best thing i found was to wrap in a Box class

public class Box<T> {
    let unbox: T
    init(_ value: T) {
        self.unbox = value
    } }

Complementing Edward Ashak's answer we can use the following extensions. So somewhere in the Objective-C part a container property can be declared:

// An object that holds our Swift struct instance:
@property (nonatomic, strong) NSObject* pocObject;

In the Swift part we declare struct itself and a bunch of helpers:

// The struct we are boxing inside pocObject:
struct POCWithCheck: Decodable {
 ...
}

@objc class POCWithCheckBox: NSObject {
  let unbox: POCWithCheck
    init(_ value: POCWithCheck) {
      self.unbox = value
    }
}

extension POCWithCheck {
  func asNSObject() -> NSObject {
    return POCWithCheckBox(self)
  }
}

extension NSObject {
  func asPOCWithCheck() -> POCWithCheck? {
    return (self as? POCWithCheckBox)?.unbox
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM