Я работаю над приложением Apple Watch. Большинство моих компонентов используют JSON и используют протокол Swift Codable для декодирования JSON. Теперь я хотел подготовить свой выпуск, но я получил сообщение от бета-тестера, что приложение всегда зависало на его Series 3.
После того, как я установил сборку TestFlight на Series 3, я смог воспроизвести проблему. Журналы cra sh из TestFlight и журналы cra sh, извлеченные из моего iPhone, указывают, что cra sh происходит, пока JSON декодируется.
У меня довольно сложные JSON структуры, но я не вносил в них никаких изменений с момента последнего обновления. Кроме того, декодирование JSON отлично работает на сборках Xcode (также на Series 3) и на более новых Apple Watch (Series 4 + 5). Я изо всех сил пытаюсь выяснить, что могло вызвать проблему. На форумах разработчиков Apple я обнаружил пост с похожей проблемой, но без решения: https://forums.developer.apple.com/thread/124627
Вот часть Stacktrace моего журнала cra sh:
Date/Time: 2020-02-05 08:37:42.9924 +0100
Launch Time: 2020-02-05 08:37:40.0000 +0100
OS Version: Watch OS 6.1.2 (17S5792a)
Release Type: User
Baseband Version: 4.40.02
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Application Specific Information:
abort() called
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x4d9aefc8 __pthread_kill + 8
1 libsystem_pthread.dylib 0x4da260be pthread_kill + 108
2 libsystem_c.dylib 0x4d9383a4 abort + 84
3 libswiftCore.dylib 0x6cffbade swift_vasprintf+ 2341598 (char**, char const*, char*) + 0
4 libswiftCore.dylib 0x6d00932c swift::TargetMetadata<swift::InProcess>::getGenericArgs+ 2396972 () const + 0
5 libswiftCore.dylib 0x6d00508c _swift_initClassMetadataImpl+ 2379916 (swift::TargetClassMetadata<swift::InProcess>*, swift::ClassLayoutFlags, unsigned long, swift::TypeLayout const* const*, unsigned long*, bool) + 28
6 libswiftCore.dylib 0x6d005c86 swift_initClassMetadata2 + 22
7 libswiftCore.dylib 0x6cfdc6fc type metadata completion function for _KeyedDecodingContainerBox + 50
8 libswiftCore.dylib 0x6d00a6c2 swift::MetadataCacheEntryBase<(anonymous namespace)::GenericCacheEntry, void const*>::doInitialization+ 2401986 (swift::ConcurrencyControl&, swift::MetadataCompletionQueueEntry*, swift::MetadataRequest) + 178
9 libswiftCore.dylib 0x6d003a0c swift_getGenericMetadata + 1124
10 libswiftCore.dylib 0x6cdf4210 KeyedDecodingContainer.init<A>+ 213520 (_:) + 40
11 libswiftFoundation.dylib 0x6d156e0a __JSONDecoder.container<A>+ 323082 (keyedBy:) + 678
12 libswiftFoundation.dylib 0x6d1a3a1c protocol witness for Decoder.container<A>+ 637468 (keyedBy:) in conformance __JSONDecoder + 18
13 libswiftFoundation.dylib 0x6d1592b6 protocol witness for Decoder.container<A>+ 332470 (keyedBy:) in conformance __JSONDecoder + 32
14 libswiftCore.dylib 0x6cfdb1cc dispatch thunk of Decoder.container<A>+ 2208204 (keyedBy:) + 24
15 WatchSonos WatchKit Extension 0x00440bf2 0x358000 + 953330
16 WatchSonos WatchKit Extension 0x0043d08c 0x358000 + 938124
17 libswiftCore.dylib 0x6cfdb156 dispatch thunk of Decodable.init+ 2208086 (from:) + 12
18 libswiftFoundation.dylib 0x6d16fbee __JSONDecoder.unbox_+ 424942 (_:as:) + 4014
19 libswiftFoundation.dylib 0x6d156816 JSONDecoder.decode<A>+ 321558 (_:from:) + 642
20 libswiftFoundation.dylib 0x6d22af98 dispatch thunk of JSONDecoder.decode<A>+ 1191832 (_:from:) + 28
21 WatchSonos WatchKit Extension 0x0045db0c 0x358000 + 1071884
22 WatchSonos WatchKit Extension 0x00461cce 0x358000 + 1088718
23 WatchSonos WatchKit Extension 0x00461bde 0x358000 + 1088478
24 WatchSonos WatchKit Extension 0x00420ffa 0x358000 + 823290
25 WatchSonos WatchKit Extension 0x00425914 0x358000 + 842004
26 libdispatch.dylib 0x4d851846 _dispatch_call_block_and_release + 10
27 libdispatch.dylib 0x4d8528b8 _dispatch_client_callout + 6
28 libdispatch.dylib 0x4d85c6b0 _dispatch_main_queue_callback_4CF + 868
29 CoreFoundation 0x4dcdbbaa __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 10
30 CoreFoundation 0x4dcd7c00 __CFRunLoopRun + 1832
31 CoreFoundation 0x4dcd723a CFRunLoopRunSpecific + 370
32 GraphicsServices 0x50aebcd0 GSEventRunModal + 96
33 UIKitCore 0x65c91580 UIApplicationMain + 1730
34 libxpc.dylib 0x4da73c80 _xpc_objc_main.cold.3 + 152
35 libxpc.dylib 0x4da649b0 _xpc_objc_main + 184
36 libxpc.dylib 0x4da668c4 xpc_main + 110
37 Foundation 0x4e56b0c6 +[NSXPCListener serviceListener] + 0
38 PlugInKit 0x556d726c 0x556c5000 + 74348
39 WatchKit 0x5cfe9afe WKExtensionMain + 62
40 WatchKit 0x5d09f020 main + 10
Вот позиция в коде, который вылетает:
required public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.id = try values.decode(String.self, forKey: .id)
do {
if values.contains(.groups) {
let groups = try values.decode(Dictionary<String, SonosGroup>.self, forKey: .groups)
self.groups = groups
}
if values.contains(.players) {
let players = try values.decode(Array<SonosPlayer>.self, forKey: .players)
self.players = players
}
}catch let error {
print("Error decoding groups \(error)")
}
}
Для меня это выглядит как ошибка Apple, и я подал отзыв об этом, но это не решение для следующей релиз.
Кто-нибудь знает, в чем разница между сборкой TestFlight и сборкой выпуска Xcode? Я попытался установить другой уровень оптимизации, отключив битовый код (не разрешен для приложений Apple Watch), и я начал заменять Codable старым добрым JSONSerialization
.
Если кто-то знает об этом больше, спасибо вам за это.
С уважением, Алекс