Разделение компонентов приложения Swift на модули Swift

Я пишу iOS-приложение на Swift и пытаюсь понять, как организовать проект в отдельные модули. Я использую архитектуру MVVM и хочу сделать компоненты Model, ViewModel и View отдельными модулями Swift, которые делают только свои подмножества доступными для модулей, которые их импортируют. Файлы в представлении будут импортировать ViewModel, а файлы в ViewModel будут импортировать модель. Как я могу это сделать? Обратите внимание, что я не пытаюсь создавать библиотеки, которыми могут пользоваться несколько приложений. Я просто пытаюсь обеспечить разделение компонентов с помощью модулей.

РЕДАКТИРОВАТЬ: Может быть, вопрос в том, «Какой механизм я должен использовать для создания модулей, кроме того, который поставляется с первоначальным проектом приложения iOS?»

Один из ответов в разделе «Как вы используете пространства имен в Swift?» https://stackoverflow.com/a/24032860/215400 говорит: "классы (и т. д.) неявно определяются модулем (цель Xcode), в которой они находятся». Из этого можно сделать вывод, что цели соответствуют модулям и что ответ заключается в создании отдельных целей в рамках проекта Xcode, но я пробовал это раньше, и tskulbru говорит, что мне нужно несколько проектов Xcode.

Что касается нескольких проектов Xcode, параметр «Файл»> «Создать»> «Проект»> «iOS Framework & Library»> «Cocoa Touch Framework» выглядит неправильно, потому что он предназначен для вещей, использующих UIKit, и два модуля, которые я хочу создать, не должны зависеть на УИКит. Другая опция «Структура и библиотека», статическая библиотека Cocoa Touch, не подходит для Swift.

В другом сообщении StackOverflow упоминается использование частных модулей. Поработав над этим час, я пришел к выводу, что это неправильное решение, потому что мне не нужно редактировать эти модули в разных рабочих пространствах.


person Christopher Simmons    schedule 01.01.2016    source источник
comment
Возможный дубликат Как вы используете пространства имен в Swift?   -  person tskulbru    schedule 01.01.2016
comment
Почему бы не использовать квалификатор private для принудительной инкапсуляции?   -  person Marc Khadpe    schedule 01.01.2016
comment
@Marc - Спасибо, но делать вещи приватными для файлов, в которых они определены, - это не то, чего я хочу. Публичный и внутренний доступ, предоставляемый модулями (developer. apple.com/library/ios/documentation/Swift/Conceptual/) — это именно то, что мне нужно.   -  person Christopher Simmons    schedule 02.01.2016
comment
@ChristopherSimmons Название «Cocoa Touch Framework» вводит в заблуждение и, вероятно, было выбрано Apple из соображений конкурентоспособности. На самом деле, это должно называться «Darwin Framework» или что-то подобное. То, что на самом деле создает «Cocoa Touch Framework», — это динамическая разделяемая библиотека, упакованная в ….framework — она может зависеть от UIKit, AppKit, Foundation, CoreFoundation или любых других фреймворков или даже не иметь зависимостей (зависит только от std/system). C API). Чтобы это не зависело от UIKit, зайдите в настройки проекта и замените UIKit.framework в Linked Frameworks на Foundation.framework.   -  person Slipp D. Thompson    schedule 13.02.2017


Ответы (2)


Это невозможно без создания отдельных проектов для модулей, которые вы хотите создать. Это связано с тем, как Swift обрабатывает пространство имен.

Эонил ответил на это лучше меня: https://stackoverflow.com/a/24032860/215400 (скопируйте ниже)

Ответ пользователя SevenTenEleven на форуме разработчиков Apple:

Пространства имен не относятся к файлам; они предназначены для каждой цели (на основе настройки сборки «Имя модуля продукта»). Таким образом, вы получите что-то вроде этого:

import FrameworkA
import FrameworkB

FrameworkA.foo()

Все объявления Swift считаются частью какого-то модуля, поэтому, даже когда вы говорите «NSLog» (да, он все еще существует), вы получаете то, что Swift считает «Foundation.NSLog».

Также Крис Латтнер написал в Твиттере о пространстве имен.

Пространство имен неявно в Swift, все классы (и т. д.) неявно ограничены модулем (целью Xcode), в котором они находятся. Префиксы классов не требуются.

person tskulbru    schedule 01.01.2016
comment
Если вы копируете основные части из другого ответа, добавьте ссылку на оригинал для правильной атрибуции: stackoverflow.com/a/24032860/1187415< /а>. - person Martin R; 01.01.2016
comment
Хех, я действительно думаю, что твой ответ ближе к тому, что я ищу, tskulbru. Если мне нужно создать отдельные проекты, как мне это сделать? Должен ли я выбрать вариант Cocoa Touch Framework, несмотря на то, что мне не нужен UIKit? Кажется, что Cocoa Touch Static Library будет иметь больше смысла, но это не вариант со Swift. Как упоминалось выше, я начал идти по пути частного пода, но это выглядело не слишком хорошо. - person Christopher Simmons; 02.01.2016

С моей точки зрения, если вы хотите инкапсулировать свои компоненты, возможно, у вас есть два решения:

  • Рамки
  • Внутренние какаоподы

Оба решения предоставят вам полностью инкапсулированные модули, где вы можете определить API, который будет доступен в проекте с помощью ключевого слова public. Все остальное не будет видно в вашем основном проекте.

Управление вашим проектом будет стоить вам гораздо больше времени, но если вы напишете это, используя принципы SOLID, вероятно, вы получите больше кода, который можно использовать повторно, и эти фреймворки можно будет импортировать в другой проект, просто используя определение import.

person user3292998    schedule 01.11.2016