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.
For IDFA collection first at all we checks NSClassFromString(@"ASIdentifierManager")
The problem is:
Imagine we have a client and this client released version for iOS10-iOS12.
And this client gets IDFA for iOS10 and iOS11, but for all iOS12 there is no IDFA at all! After logs checked we have found that NSClassFromString(@"ASIdentifierManager")
is nil only for iOS12..
How the client could add a framework for iOS10, 11 but not for iOS12?
On the other hand, another client is doing well with 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.
> 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.
Second, what's the difference between using NSClassFromString()
directly and calling [ASIdentifierManager sharedManager]
anywhere?
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"
, nothing will be found in result since you didn't use it.
For the latter one, try to grep the same symbol in the executable program, there it is.
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.
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.
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. 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.
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With