Можно ли использовать Objective-C код через Swift Package Manager (SPM)?

«Можно ли использовать Objective-C код через Swift Package Manager (SPM)?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, но с определенными условиями. Swift Package Manager изначально ориентирован на Swift, но поддерживает Objective-C через модули (modulemaps).

Основной способ — использование файла module.modulemap:

  1. Создайте структуру папок include/ в директории с исходным кодом (Sources/ИмяЦели).
  2. Поместите заголовочные файлы (.h) в include/.
  3. Создайте файл include/module.modulemap, который описывает модуль.

Пример структуры и кода:

MyObjCPackage/
├── Package.swift
└── Sources/
    └── MyObjCLib/
        ├── MyObjCLib.c
        └── include/
            ├── MyObjCLib.h
            └── module.modulemap

Содержимое module.modulemap:

module MyObjCLib {
    header "MyObjCLib.h"
    export *
}

Настройка в Package.swift:

let package = Package(
    name: "MyObjCPackage",
    targets: [
        .target(
            name: "MyObjCLib",
            publicHeadersPath: "include" // Указывает путь к заголовкам
        )
    ]
)

Ограничения и рекомендации:

  • SPM не поддерживает смешанные цели (файлы .m и .swift в одной цели). Цель должна быть либо чисто Swift, либо чисто C/Objective-C.
  • Для удобного использования Objective-C кода в Swift-проектах часто создают чистую Objective-C цель (как библиотеку) и затем зависимую от неё Swift-цель.
  • Альтернатива для сложных библиотек — дистрибуция в виде .xcframework, который SPM может использовать.