Swift PropertyListDecoder не работает с типом из пакета swift - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть отдельное приложение для 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
  }
}

1 Ответ

0 голосов
/ 01 мая 2020

После дальнейших исследований я исправил свою проблему с помощью этого ответа Stackoverflow .

В базе кода приложения я изменил Настройки сборки -> Удаление мертвого кода с «да» на «нет» в проекте и все цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...