有没有办法在Objective-C中使用Swift结构而不使它们成为类?

时间:2017-06-30 11:41:12

标签: objective-c swift frameworks cross-platform

我有几个简单的structs用swift里面的.swift文件编写。 这些structs非常简单,几乎只包含字符串:

struct Letter {
   struct A {
      static let aSome : String = "descASome"
      static let aSomeMore : String = "descASomeMore"
   }
   struct B {
      static let bNow : String = "descBNow"
      static let bLater : String = "descBLater"
   }
...
}

我想在包含Objective-C代码的项目中使用那些结构,因为我正在编写一个跨平台框架。

我读过:ObjectiveC - Swift interoperability by Apple明确指出,ObjectiveC不能使用Swift编写的结构。 不包括(以及其他功能):

  

Swift中定义的结构

解决方案1:

我找到了一个SO解决方案,通过使用类来解决问题:

@objc class Letter : NSObject {
   @objc class A : NSObject {
      static let aSome : String = "descASome"
      static let aSomeMore : String = "descASomeMore"
   }
   @objc class B : NSObject {
      static let bNow : String = "descBNow"
      static let bLater : String = "descBLater"
   }
...
}

此解决方案有效,但我必须将所有结构重写为类。它们也不像结构(以及其他东西)那样轻量级。 此外,我觉得我倒退去解决问题。

Q1。在解决方案1旁边的ObjectiveC中是否还有其他方法可以使用Swift结构,这不适合我的项目/情况? (如果rawValue为Int,则可以使用枚举)

Q2。有没有办法使用#define SomeConst进行ObjectiveC访问,并使用Stift进行Swift访问:

#if macOS // if Swift?
#endif

2 个答案:

答案 0 :(得分:1)

如果不进行重写,你就无法做到这一点:从ObjC看不到Swift结构。

您需要编写一个ObjC可见的Swift类来公开值,这是Swift Foundation的“叠加”类型的反转。

一种选择是尽可能地遵循Swift代码的结构。请注意,不允许使用嵌套类,并且ObjC“overlay”必须具有与Swift结构不同的名称。这是不幸的,但不可能解决,因为这个Swift代码在原始结构所在的相同位置是可见的。

导入基金会

@objc class OCLetters : NSObject {
    static let A = _A.self
    static let B = _B.self
}

@objc class _A : NSObject {
    static let some = Letters.A.some
    static let someMore = Letters.A.someMore
}

@objc class _B : NSObject {
    static let now = Letters.B.now
    static let later = Letters.B.later
}

但是,如果要对ObjC代码中的值使用点表示法,则不起作用。这可能是一个错误,但.some中的OCLetters.A.some被视为结构成员引用,但失败了。 (将属性更改为计算类属性也不起作用。)您必须编写[[OCLetters A] some](或[OCLetters.A some])。

为了能够使用点表示法,您必须稍微更改结构,以便属性实际上是实例:

import Foundation

@objc class OCLetters : NSObject {
    static let A = _A()
    static let B = _B()
}

@objc class _A : NSObject {
    let some = Letters.A.some
    let someMore = Letters.A.someMore
}

@objc class _B : NSObject {
    let now = Letters.B.now
    let later = Letters.B.later
}

另请注意,遗憾的是,您无法限制助手_A_B类的ObjC中的可见性,因为如果它们不可见,则OCLetters的属性也不会

答案 1 :(得分:1)

截至目前,没有。 您将需要使用类来存储模型对象。

@objcMembers public class Car: NSObject {
    public var mileage: NSNumber?
}

@objcMember 实际上将它们转换为Objective-c可读格式,并且可以从Objective-C类进行访问。 这将使您的代码具有互操作性。

注意:确保类类型为 NSObject