Reputation: 103
I have a function that returns certain system values. It worked fine in Swift 2.2, and I just upgraded to Xcode 8 and Swift 3, and now it's failing.
func ioPlatExpertDevString(_ property: String) -> String {
// Start tapping in to the IO Service
let ioPlatformExpertDevice:io_service_t? = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
var sAnswer = "Not Found"
let cfAnswer:AnyObject! = IORegistryEntryCreateCFProperty(ioPlatformExpertDevice!, "\(property)" as CFString!, kCFAllocatorDefault, 0).takeRetainedValue()
if (cfAnswer != nil) {
let nsAnswer = (cfAnswer as! NSString)
sAnswer = nsAnswer.uppercased
}
// Close the IO Service
IOObjectRelease(ioPlatformExpertDevice!)
return sAnswer
}
Prior, I was using "CFData" instead of "AnyObject". It builds fine, but at runtime, I get the following error:
Could not cast value of type '__NSCFData' (0x7fff7b833ec0) to 'NSString' (0x7fff7ac32038).
Upvotes: 3
Views: 9550
Reputation: 5400
For more recent versions of Swift:
String(decoding: data, as: UTF8.self)
Upvotes: 1
Reputation: 461
Replace
let nsAnswer = (cfAnswer as! NSString)
To
let nsAnswer = NSString(data: cfAnswer as! Data, encoding: String.Encoding.utf8.rawValue)
Upvotes: 5
Reputation: 285069
Please do not annotate types unless the compiler tell you to do.
For example IOServiceGetMatchingService
returns a non-optional io_service_t
, your optional annotation makes it worse.
IORegistryEntryCreateCFProperty
returns Unmanaged<CFTypeRef>!
an annotation is not needed either as well as the string interpolation and the cast to implicit unwrapped optional.
CFTypeRef
can be bridge casted to a native Swift type.
If the return type is (NS)Data
it's most unlikely that it worked in prior versions.
This code considers String
and Data
if the latter can be converted to String
.
func ioPlatExpertDevString(_ property: String) -> String {
// Start tapping in to the IO Service
let ioPlatformExpertDevice = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
var sAnswer = "Not Found"
let cfAnswer = IORegistryEntryCreateCFProperty(ioPlatformExpertDevice, property as CFString, kCFAllocatorDefault, 0).takeRetainedValue()
if let cfData = cfAnswer as? Data, let answer = String(data:cfData, encoding:.utf8) {
sAnswer = answer.uppercased()
} else if let answer = cfAnswer as? String {
sAnswer = answer.uppercased()
}
// Close the IO Service
IOObjectRelease(ioPlatformExpertDevice)
return sAnswer
}
Upvotes: 0