Hi,
since the advertisingIdentifier of the ASIdentifierManager seems to be incorrectly annotated and therefore causes a crash when accessing the uuidString on Swift (if advertisingIdentifier is nil -
SR-6143), my question is whether it's safe to do the following for now and future versions of Swift:
guard let advertisingIdentifier = ASIdentifierManager.shared().advertisingIdentifier as UUID? else {
return "00000000-0000-0000-0000-000000000000"
}
or is it safer to make an objective c wrapper with a nullable annotation?
4 Likes
jrose
(Jordan Rose)
2
You should make the Objective-C wrapper (and sorry on behalf of the AS framework team).
The compiler had a workaround for incorrect nonnulls, but it only works with reference types (i.e. methods where the return type is the same as it is in Objective-C). So you'll need to use the wrapper function this time.
1 Like
fabb
(Fabian)
3
Thanks Jordan. I have created a Radar, maybe you could push this a little? It's just a single word after all, and would perfectly fit into the iOS 12 strategy of stability as a main focus. Feedback Assistant
Jon_Shier
(Jon Shier)
5
We’ve seen a similar but different problem in Alamofire where the Data passed by the URLSession delegate method is occasionally nil from the Objective-C side but is being bridged as a non-optional and so crashing in the bridge code. Making the delegate method take a Data? works but causes a permanent compiler warning. I imaging dropping to Objective-C could work but causes issues for a potential Linux port. Any better ideas for a workaround or something?
@jrose
You know whether this is a valid work-around for getting the uuidString?
let optionalIdfv: UUID! = ASIdentiferManager.shared().advertisingIdentifier
if let idfv = optionalIdfv {
return idfv.uuidString
}
jrose
(Jordan Rose)
7
I can't remember if that's the syntactic form we treated specially (as opposed to the one whcemyesil posted originally), but that trick is only for reference types. Since UUID is a value type bridged to NSUUID, it won't work, sorry. The workaround has to be on the Objective-C side.
If you want to avoid the crash issue, I don't think the code will work.
Actually the crash happens in Object-C side, we can write a OC wrapper to the crash like this:
Create a Header file, and add OCCatch.h in your Bridging-Header.h.
//
// OCCatch.h
//
//
#ifndef OCCatch_h
#define OCCatch_h
// add the code below to your -Bridging-Header.h
/**
#import "OCCatch.h"
*/
// How to use it in Swift?
/**
let exception = tryBlock {
let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView
//......
}
if let exception = exception {
print("exception: \(exception)")
}
*/
#import <Foundation/Foundation.h>
NS_INLINE NSException * _Nullable tryBlock(void(^_Nonnull tryBlock)(void)) {
@try {
tryBlock();
}
@catch (NSException *exception) {
return exception;
}
return nil;
}
#endif /* OCCatch_h */
You can find the file here:How to properly catch NSExceptions in Swift? · GitHub
The get the advertisingIdentifier by
let exception = tryBlock {
let advertisingIdentifier = ASIdentifierManager.shared().advertisingIdentifier
}
if let exception = exception {
print("advertisingIdentifier exception: \(exception)")
}
I haven't tested it, please try and let me know if there is any problem
Keith
(Keith Smiley)
10
Another workaround for this specific issue is to use the Objective-C runtime from Swift, which doesn't require any Objective-C code which you may prefer if you have an all Swift codebase
import AdSupport
extension ASIdentifierManager {
public var safeAdvertisingIdentifier: UUID? {
return self.perform(#selector(getter: ASIdentifierManager.advertisingIdentifier))?.takeUnretainedValue() as? UUID
}
}
5 Likes
jrose
(Jordan Rose)
11
Nitpick: that should be as! UUID? rather than as? UUID.
1 Like
mathaeus
(Mathaeus)
12
Hi, still seeing the crash regarding advertisingIdentifier on an iOS 13 device running an app built with Xcode 10.3.
@jrose would you know if building with Xcode 11 would resolve the issue, or would I still need one of the workarounds described above? Thx
jrose
(Jordan Rose)
13
I'm not at Apple anymore, sorry. But it looks like the headers haven't changed, and if you're still seeing the crash I guess the implementation hasn't changed either. So yes, the workaround is still necessary. :-(
1 Like
andr3a88
(Andrea)
14
can it be considered as a "working" workaround?