Команда печати Xcode 12 не отображает поля класса

#swift #xcode

#swift #xcode

Вопрос:

Недавно я перешел на новый MacBookPro. На новой машине и Xcode 12 команда печати работает иначе, чем раньше. Я немного озадачен тем, что изменилось. Новая установка Xcode установлена на MacOSX 10.15.7, и я использую Xcode 12.4. Я убедился, что у меня выбраны правильные параметры в выбранной консоли, слева фильтр не применяется, а на правой стороне выбрано «Весь вывод».

Что я получаю в консоли, так это «trans: apitest.Транзакция», которая является именем проекта и именем класса. Мои вопросы таковы: почему Xcode внезапно печатает название проекта? Кроме того, почему он не отображает какие-либо свойства класса? Есть ли способ перечислить все свойства экземпляра класса, не делая этого вручную? Спасибо за ваше терпение и помощь.

Это мой класс

 import Foundation

final class Transaction: Codable {
        
    var id: Int?
    var date: Date
    var amount: Int
    var planeID: Int
    var userID: UUID
    var month: Int
    var year: Int

    init(date: Date, amount: Int, planeID: Int, userID: UUID, month: Int, year: Int) {
        self.date = date
        self.amount = amount
        self.planeID = planeID
        self.userID = userID
        self.month = month
        self.year = year
    }
}
 

И с помощью кнопки в моем приложении я пытаюсь распечатать объект

 
                let trans = Transaction(date: now, amount: 5, planeID: 5, userID: id, month: month, year: year)
        
        print("trans: (trans)")
 

Ответ №1:

Если вы сделаете это структурой вместо класса, вы получите это поведение бесплатно. Но, возможно, есть причины, по которым это должен быть класс. В этом случае вы можете использовать отражение для печати ключей без необходимости делать это вручную:

 
final class Transaction: Codable, ReflectedStringConvertible {
        
    var id: Int?
    var date: Date
    var amount: Int
    var planeID: Int
    var userID: UUID
    var month: Int
    var year: Int

    init(date: Date, amount: Int, planeID: Int, userID: UUID, month: Int, year: Int) {
        self.date = date
        self.amount = amount
        self.planeID = planeID
        self.userID = userID
        self.month = month
        self.year = year
    }
}

public protocol ReflectedStringConvertible : CustomStringConvertible { }

extension ReflectedStringConvertible {
  public var description: String {
    let mirror = Mirror(reflecting: self)
    
    var str = "(mirror.subjectType)("
    var first = true
    for (label, value) in mirror.children {
      if let label = label {
        if first {
          first = false
        } else {
          str  = ", "
        }
        str  = label
        str  = ": "
        str  = "(value)"
      }
    }
    str  = ")"
    
    return str
  }
}
 

Идея взята из: https://medium.com/swift-programming/struct-style-printing-of-classes-in-swift-7ee34f1c975a

Комментарии:

1. Спасибо. Но почему сейчас выводится имя проекта?

2. Поведение по умолчанию для печатаемого класса — это пакет, частью которого он является (в данном случае это имя проекта), а затем само имя класса. Это означало бы, что если Transaction бы оно также появилось в другом пакете, не было бы путаницы в пространстве имен.