Apple's code for the HomeKit Catalog app is available for Swift 2.3 as of the 9/13/16 release. I'm trying to use some of that code (the HMCharacteristic extension) in my app, which is all in Swift 3.
Much of the HMCharacteristic extension converts to Swift 3 successfully.
The problem I'm seeing centers on the NumberFormatter. I cannot seem to get the syntax right for the conversion of a number to a string.
Here's the extension as provided by Apple for Swift 2.3. The problem is in line #40.
import HomeKit
extension HMCharacteristic {
private struct Constants {
static let valueFormatter = NSNumberFormatter()
static let numericFormats = [
HMCharacteristicMetadataFormatInt,
HMCharacteristicMetadataFormatFloat,
HMCharacteristicMetadataFormatUInt8,
HMCharacteristicMetadataFormatUInt16,
HMCharacteristicMetadataFormatUInt32,
HMCharacteristicMetadataFormatUInt64
]
}
/*
Returns the localized description for a provided value, taking the characteristic's metadata and possible
values into account.
- parameter value: The value to look up.
- returns: A string representing the value in a localized way, e.g. `"24%"` or `"354º"`
*/
func localizedDescriptionForValue(value: AnyObject) -> String {
if self.isWriteOnly {
return NSLocalizedString("Write-Only Characteristic", comment: "Write-Only Characteristic")
}
else if self.isBoolean {
if let boolValue = value.boolValue {
return boolValue ? NSLocalizedString("On", comment: "On") : NSLocalizedString("Off", comment: "Off")
}
}
if let number = value as? Int {
if let predeterminedValueString = self.predeterminedValueDescriptionForNumber(number) {
return predeterminedValueString
}
if let stepValue = self.metadata?.stepValue {
Constants.valueFormatter.minimumFractionDigits = Int(log10(1.0 / stepValue.doubleValue))
if let string = Constants.valueFormatter.stringFromNumber(number) {
return string + self.localizedUnitDecoration
}
}
}
return "\(value)"
}
The line that causes trouble in Swift 3 is #03 below, where the integer "number " is to be converted to a string:
if let stepValue = self.metadata?.stepValue {
Constants.valueFormatter.minimumFractionDigits = Int(log10(1.0 / stepValue.doubleValue))
if let string = Constants.valueFormatter.string(from: number) {
return string + self.localizedUnitDecoration
}
I can't this to work in Playground either:
import UIKit
let valueFormatter = NumberFormatter()
let value = 23
if let myNumber = value as? Int {
print("myNumber is \(myNumber)") <-- "myNumber is 23"
if let string = valueFormatter.string(from number: myNumber) {
print("myNumber is \(myNumber) and the string is \(string)")
}
}
error: NumberFormatter testing.playground:6:49: error: cannot convert value of type 'Int' to expected argument type 'NSNumber'
if let string = valueFormatter.string(from: myNumber) {
In addition to the syntax above, I've tried the suggestion:
if let string = valueFormatter.string(from: NSNumber(myNumber))
if let string = valueFormatter.string(from:myNumber)
Nothing is working!