简体   繁体   English

在iOS12中找不到ASIdentifierManager

[英]ASIdentifierManager is not found in iOS12

I m writing here cos I'm really stuck and can't find an answer. 我写在这里因为我真的卡住了,找不到答案。

We have a small framework who can collect IDFA inside. 我们有一个可以在里面收集IDFA的小框架。 For IDFA collection first at all we checks NSClassFromString(@"ASIdentifierManager") 对于IDFA集合,我们首先检查NSClassFromString(@"ASIdentifierManager")

The problem is: 问题是:

Imagine we have a client and this client released version for iOS10-iOS12. 想象一下,我们有一个客户端和这个客户端发布的iOS10-iOS12版本。 And this client gets IDFA for iOS10 and iOS11, but for all iOS12 there is no IDFA at all! 此客户端获得iOS10和iOS11的IDFA,但对于所有iOS12,根本没有IDFA! After logs checked we have found that NSClassFromString(@"ASIdentifierManager") is nil only for iOS12.. 检查NSClassFromString(@"ASIdentifierManager")日志后,我们发现NSClassFromString(@"ASIdentifierManager")仅适用于iOS12 ..

How the client could add a framework for iOS10, 11 but not for iOS12? 客户端如何为iOS10,11而不是iOS12添加框架?

On the other hand, another client is doing well with iOS12. 另一方面,另一个客户端在iOS12上运行良好。

This may not answer your question completely, just text what I know and my guess. 这可能不会完全回答你的问题,只是发短信给我知道和猜测。

First , the dynamic frameworks won't be loaded in your app process until you use it, such as the frameworks under the directory which are available in iOS with simulator device. 首先 ,在您使用动态框架之前,动态框架将不会加载到您的应用程序进程中,例如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

How to use it? 怎么 TLDR, call it with [ASIdentifierManager sharedManager] in your app anywhere, link against the framework firstly and compile it successfully, of course. TLDR,在你的应用程序中随地用[ASIdentifierManager sharedManager]调用它,首先链接到框架并成功编译它,当然。

Second , what's the difference between using NSClassFromString() directly and calling [ASIdentifierManager sharedManager] anywhere? 第二 ,直接使用NSClassFromString()和在任何地方调用[ASIdentifierManager sharedManager]之间的区别是什么?

For the former case, your application won't load the AdSupport framework bundle since there are not symbol named ASIdentifierManager in your executable program when the os kernel loads your program, it can be proved by print your app main bundle path and find the app executable file, try to nm <path/to/executable_app> | grep "ASIdentifierManager" 对于前一种情况,您的应用程序将不会加载AdSupport框架包,因为当OS内核加载您的程序时,您的可执行程序中没有名为ASIdentifierManager符号,可以通过打印您的应用程序主程序包路径并查找应用程序可执行文件来证明文件,尝试nm <path/to/executable_app> | grep "ASIdentifierManager" nm <path/to/executable_app> | grep "ASIdentifierManager" , nothing will be found in result since you didn't use it. nm <path/to/executable_app> | grep "ASIdentifierManager" ,因为你没有使用它,所以在结果中找不到任何东西。

For the latter one, try to grep the same symbol in the executable program, there it is. 对于后者,尝试在可执行程序中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 . 注意:它不是os内核通过nm结果列表加载框架,但内核加载包含符号的框架,查看有关动态加载器dyld的更多信息。

Third , NSClassFromString only checks the loaded classes, if the AdSupport framework doesn't be loaded, it returns nil without trying to load the framework containing the target class. 第三NSClassFromString只检查加载的类,如果没有加载AdSupport框架,它返回nil而不试图加载包含目标类的框架。

Forth , it's impossible to recall the difference between in iOS 10/11 and iOS 12 until you paste out more context about the IDFA and AdSupport framework usage in your project. 第四 ,在你粘贴关于项目中IDFA和AdSupport框架使用的更多背景之前,不可能回想起iOS 10/11和iOS 12之间的区别。 Here is my one guess, some of the dependent libraries use the AdSupport framework in the early version but iOS 12, you have to try to dump the symbol list between in iOS 11 and iOS 12 and compare the result. 这是我的猜测,一些依赖库在早期版本中使用 AdSupport框架但是iOS 12,你必须尝试在iOS 11和iOS 12之间转储符号列表并比较结果。

Fifth , I'm not sure what you want, maybe you're trying to avoid importing AdSupport framework explicitly, how about initializing a NSBundle by framework path and call the -(BOOL)load of NSBundle class, then you could get the Class object with NSClassFromString . 第五 ,我不确定你想要什么,也许你试图避免显式导入AdSupport框架,如何通过框架路径初始化NSBundle并调用NSBundle类的-(BOOL)load ,然后你可以得到Class对象使用NSClassFromString

UPDATE: 更新:

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"));

You may need to enhance the compatibility of kinds of the device for products, for more details about the NSBundle usage, check out the official documentation here . 您可能需要增强产品的各种设备的兼容性,有关NSBundle使用的更多详细信息,请查看此处的官方文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM