我写这封信是因为我被困住了,找不到答案。
我们有一个小框架,可以收集内部的IDFA。对于IDFA集合,我们首先检查NSClassFromString(@"ASIdentifierManager")
问题是:
假设我们有一个客户端,这个客户端发布了iOS12 10-iOS12 12版本。这个客户端为iOS10和iOS11获取IDFA,但是对于所有的iOS12,根本就没有IDFA!经过日志检查,我们发现NSClassFromString(@"ASIdentifierManager")只适用于iOS12。
客户端如何为iOS10添加一个框架,而不是为iOS12添加一个框架?
另一方面,另一个客户端在iOS12方面做得很好。
发布于 2018-11-16 07:19:07
这可能不会完全回答你的问题,只是发短信,我知道和我的猜测。
First,在使用之前,动态框架不会加载到应用程序进程中,例如在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如何使用 it?当然,TLDR,在您的应用程序中使用[ASIdentifierManager sharedManager]调用它,首先根据框架链接并成功编译它。
第二次,直接使用NSClassFromString()与在任何地方调用[ASIdentifierManager sharedManager]有什么区别?
对于前一种情况,您的应用程序不会加载AdSupport框架包,因为在操作系统内核加载程序时,可执行程序中没有名为ASIdentifierManager的符号,可以通过打印应用程序主包路径和查找应用程序可执行文件来证明这一点,尝试使用nm <path/to/executable_app> | grep "ASIdentifierManager",结果不会发现任何符号,因为您没有使用它。
对于后者,尝试在可执行程序中使用相同的grep符号,它就在这里。
注意:不是os内核通过
nm结果列表加载框架,而是内核加载包含符号的框架,查看有关动态加载器迪尔德的更多信息。
Third,NSClassFromString只检查加载的类,如果AdSupport框架未加载,则返回零,而不尝试加载包含目标类的框架。
Forth,如果不粘贴更多关于项目中iOS和AdSupport框架使用情况的上下文,就不可能回忆起iOS 10/11和iOS 12中的不同之处。下面是我的一个猜测,一些依赖库在早期版本中使用 AdSupport框架,但是iOS 12,您必须尝试在iOS 11和iOS 12之间转储符号列表并比较结果。
第五,我不知道您想要什么,也许您试图避免显式导入AdSupport框架,不如通过框架路径初始化NSBundle并调用-(BOOL)load of NSBundle类,这样就可以使用NSClassFromString获得Class对象了。
更新:
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使用的更多细节,请参阅这里的官方文件。
https://stackoverflow.com/questions/53298053
复制相似问题