Swift - 当框架/模块具有相同名称的类时无法使用命名空间

tar*_*rma 6 namespaces module swift

环境:

Swift >=2.3,Swift 应用程序中的 Swift 框架

设置:

  • 一个带有模块名称的 Swift 动态框架,比如 APIService.framework.
  • 它有 apublic class APIService.swift并且具有静态功能。
  • 它有另一个public class Item.swift.

  • 一个快速的应用程序,使用 APIService.framework

  • 应用程序可以与框架一起使用 APIService.function()
  • 应用程序还有一个 class Item.swift

如果 App 需要引用框架的 Item 类,它必须这样做,APIService.Item但由于 APIService 是框架内的一个类,编译器总是尝试在 APIService 类中而不是在 APIService 模块中查找属性,因此会抛出一个错误说

'Item' is not a member type of 'APIService'
Run Code Online (Sandbox Code Playgroud)

可能的解决方案:

  • 将框架的模块名称更改为类名称以外的名称。
  • 将类名更改为模块名称以外的其他名称。
  • 在 APIService 类中放置一个“Item”静态属性,指向
    框架中的 Item 类。

所有这些都只是变通方法,真正的问题仍然是编译器无法区分模块名称和类名称。Swift 中有什么我可以说的"Don't look into the ModuleName.swift, instead look into the whole Module"吗?

iUr*_*rii 2

Swift 中符号名称冲突是一个老问题,因为编译器按以下优先顺序解析名称:

  1. 本地声明
  2. 进口报关
  3. 进口模块

您的应用程序的Item类名会覆盖从APIService模块导入的类名,并且APIService类名会覆盖您的情况下的模块名称,以便您无法再访问APIService.Item

唯一的解决方案是将框架导入到一个清晰的命名空间(模块)中,而不会发生冲突、类型别名,然后将其重新导入到您的应用程序中,为此,您可以创建一个包装框架并在 ie 中链接您的第三方库:

Your App-> Wrapper Framework(typealias)-> Target Framework

让我们的APIService框架有实现:

APIService.swift

public class APIService {
    public static func test() {
        print("APIService")
    }
}

public class Item {
    public static func test() {
        print("APIService.Item")
    }
}
Run Code Online (Sandbox Code Playgroud)

制作Dependencies框架,将其与APIService框架链接并添加此文件:

依赖项.swift

import APIService

public typealias APIService_Item = Item
Run Code Online (Sandbox Code Playgroud)

现在您可以将Dependencies框架链接到您的应用程序(APIService自动链接)并将库导入到您的代码中:

应用程序.swift

import Dependencies
import APIService

class Item {
    static func test() {
        print("App.Item")
    }
}

...

Item.test() // Prints: App.Item
APIService.test() // Prints: APIService
APIService_Item.test() // Prints: APIService.Item
Run Code Online (Sandbox Code Playgroud)

因此,正如您从测试中看到的那样,我们可以访问APIService.Item类。