У меня есть отдельное приложение для WatchOS. Это работает, когда я развертываю приложение из XCode на часы. Я поместил приложение в TestFlight, но оно аварийно завершает работу при попытке чтения из файла plist.
Тип, который он пытается декодировать, находится в быстром пакете. Если я перенесу этот тип из пакета swift в базу кода watchOS, он будет работать при развертывании из TestFlight. Но когда он находится в быстром пакете, он падает при развертывании из TestFlight.
Я не знаю, почему это происходит. Чем отличается использование пакета между TestFlight и развертыванием из XCode?
Вот часть отчета cra sh:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000
VM Region Info: 0 is not in any region. Bytes before following region: 3686400
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT 00384000-0039c000 [ 96K] r-x/r-x SM=COW ...Kit Extension
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [384]
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libswiftCore.dylib 0x659e0e06 swift_checkMetadataState + 14
1 libswiftCore.dylib 0x659b66a8 type metadata completion function for ClosedRange<>.Index + 14
2 libswiftCore.dylib 0x659dc504 swift_getGenericMetadata + 1112
3 libswiftCore.dylib 0x659b5644 __swift_instantiateGenericMetadata + 28
4 libswiftFoundation.dylib 0x65b80fb0 PropertyListDecoder.decode<A>+ 651184 (_:from:format:) + 310
5 libswiftFoundation.dylib 0x65b80e72 PropertyListDecoder.decode<A>+ 650866 (_:from:) + 40
6 libswiftFoundation.dylib 0x65bf9b2c dispatch thunk of PropertyListDecoder.decode<A>+ 1145644 (_:from:) + 28
7 ...llHelper WatchKit Extension 0x0038ddb6 specialized load<A>(_:) + 40374 (Data.swift:117)
Из отчета cra sh это выглядит так в этой строке моего кода происходит сбой:
return try decoder.decode(T.self, from: data)
Ниже приведены подробности моего проекта:
В базе кода приложения для часов на вкладке Проект -> Swift Packages:
Я включил ссылку на мое git репо. Это частное репо на GitHub. Для правил версии я установил его в основную ветвь.
В целевом объекте «Расширение WatchKit» я включил свой пакет в раздел «Каркасы, библиотеки и встроенное содержимое».
Цель развертывания - 6.1
. Вот код, который использует PropertyListDecoder из файла Data.swift, на который есть ссылка в отчете cra sh.
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil) else {
os_log("Couldn't find %@ in main bundle", log: Log.data, type: .error, filename)
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
os_log("Couldn't load %@ from main bundle", log: Log.data, type: .error, filename)
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = PropertyListDecoder()
return try decoder.decode(T.self, from: data) <-- this is the line it crashes at
} catch {
os_log("Couldn't parse %@. Error is: %@", log: Log.data, type: .error, filename, error.localizedDescription)
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
Вот код, который находится в менеджер пакетов swift:
import Foundation
public struct Bar: Hashable, Codable, Identifiable, Comparable {
public var id: Bar{self}
public var name: String
public var weight: Double
public let unit: WeightUnit
public init(name: String, weight: Double, weightUnit: WeightUnit) {
self.name = name
self.weight = weight
self.unit = weightUnit
}
public static func < (lhs: Bar, rhs: Bar) -> Bool {
if lhs.name != rhs.name {
return lhs.name < rhs.name
}else if lhs.weight != rhs.weight {
return lhs.weight < rhs.weight
}else {
return lhs.unit < rhs.unit
}
}
public static func == (lhs: Self, rhs: Self) -> Bool {
return
lhs.name == rhs.name &&
lhs.weight == rhs.weight &&
lhs.unit == rhs.unit
}
}
public enum WeightUnit: String, CaseIterable, Identifiable, Codable, Comparable {
case Kilo = "kg"
case Pound = "lb"
public var id: WeightUnit {self}
public func description() -> String {
switch self {
case .Kilo:
return "Metric (\(self.rawValue))"
case .Pound:
return "Imperial (\(self.rawValue))"
}
}
public static func < (lhs: WeightUnit, rhs: WeightUnit) -> Bool {
lhs.description() < rhs.description()
}
public static func == (lhs: Self, rhs: Self) -> Bool {
return lhs.rawValue == rhs.rawValue
}
}