Как добавить структуру внутри другой структуры (Umbrella Framework)

Я построил структуру, используя следующее руководство.

И я также получил эту структуру.

Я пытаюсь реализовать вторую Framework внутри моей, из того, что я прочитал в документах Apple, результирующая структура называется "Umbrella Framework".

Я добавил вторую структуру в фреймворке с помощью перетаскивания и подтвердил, что она находится в "Link Binary With Libraries".

И после того, как я попытался сделать следующий импорт в одном из классов моей рамки:

#import <CrashReporter/CrashReporter.h>

Я получил сообщение об ошибке, поскольку импортированная структура не видна.

Также я видел сообщение stackoverflow: Как создать зонтичную структуру в SDK для iOS?

Update

Кто-нибудь пытался извлечь классы PLCrashReporter для iOS и интегрировать в проект?

Вы можете найти мою попытку здесь.

Ответ 1

Искушение распространять другую структуру понятно, но очень обескуражено. Я попытаюсь объяснить, почему это (с аргументами), а также предоставить некоторые отличные альтернативы, которые помогут в вашем случае.

Umbrella framework предназначены для использования, только когда вы являетесь дистрибьютором обеих фреймворков, у вас есть полный контроль над ними, и они будут распределены вместе.

Существует популярная цитата на эту тему от Apple, где они говорят, что они препятствуют созданию зонтичных фреймворков.

Не создавать рамки зонтика

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

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

Сообщите пользователю, что ваша инфраструктура требует использования другой сторонней структуры. В большинстве случаев это вполне стандартно и ожидается. Затем подключитесь к нему на системном уровне. Это так просто. Ваша инфраструктура найдет стороннюю функцию и функцию по-прежнему, как и с использованием встроенной среды. Возьмите UIKit, например. Чтобы связаться с третьим лицом, выполните действия, описанные в следующем разделе. Это, безусловно, можно сделать стандартным способом, но использование такого инструмента, как CocoaPods, упростит работу вашего проекта.

Чтобы полностью ответить на ваш вопрос, вместо обычного использования сторонней структуры, поскольку вы можете столкнуться с проблемами и сложностями, используйте CocoaPods, чтобы добавить его для вас. Таким образом, вы устраняете возможные проблемы, а также получаете дополнительное преимущество CocoaPods, получая вам точную версию третьей стороны, которая вам понадобится.

Вот подкаст CocoaPods для приложения под названием "CrashTest"

target 'CrashTest' do
pod 'PLCrashReporter', '~> 1.2.0'
end

Просто, чтобы уточнить, когда вы разрабатываете фреймворк, он все равно будет добавлен в ваш проект и будет видимым. Большая разница здесь в том, что он будет распространяться отдельно от вашей структуры, и конечным пользователям придется добавлять оба их проекта, чтобы они работали.

Вот почему это делается таким образом.

Например, вы хотели бы включить PLCrashReporter в свою структуру. Скажем, еще один разработчик фреймворка хочет включить его в свою. Приложение, использующее обе структуры, будет иметь PLCrashReporter, включенный дважды (как часть каждой зонтичной структуры). Возможны даже разные версии. Это может привести к серьезным проблемам внутри пользовательского приложения. Если обе структуры зонтика связаны с PLCrashReporter, как описано в предыдущем разделе, эта проблема будет полностью устранена.

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

Я знаю, что этот подход не дает прямого ответа на этот вопрос, но он пытается отказать в неудачной практике вместо этого, указывая на стандартный способ ведения дел.

Ответ 2

Apple отпугивает вас создать зонтичную структуру, но все же говорит, что возможно с некоторое описание по своей структуре и т.д., поэтому я буду сосредоточьтесь на том, как это сделать на самом деле.

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

Создание зонтичной структуры действительно просто сейчас на последних Xcodes (7 и выше)

Вот как это сделать.

Сначала создайте фреймворк:

введите описание изображения здесь

Перетащите CrashReporter.framework в проект рамки Umbrella:

введите описание изображения здесь

Пример кода, чтобы убедиться, что обе структуры функциональны:

Umbrella.h:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

@interface Umbrella : NSObject

+(void)sayHelloFromUmbrella;

@end

Umbrella.m:

#import "Umbrella.h"
#import <CrashReporter/CrashReporter.h>

@implementation Umbrella

+(void)sayHelloFromUmbrella
{
    NSLog(@"Hey from Umbrella");
    PLCrashReporter *crashObject = [[PLCrashReporter alloc]initWithConfiguration:nil];
    NSLog(@"crashObject: %@",crashObject);
}

@end

Создайте и вы получите Umbrella.framework (который содержит CrashReporter.framework) в вашей папке сборки.

Перетащите Umbrella.framework и поместите его внутри "Встроенных бинарных файлов" в проекте, который будет его использовать:

введите описание изображения здесь

Затем просто импортируйте готовые рамки.

ViewController.m из проекта, который мы просто перетащили Umbrella.framework в:

#import "ViewController.h"
#import <Umbrella/Umbrella.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [Umbrella sayHelloFromUmbrella];
}

Что выведет это:

Hey from Umbrella 
crashObject: <PLCrashReporter: 0x7fb441d5c650>

Что говорит нам, что обе структуры работают.

Ответ 3

Я пробовал делать то, что предложил @Segev, но я все время получал ошибку, которая отсутствовала в файлах встроенных фреймов.

Однако, выполняя некоторую дополнительную конфигурацию, мне удалось заставить ее работать!

Вот что я сделал:

  • Добавить встроенный файл заголовка фреймворка в проект рамки зонтика.
  • В заголовке зонтика добавьте: import "EmbeddedFramework.h"
  • Затем импортируйте структуру зонтика в желаемый проект, и вы не получите больше ошибок.

Вы увидите, что папка "Заголовки" зонтичной рамки будет содержать файл "EmbeddedFramework.h"

Здесь вы можете увидеть пример проекта:

Надеюсь, что это поможет