I have crash while trying to do:
static func getDeviceUUID() -> String {
guard let uuid = UIDevice.current.identifierForVendor?.uuidString else {
assertionFailure("Nil while unwrapping UIDevice.current.identifierForVendor?.uuidString")
return ""}
return uuid
}
Error says: Thread 9: Fatal error: Nil while unwrapping UIDevice.current.identifierForVendor?.uuidString
But when i try to log it out in console it says:
po UIDevice.current.identifierForVendor?.uuidString
▿ Optional<String>
- some : "39DEFA50-D6A1-4788-BCCC-5E2A28A04C57"
So, it actually have value. Why crash is happening?
It's working fine
func getDeviceUUID() -> String {
guard let uuid = UIDevice.current.identifierForVendor?.uuidString else {
assertionFailure("Nil while unwrapping UIDevice.current.identifierForVendor?.uuidString")
return ""}
return uuid
}
print(getDeviceUUID()) //50E6548C-0BB4-4979-8F5F-DFAD422BEB26
I've had a similar problem occur when trying to grab the IDFA from the AdSupport framework:
ASIdentifierManager.shared().advertisingIdentifier.uuidString
// causes exception
In this case, it seems as though the Objective-C code base has an incorrectly marked 'nonnull' method, which can't be worked around because the uuidString method for the UUID class returns a value type (String), whereas in Obj-C it would return a reference type (NSString): https://forums.swift.org/t/is-it-safe-to-cast-a-nonnull-objc-type-to-a-swift-optional/10658
Since these both make use of the UUID class, my guess is that it's the same problem.
The workaround that the above link suggests is to build an Obj-C wrapper for accessing the UUID:
+ (nullable NSString*)getUUIDFromDevice {
NSString *uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
if (uuid) {
return uuid;
} else {
return nil;
}
}
Unfortunately this is difficult to test, because it's unclear when exactly the UUID value would ever be nil.
Maybe because you didn't check if user permit ti check it.
guard ASIdentifierManager.shared().isAdvertisingTrackingEnabled else {
return nil
}
return ASIdentifierManager.shared().advertisingIdentifier.uuidString
BTW, for iOS14+ you should check it differently:
import AdSupport
import AppTrackingTransparency
extension ASIdentifierManager {
//NOTE: if the user has enabled Limit Ad Tracking, this IDFA will be all zeros on a physical device
static var identifierForAdvertising: String {
if #available(iOS 14, *) {
guard ATTrackingManager.trackingAuthorizationStatus == .authorized else {
return ""
}
} else {
guard ASIdentifierManager.shared().isAdvertisingTrackingEnabled else {
return ""
}
}
return ASIdentifierManager.shared().advertisingIdentifier.uuidString
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.