2017-02-15 8 views
2

Я загрузил xml-файлы через Alamofire.download (теперь у меня есть копия XML когда мои пользователи отключены). Следующая вещь - разобрать загруженный XML в словарь.Невозможно разобрать XML с использованием Swift3 Alamofire (4.3.0), EVReflection (4.2.0) - не соответствует кодированию с ключевым значением

Я получаю следующие ошибки при использовании EVReflection/XML:

WARNING: The class '_TtCC13WINSystemInfo15RepeaterUpdates9WinSystem' is not key value coding-compliant for the key '__name' There is no support for optional type, array of optionals or enum properties. As a workaround you can implement the function 'setValue forUndefinedKey' for this. See the unit tests for more information

WARNING: The class '_TtCC13WINSystemInfo15RepeaterUpdates17WinSystemRepeater' is not key value coding-compliant for the key 'winSystemRepeater' There is no support for optional type, array of optionals or enum properties. As a workaround you can implement the function 'setValue forUndefinedKey' for this. See the unit tests for more information

Вот отрывок из XML:

определения
<?xml version="1.0" encoding="UTF-8"?> 
<winSystem> 
    <timeStamp> AS OF:02/15/2017 20:17:01</timeStamp> 
    <winSystemRepeaters> 
     <winSystemRepeater> 
      <node>1000</node> 
      <repeaterId>1000</repeaterId> 
      <grouping>irlp</grouping> 
      <callSign>VE7RHS</callSign> 
      <serviceArea>Vancouver</serviceArea> 
      <serviceState>BC</serviceState> 
      <country>Canada</country> 
      <locationElevation>Vancouver, BC Canada</locationElevation> 
      <latitudeDefault>49.26973</latitudeDefault> 
      <longitudeDefault>-123.24992</longitudeDefault> 
      <freqOffsetPl>145.2700 -600.0000 100.0</freqOffsetPl> 
      <url>http://www.ars.ams.ubc.ca</url> 
      <notes>IRLP Status AS OF:02/15/2017 20:17:01</notes> 
     </winSystemRepeater> 
     <winSystemRepeater> 
      <node>1003</node> 
      <repeaterId>1003</repeaterId> 
      <grouping>irlp</grouping> 
      <callSign>VE7ISC</callSign> 
      <serviceArea>Nanaimo</serviceArea> 
      <serviceState>BC</serviceState> 
      <country>Canada</country> 
      <locationElevation>Nanaimo, BC Canada</locationElevation> 
      <latitudeDefault>49.22750</latitudeDefault> 
      <longitudeDefault>-123.97417</longitudeDefault> 
      <freqOffsetPl>146.6400 -600.0000 0.00</freqOffsetPl> 
      <url>http://ve7na.ca</url> 
      <notes>IRLP Status AS OF:02/15/2017 20:17:01</notes> 
     </winSystemRepeater> 
    </winSystemRepeaters> 
</winSystem> 

Мои EVObject Класс:

class WinSystem: EVObject { 
    var timeStamp: String? 
    var winSystemRepeaters: [WinSystemRepeater] = [WinSystemRepeater]() 
} 

class WinSystemRepeater: EVObject { 
    var node: String? 
    var repeaterId: NSNumber? 
    var grouping: String? 
    var callSign: String? 
    var serviceArea: String? 
    var serviceState: String? 
    var country: String? 
    var locationElevation: String? 
    var latitudeDefault: NSNumber? 
    var longitudeDefault: NSNumber? 
    var freqOffsetPl: String? 
    var url: String? 
    var notes: String? 
} 

Моя функция который вызывается после уведомления об успешной загрузке XML fi ле:

func buildRepeaterDictionary(notification:Notification) -> Void { 

    SpeedLog.print("Starting buildRepeaterDictionary") 
    SpeedLog.print(notification) 
    guard let userInfo = notification.userInfo, 
     let urlString = userInfo["fileUrlString"] as? String else { 
      SpeedLog.print("No userInfo found in successful notification") 
      return 
    } 

    // Parse XML 
    let xmlUrl = URL(string: urlString) 
    do { 
     let xmlString = try String(contentsOf: xmlUrl!, encoding: String.Encoding.utf8) 
     let repeaters = WinSystem(xmlString: xmlString) 
     SpeedLog.print("Opened file: \(xmlUrl)") 
     SpeedLog.print("Repeaters: \(repeaters)") 
    } 
    catch { 
     SpeedLog.print("Unable to open: \(xmlUrl)") 
    } 
} 

Когда я напечатать xmlString непосредственно перед let repeaters = WinSystem(xmlString: xmlString) заявления. Я получаю:

Printing description of xmlString: 
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<winSystem>\n <timeStamp> AS OF:02/16/2017 06:00:01</timeStamp>\n <winSystemRepeaters>\n <winSystemRepeater>\n <node>1000</node>\n <repeaterId>1000</repeaterId>\n <grouping>irlp</grouping>\n <callSign>VE7RHS</callSign>\n <serviceArea>Vancouver</serviceArea>\n <serviceState>BC</serviceState>\n <country>Canada</country>\n <locationElevation>Vancouver, BC Canada</locationElevation>\n <latitudeDefault>49.26973</latitudeDefault>\n <longitudeDefault>-123.24992</longitudeDefault>\n <freqOffsetPl>145.2700 -600.0000 100.0</freqOffsetPl>\n <url>http://www.ars.ams.ubc.ca</url>\n <notes>IRLP Status AS OF:02/16/2017 06:00:01</notes>\n </winSystemRepeater>\n 

Что мне не хватает?

ответ

0

Как вы можете видеть в тесте AlamofireXmlTests.swift EVReflection, вам нужен переменный с именем __name в вашем объекте. Библиотека XMLDictionary в некоторых случаях добавит это свойство как имя узла.

Если вы хотите, вы можете написать его в другую собственность, добавив следующий фрагмент кода вам возразить:

override internal func propertyMapping() -> [(keyInObject: String?, keyInResource: String?)] { 
    return [(keyInObject: "name", keyInResource: "__name")] 
} 

Для вашего другого вопроса вашего winSystemRepeaters является объектом с массивом winSystemRepeater в нем. Поэтому вам нужен дополнительный объект для хранения списка. Таким образом, ваше определение объекта будет:

class WinSystem: EVObject { 
    var timeStamp: String? 
    var winSystemRepeaters: WinSystemRepeaters? 
} 

class WinSystemRepeaters: EVObject { 
    var winSystemRepeater: [WinSystemRepeater]? 
} 

class WinSystemRepeater: EVObject { 
    var node: String? 
    var repeaterId: NSNumber? 
    var grouping: String? 
    var callSign: String? 
    var serviceArea: String? 
    var serviceState: String? 
    var country: String? 
    var locationElevation: String? 
    var latitudeDefault: NSNumber? 
    var longitudeDefault: NSNumber? 
    var freqOffsetPl: String? 
    var url: String? 
    var notes: String? 
} 

... но я помню, что есть обходной путь для этого ... Так почему же, что не работает в вашем случае ... Не могли бы вы попробовать назвать вашу собственность WinSystem для winSystemRepeater вместо winSystemRepeaters?

+0

Теперь я могу разобрать XML после изменения EVObjects по мере ввода. Я все еще получаю сообщение об ошибке: «ПРЕДУПРЕЖДЕНИЕ: класс« _TtCC13WINSystemInfo15RepeaterUpdates9WinSystem »не является ключевым для кодирования для ключа« __name » Нет поддержки дополнительного типа, массива опций или свойств перечисления. В качестве обходного пути вы можете реализовать для него функцию setValue forUndefinedKey. Более подробную информацию см. В модульных тестах. val: «Необязательно (winSystem)». Я добавил строку «val» в строку ошибки. Похоже, что это имя корневого элемента. – Kent