在 iOS12 中找不到 ASIdentifierManager

ASIdentifierManager is not found in iOS12

我写在这里是因为我真的被困住了,找不到答案。

我们有一个可以在里面收集IDFA的小框架。 对于 IDFA 集合,我们首先检查 NSClassFromString(@"ASIdentifierManager")

问题是:

假设我们有一个客户端,这个客户端发布了 iOS10-iOS12 的版本。 并且此客户端获得 iOS10 和 iOS11 的 IDFA,但对于所有 iOS12 根本没有 IDFA!检查日志后,我们发现 NSClassFromString(@"ASIdentifierManager") 仅对 iOS12..

为零

客户如何为 iOS10、11 添加框架而不为 iOS12 添加框架?

另一方面,另一个客户 iOS12 表现良好。

这可能无法完全回答您的问题,请将我所知道的和我的猜测发短信给您。

首先,在你使用之前,动态框架不会加载到你的应用程序进程中,例如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] 调用它,首先针对框架 link 并成功编译它。

其次,直接使用NSClassFromString()和在任何地方调用[ASIdentifierManager sharedManager]有什么区别?

对于前一种情况,您的应用程序不会加载 AdSupport 框架包,因为当 os 内核加载您的程序时,您的可执行程序中没有名为 ASIdentifierManager 的符号,可以通过打印你的应用程序主包路径并找到应用程序可执行文件来证明,尝试nm <path/to/executable_app> | grep "ASIdentifierManager",因为你没有使用,所以不会在结果中找到任何东西.

对于后一种,尝试在可执行程序中grep相同的符号,就是这样。

Note: it's not os kernel loads the frameworks by nm result list but the kernel loads the frameworks containing the symbols, check out more info about the dynamic loader dyld.

第三,NSClassFromString只检查加载的classes,如果AdSupport框架没有加载,它returns nil 没有尝试加载包含目标的框架 class.

Forth,很难os记住iOS 10/11 和iOS 12 之间的区别,直到你粘贴出来有关项目中 IDFA 和 AdSupport 框架使用情况的更多背景信息。这是我的一个猜测,一些依赖库使用早期版本的AdSupport框架但是iOS12,你必须尝试转储符号列表在 iOS 11 和 iOS 12 之间比较结果。

Fifth,我不确定你想要什么,也许你试图避免显式导入 AdSupport 框架,如何初始化一个 NSBundle通过框架路径调用NSBundleclass的-(BOOL)load,就可以得到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使用的更多详细信息,请查看the official documentation here