es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Acceder a las clases de ObjC/C++ en una biblioteca estática de Swift

Estoy construyendo esta biblioteca estática en Swift: OxfordLibrary que en última instancia quiero distribuir utilizando XCFramework.

Tengo código en ObjC / C++ al que quiero acceder desde Swift.
Dado que no podemos usar un archivo de puente ObjC en bibliotecas estáticas (genera errores al crear XCFramework), estoy intentando utilizar archivos modulemap.

La idea es mantener la base de código en ObjC / C++ interna / privada a la biblioteca y solo exponer las API a través de Swift.

Entonces, creé lo siguiente:

/// ARCHIVO: module.modulemap

module OxfordLibrary {
    export *
}
/// ARCHIVO: module.private.modulemap

module OxfordLibrary_Private {
    umbrella header "OxfordLibrary-objc-umbrella.h"
    export *
}

He configurado Defines Module: YES y también he establecido la ruta de búsqueda de Swift en la configuración de compilación.

Ahora, en mi archivo principal de Swift:

/// ARCHIVO: OxfordLibrary.swift

import OxfordLibrary_Private

open OxfordLibrary{
    public static func foo() {
        SomeObjcClass.someObjcMehtod()    // Objetivo final
    }
}

Ahora, sin importar OxfordLibrary_Private, no puedo acceder a SomeObjcClass en Swift. Está bien. Después de agregar la importación, funciona.

Esto incluso se compila correctamente.

Pero cuando creo el XCFramework y lo importo al proyecto de la aplicación del cliente, si hago import OxfordLibrary, lanza un error OxfordLibrary_Private módulo no encontrado / no definido.

Después de investigar un poco, descubrí que necesito copiar los archivos modulemap y los encabezados al XCFramework, ya sea en la carpeta de Módulos o utilizando la opción -headers. Funciona si hago eso.

Pero la pregunta es: ¿Se supone que el archivo private.modulemap debería ser privado y no estar disponible fuera de la biblioteca?

Porque ahora puedo hacer import OxfordLibrary_Private en la aplicación del cliente y acceder a cualquier método de ObjC allí.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, el archivo module.private.modulemap está destinado a ser privado y no expuesto fuera de tu biblioteca. Al copiarlo en tu XCFramework o hacerlo disponible a través de la opción -headers, estás efectivamente haciéndolo público y permitiendo que los clientes de tu biblioteca accedan a los métodos de ObjC que se pretendían internos.

    En su lugar, debes considerar usar un solo archivo module.modulemap que exponga solo las API que deseas hacer públicas. En este archivo, puedes usar la directiva header para incluir los archivos de encabezado que contienen las API públicas. De esta manera, los clientes de tu biblioteca solo pueden acceder a las API que has expuesto explícitamente, y tu código privado de ObjC permanece oculto.

    Por ejemplo, tu archivo module.modulemap podría tener este aspecto:

    module OxfordLibrary {
    header "PublicHeader1.h"
    header "PublicHeader2.h"
    export *
    }

    Luego solo incluirías los archivos de encabezado públicos en el XCFramework, y los archivos de encabezado privados permanecerían internos a la biblioteca.

Comments are closed.