Слабая связь в статической библиотеке iOS - PullRequest
0 голосов
/ 28 июня 2018

У нас есть статическая структура, которую мы создали, и она зависит от SDK, который мы используем для доступа к идентификаторам. Этот SDK вышел с новой версией, которая имеет новый интерфейс.

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

У меня есть протокол SDKProtocol, который реализуется двумя классами NewSDKServices и OldSDKServices.

NewSDKServices не скомпилируется, если не присутствует новый SDK, а OldSDKServices не скомпилируется, если не присутствует старый SDK. Я полагаю, что это нормально, так как это предварительно скомпилированный фреймворк, и мы можем решить во время выполнения, что использовать.

Тогда я бы хотел иметь возможность сделать что-то подобное, возможно, с ifdef для импорта и инициализации правильного сервиса.

if (useNewSDK) {
    _sdkService = [[NewSDKServices alloc] init];
} else {
    _sdkService = [[OldSDKServices alloc] init];
}

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

Оба SDK имеют несколько заголовков и .a.

1 Ответ

0 голосов
/ 28 июня 2018

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

if (useNewSDK) {
    _sdkService = [[NewSDKServices alloc] init];
} else {
    _sdkService = [[OldSDKServices alloc] init];
}

будет

#ifdef USE_SDK_NEW
    _sdkService = [[LinkedSDK alloc] init];
#else //USE_SDK_NEW
    _sdkService = [[LinkedSDK alloc] init];
#endif //USE_SDK_NEW 

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

Если используется слабое связывание, для доступа к содержимому обычно требуется NSClassFromString (...). Вам нужно будет определить доступность SDK, надеюсь, кто-то либо добавил информацию к статическим классам, таким как [NSClassFromString("TheSdk") performSelector: @"GetVersion"], либо использует знание, что другие классы существуют или не существуют. Если набор классов между двумя версиями одинаков, вы бы обратились к запросам селекторов или членов.

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

Если вы распространяете себя как модуль, вы можете создать две цели и использовать версию для дифференциации необходимого другого SDK.

...