ASIdentifierManager не найден в iOS12 - PullRequest
0 голосов
/ 14 ноября 2018

Я пишу здесь, потому что я действительно застрял и не могу найти ответ.

У нас есть небольшая структура, которая может собирать IDFA внутри. Для сбора IDFA сначала мы проверяем NSClassFromString(@"ASIdentifierManager")

Проблема:

Представьте, что у нас есть клиент, и этот клиент выпустил версию для iOS10-iOS12. И этот клиент получает IDFA для iOS10 и iOS11, но для всех iOS12 вообще нет IDFA! После проверки логов мы обнаружили, что NSClassFromString(@"ASIdentifierManager") это ноль только для iOS12 ..

Как клиент может добавить фреймворк для iOS10, 11, но не для iOS12?

С другой стороны, у другого клиента все в порядке с iOS12.

1 Ответ

0 голосов
/ 16 ноября 2018

Это может не полностью ответить на ваш вопрос, просто напишите то, что я знаю, и мое предположение.

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

> cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks
> # Now there are plenty of frameworks here.
> file  AdSupport.framework/AdSupport
Mach-O 64-bit dynamically linked shared library x86_64

Как использовать это?TLDR, назовите его с помощью [ASIdentifierManager sharedManager] в любом месте вашего приложения, сначала свяжите его с фреймворком и, конечно, скомпилируйте его успешно.

Второй , в чем разница между прямым использованием NSClassFromString() ивызывать [ASIdentifierManager sharedManager] где-нибудь?

В первом случае ваше приложение не будет загружать пакет AdSupport framework, так как в исполняемой программе нет символа с именем ASIdentifierManager, когда ядро ​​os загружает вашу программу,это можно проверить, напечатав путь к основному комплекту приложения и найдя исполняемый файл приложения, попробуйте nm <path/to/executable_app> | grep "ASIdentifierManager", в результате ничего не будет найдено, поскольку вы не использовали it.

В последнем случае попробуйте использовать grep для того же символа в исполняемой программе, вот он:

Примечание: ядро ​​не загружает рамки по списку результатов nm, а ядро ​​загружает рамкисодержащий символы, ознакомьтесь с дополнительной информацией о динамическом загрузчике dyld .

Третий , NSClassFromString проверяет только загруженные классы, если AdSupport фреймворк не загружается, он возвращает ноль, не пытаясь загрузить фреймворк, содержащий целевой класс.

Далее , невозможно вспомнить разницу между iOS 10/11 и iOS12, пока вы не вставите больше контекста об использовании IDFA и AdSupport framework в вашем проекте.Вот мое предположение, некоторые из зависимых библиотек используют AdSupport фреймворк в ранней версии, но iOS 12, вы должны попытаться сбросить список символов между в iOS 11 и iOS 12 и сравнитьрезультат.

Пятый , я не уверен, что вы хотите, может быть, вы пытаетесь избежать импорта структуры AdSupport явно, как насчет инициализации NSBundle путем платформы ивызовите -(BOOL)load класса NSBundle, тогда вы можете получить объект Class с NSClassFromString.

ОБНОВЛЕНИЕ:

NSString *strFrameworkPath = nil;

#if TARGET_OS_SIMULATOR
strFrameworkPath = [[NSProcessInfo processInfo] environment][@"DYLD_FALLBACK_FRAMEWORK_PATH"];
#else
// Assume that the AdSupport and Foundation framework are in the same directory.
strFrameworkPath = [NSBundle bundleForClass:NSPredicate.class].bundlePath;
strFrameworkPath = [strFrameworkPath stringByDeletingLastPathComponent];
#endif

strFrameworkPath = [strFrameworkPath stringByAppendingPathComponent:@"AdSupport.framework"];
NSAssert([[NSFileManager defaultManager] fileExistsAtPath:strFrameworkPath], @"Invalid framework bundle path!");

NSBundle *bundle = [NSBundle bundleWithPath:strFrameworkPath];

if (!bundle.isLoaded) {
    NSError *error = nil;

    if (![bundle loadAndReturnError:&error]) {
        DDLogError(@"Load framework bundle %@ with error %@", bundle, error);
    }
}

DDLogDebug(@"bundle: %@", bundle.bundlePath);
DDLogDebug(@"class: %@", NSClassFromString(@"ASIdentifierManager"));

Вам может потребоваться улучшить совместимость типов устройств для продуктов, для получения более подробной информации об использовании NSBundle ознакомьтесь с официальной документацией здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...