Причина сбоя HomeKit: '-[__NSDate length]: но Bool отправил
tl;dr - Код в вопросе правильный. Причина аварии на другой вечеринке.
Задача состоит в том, чтобы контролировать розетку Elgato Eve Energy HomeKit. До начала кода все работает нормально, поэтому выбрана правильная комната, аксессуары и т. Д. Код отключает розетку, но сразу после этого происходит сбой приложения.
guard let services = accessory?.services else {
print("No Service")
return
}
for service in services {
if service.serviceType == HMServiceTypeOutlet {
for characteristic in service.characteristics {
print(characteristic.characteristicType)
if characteristic.characteristicType == HMCharacteristicTypePowerState {
print(characteristic.metadata!)
dump(characteristic)
// Turning off the outlet
characteristic.writeValue(false, completionHandler: { (error: Error?) -> Void in
if error == nil {
print("Yep")
} else {
print("Nop")
}
})
}
}
}
}
Журнал
00000023-0000-1000-8000-0026BB765291
00000025-0000-1000-8000-0026BB765291
[%@ Format: bool, Manufacturer Description: Power State ]
- <HMCharacteristic: 0x1702c23e0> #0
- super: NSObject
00000026-0000-1000-8000-0026BB765291
E863F10A-079E-48FF-8F27-9C2605A29F52
E863F126-079E-48FF-8F27-9C2605A29F52
E863F10D-079E-48FF-8F27-9C2605A29F52
E863F10C-079E-48FF-8F27-9C2605A29F52
2017-02-07 23:19:59.725340 POS[499:100178] -[__NSDate length]: unrecognized selector sent to instance 0x170007710
2017-02-07 23:19:59.725767 POS[499:100178] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDate length]: unrecognized selector sent to instance 0x170007710'
*** First throw call stack:
(0x188a291b8 0x18746055c 0x188a30268 0x188a2d270 0x18892680c 0x1895be458 0x1895be350 0x1895be698 0x1006328f8 0x1a249ac8c 0x199674f34 0x19966c588 0x1a249d194 0x101951258 0x101951218 0x10195eaec 0x101954ce0 0x10195f088 0x101960e2c 0x101960b78 0x187abb2a0 0x187abad8c)
libc++abi.dylib: terminating with uncaught exception of type NSException
Sym
2017-02-08 10:17:47.804825 POS[602:171994] -[__NSDate length]: unrecognized selector sent to instance 0x1740169c0
iZettlePayments`-[NSDictionary(Fractionized) dateForKey:]:
0x100973d88 <+0>: stp x22, x21, [sp, #-48]!
0x100973d8c <+4>: stp x20, x19, [sp, #16]
0x100973d90 <+8>: stp x29, x30, [sp, #32]
0x100973d94 <+12>: add x29, sp, #32 ; =32
0x100973d98 <+16>: mov x19, x0
0x100973d9c <+20>: nop
0x100973da0 <+24>: ldr x20, #861056 ; (void *)0x00000001ad8966b8: NSDateFormatter
0x100973da4 <+28>: nop
0x100973da8 <+32>: ldr x21, #851248 ; "izDateFormatterUsingISO8601"
0x100973dac <+36>: mov x0, x2
0x100973db0 <+40>: bl 0x1009e9b54 ; symbol stub for: objc_retain
0x100973db4 <+44>: mov x22, x0
0x100973db8 <+48>: mov x0, x20
0x100973dbc <+52>: mov x1, x21
0x100973dc0 <+56>: bl 0x1009e9b30 ; symbol stub for: objc_msgSend
0x100973dc4 <+60>: mov x29, x29
0x100973dc8 <+64>: bl 0x1009e9b78 ; symbol stub for: objc_retainAutoreleasedReturnValue
0x100973dcc <+68>: mov x20, x0
0x100973dd0 <+72>: nop
0x100973dd4 <+76>: ldr x1, #849044 ; "valueForKey:"
0x100973dd8 <+80>: mov x0, x19
0x100973ddc <+84>: mov x2, x22
0x100973de0 <+88>: bl 0x1009e9b30 ; symbol stub for: objc_msgSend
0x100973de4 <+92>: mov x19, x0
0x100973de8 <+96>: mov x0, x22
0x100973dec <+100>: bl 0x1009e9b48 ; symbol stub for: objc_release
0x100973df0 <+104>: mov x0, x19
0x100973df4 <+108>: bl 0x1009e9b78 ; symbol stub for: objc_retainAutoreleasedReturnValue
0x100973df8 <+112>: mov x19, x0
0x100973dfc <+116>: nop
0x100973e00 <+120>: ldr x1, #851168 ; "dateFromString:"
0x100973e04 <+124>: mov x0, x20
0x100973e08 <+128>: mov x2, x19
0x100973e0c <+132>: bl 0x1009e9b30 ; symbol stub for: objc_msgSend
0x100973e10 <+136>: mov x29, x29
0x100973e14 <+140>: bl 0x1009e9b78 ; symbol stub for: objc_retainAutoreleasedReturnValue
0x100973e18 <+144>: mov x21, x0
0x100973e1c <+148>: mov x0, x19
0x100973e20 <+152>: bl 0x1009e9b48 ; symbol stub for: objc_release
0x100973e24 <+156>: mov x0, x20
0x100973e28 <+160>: bl 0x1009e9b48 ; symbol stub for: objc_release
0x100973e2c <+164>: mov x0, x21
0x100973e30 <+168>: ldp x29, x30, [sp, #32]
0x100973e34 <+172>: ldp x20, x19, [sp, #16]
0x100973e38 <+176>: ldp x22, x21, [sp], #48
0x100973e3c <+180>: b 0x1009e9ac4 ; symbol stub for: objc_autoreleaseReturnValue
Просмотр сервисов и характеристик Elgato Eve показывает, что первая характеристика в массиве - это та, которая содержит имя, а вторая - это та, которой мне нужно манипулировать. Напечатанные метаданные показывают его тип bool и подтверждают его состояние Power, а также его можно читать и записывать, как описано в приведенной выше таблице. Поскольку я записываю false для правильной характеристики, розетка выключается, но через пару секунд приложение вылетает. Я удалил всех наблюдателей и делегировал методы, которые могли бы помешать. Это действительно сбивает с толку меня. Кроме того, код не вылетает на iOS 9, только на iOS 10.2, а также на бета-версии 10.3
Решение
Извините, ребята, после большого количества ругательств, ушибленного пальца ноги и намного меньшего количества волос, и через 24 часа я нашел виновника. Я использую iZettle, платежное устройство, и как только библиотеки были добавлены в проект, он рухнул. Ребята из iZettle признались, что у них есть расширение на NSDictionary
@interface NSDictionary (Fractionized)
- (NSDate *)dateForKey:(id)aKey;
@end
Это сталкивается с расширением в HomeKit, так что это является причиной проблемы. В результате они должны добавить префикс к своему расширению и снова скомпилировать библиотеки.
1 ответ
Хотя символическая трассировка стека может помочь, в ваших журналах есть один символ, который может дать полезную подсказку: что-то пытается задать NSDate для длины. По моему опыту, это происходит, когда библиотека ожидает, что что-то будет строкой NSString, и собирается ее проанализировать или распечатать или что-то еще.
Возможно, вы знаете, где используются NSDates. Это также поможет узнать, происходит ли сбой в том же потоке, который выполняет указанный выше код. Учитывая, что вы испытываете небольшую задержку, трудно сказать, связано ли это вообще с этим кодом! Возможно, в другом месте вашего приложения вы отвечаете на само устройство, предоставляющее вам обновление статуса, и, возможно, печатаете значение, которое вы считаете строкой, но на самом деле датой?