Swift framework nested classes are not exported we

2020-06-03 01:19发布

问题:

I have the following classes contained by Geography.framework (a Swift framework project):

public class Contact : NSObject
{
    public static let  Table: String = "contacts"

    public class Fields : NSObject
    {
        public static let  Id: String = "_id"
        public static let  Name: String = "name"
        static let  rawId: String = "rawId"
    }
}


public class Country : NSObject
{
    public class Fields : NSObject
    {
        public static let  Id: String  = "_id"
        public static let  Prefix: String = "prefix"
        static let  rawId: String  = "rawId"
    }
}

In my swift app using this framework everything works smoothly:

import geography

func setFields()
{
    var contactName:String = Contact.Fields.Name
    var countryPrefix:String = Country.Fields.Prefix
    var contactsTable: String  = Country.Table
}

Well, if I use the same Geography.framework in ObjectiveC, I see Contact and Country class but the nested classes Fields are not seen. Also the value of Contact.Table is not seen.

What I need to do in order to have same library structure and library usage in ObjectiveC?

Thank you,

回答1:

You have to be explicit here with definition for ObjC.

public class Country: NSObject {

    @objc(CountryFields) public class Fields: NSObject {
        // ...
    }
}

This should expose your Switf's Country.Fields for your ObjC as CountryFields. I haven't tested it but I believe you don't have to be explicit about inheriting from NSObject. @objc attribute should do it for you when compiling.

Update for Swift 3:

Looks like this was broken in Swift 3 and won't be fixed. https://bugs.swift.org/browse/SR-2267?focusedCommentId=21033&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-21033



回答2:

You can use a trick with typealias to have the same syntax when using it :

public class Contact : NSObject
{
    public static let  Table: String = "contacts"

    typealias Fields = ContactFields
}

@objcMembers
public class ContactFields : NSObject
{
    public static let  Id: String = "_id"
    public static let  Name: String = "name"
    static let  rawId: String = "rawId"
}

public class Country : NSObject
{
    typealias Fields = CountryFields
}

@objcMembers
public class CountryFields : NSObject
{
    public static let  Id: String  = "_id"
    public static let  Prefix: String = "prefix"
    static let  rawId: String  = "rawId"
}