programing

콘솔에 Swift 사전을 예쁘게 인쇄할 수 있는 방법이 있습니까?

topblog 2023. 5. 18. 20:40
반응형

콘솔에 Swift 사전을 예쁘게 인쇄할 수 있는 방법이 있습니까?

NSDictionary *dictionary = @{@"A" : @"alfa",
                             @"B" : @"bravo",
                             @"C" : @"charlie",
                             @"D" : @"delta",
                             @"E" : @"echo",
                             @"F" : @"foxtrot"};
NSLog(@"%@", dictionary.description);

콘솔에서 다음을 출력합니다.

{
    A = alfa;
    B = bravo;
    C = charlie;
    D = delta;
    E = echo;
    F = foxtrot;
}

let dictionary: [String : String] = ["A" : "alfa",
                                     "B" : "bravo",
                                     "C" : "charlie",
                                     "D" : "delta",
                                     "E" : "echo",
                                     "F" : "foxtrot"];
print(dictionary)

콘솔에서 다음을 출력합니다.

["B": "bravo", "A": "alfa", "F": "foxtrot", "C": "charlie", "D": "delta", "E": "echo"]

Swift에서 각 키-값 쌍이 새 줄을 차지하는 예쁜 인쇄 사전으로 가져올 수 있는 방법이 있습니까?

사전을 'AnyObject'에 캐스팅하는 것이 저에게 가장 간단한 해결책이었습니다.

let dictionary = ["a":"b",
                  "c":"d",
                  "e":"f"]
print("This is the console output: \(dictionary as AnyObject)")

이것이 콘솔 출력입니다.

덤프 옵션보다 읽기 쉽지만 키 값의 총 수는 표시되지 않습니다.

po

콘솔에서 이스케이프 시퀀스가 없는 JSON으로 Dictionary를 보려는 사용자를 위해 간단한 방법은 다음과 같습니다.

(lldb) p print(String(data: try! JSONSerialization.data(withJSONObject: object, options: .prettyPrinted), encoding: .utf8)!)

예를 들어 사전을 검사하는 것이 목적인 경우 덤프를 사용할 수 있습니다. dump스위프트의 표준 라이브러리의 일부입니다.

용도:

let dictionary: [String : String] = ["A" : "alfa",
                                     "B" : "bravo",
                                     "C" : "charlie",
                                     "D" : "delta",
                                     "E" : "echo",
                                     "F" : "foxtrot"]

dump(dictionary)

출력:

여기에 이미지 설명 입력


dump반사(반영)를 통해 개체의 내용을 인쇄합니다.

배열의 상세 보기:

let names = ["Joe", "Jane", "Jim", "Joyce"]
dump(names)

인쇄:


[0]:
제인[1] 제인
[2]:
조이스 [3] 조이스조

사전의 경우:

let attributes = ["foo": 10, "bar": 33, "baz": 42]
dump(attributes)

인쇄:

의 키/쌍개
(원소)[0]: (2개의 원소)
bar.0: 막대
- .1: 33
(의 원소1]: (2개의 원소)
.0: baz
- .1: 42
(2]: (2원소)
.0: foo
- .1: 10

dump는 로선됩다로 됩니다.dump(_:name:indent:maxDepth:maxItems:).

첫 번째 매개 변수에 레이블이 없습니다.

다른 매개 변수를 사용할 수 있습니다. 예를 들어,name검사할 개체의 레이블을 설정합니다.

dump(attributes, name: "mirroring")

인쇄:

의 키 쌍: 3개의 키/값 쌍: 3개의 키/값 쌍
(원소)[0]: (2개의 원소)
bar.0: 막대
- .1: 33
(의 원소1]: (2개의 원소)
.0: baz
- .1: 42
(2]: (2원소)
.0: foo
- .1: 10

또한 특정 개수의 항목만 인쇄하도록 선택할 수 있습니다.maxItems:물체를 특정 깊이까지 파싱하기 위해maxDepth:▁the▁objects▁with다▁to▁and▁change▁printed▁of로 인쇄물의 를 변경합니다.indent:.

디버그 목적으로만 배열 또는 사전을 예쁜 인쇄된 json으로 변환합니다.

public extension Collection {
    
    /// Returns: the pretty printed JSON string or an error string if any error occur.
    var json: String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
            return String(data: jsonData, encoding: .utf8) ?? ""
        } catch {
            return "json serialization error: \(error)"
        }
    }
}

그러면:

print("\nHTTP request: \(URL)\nParams: \(params.json)\n")

콘솔 결과:

HTTP request: https://example.com/get-data
Params: {
  "lon" : 10.8663676,
  "radius" : 111131.8046875,
  "lat" : 23.8063882,
  "index_start" : 0,
  "uid" : 1
}

기능 프로그래밍을 사용하는 또 다른 방법입니다.

dictionary.forEach { print("\($0): \($1)") }

산출량

B: bravo
A: alfa
F: foxtrot
C: charlie
D: delta
E: echo

JSON 검증자에게 결과를 전달할 때 결과가 유효하지 않기 때문에(종종 ':'가 아닌 '='를 포함한 코드 때문에) 여기에 제공된 답변 중 상당수는 인쇄된 진짜 JSON이라고 생각하지 않습니다.

제가 발견한 가장 쉬운 방법은 JSON 객체를 데이터로 변환하는 것입니다. 예쁜 인쇄 옵션을 사용하여 JSON 객체를 데이터로 변환한 다음 결과 데이터를 사용하여 문자열을 인쇄하는 것입니다.

다음은 예입니다.

let jsonData = try! JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)

if let jsonString = String(data: jsonData, encoding: .utf8) {
    print(jsonString)
}

결과:

{
    "jsonData": [
        "Some String"
    ],
    "moreJSONData": "Another String",
    "evenMoreJSONData": {
        "A final String": "awd"
    }
}

편집: OP가 JSON을 요청하지 않았다고 지적되었지만, 저는 단지 데이터를 인쇄하거나 콘솔에 버리는 것을 권장하는 답변은 (있는 경우) 거의 포맷을 제공하지 않으므로 인쇄하기에 적합하지 않습니다.

OP가 JSON을 요구하지는 않지만 xcode/swift로 콘솔에 뱉어내는 끔찍한 포맷보다 훨씬 더 읽기 쉬운 데이터 포맷이기 때문에 실행 가능한 답변이라고 생각합니다.

여기 제 다른 답변에 따라 조정되었습니다.

LLDB 별칭을 사용한 PrettyPrint JSON 솔루션

코드 필요 없음

  • 적절한 json 형식(인덴테이션, 새 줄 등)을 얻으려면 XCode(소스)의 lldb 터미널에서 다음 명령을 실행하여 allldb 별칭을 정의할 수 있습니다.
command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'
  • 위의 명령은 현재 XCode 세션 중에만 작동합니다.XCode를 열 때마다 별칭이 다시 정의되지 않도록 하려면 macOS 터미널에서 다음 명령을 실행합니다.을 위에정별에추니다합가에 합니다.~/.lldbinitXCode가 시작될 때마다 로드되는 LLDB:
echo "command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'" >> ~/.lldbinit
  • 이렇게 하면 다음이 생성됩니다.pjsonXCode의 lldb 터미널에서 사용할 수 있는 별칭:
pjson object

다음 Swift 개체의 출력 비교:

// Using Any? to demo optional & arbitrary Type
let dictionary: Any? = [
    "embedded": [
        "JustForTheSakeOfTheDemo": 42
    ],
    "A" : "alfa",
    "B" : "bravo",
    "C" : "charlie",
    "D" : "delta",
    "E" : "echo",
    "F" : "foxtrot"
]

✅ ✅ 출력pjson dictionary

{
  "F" : "foxtrot",
  "D" : "delta",
  "embedded" : {
    "JustForTheSakeOfTheDemo" : 42
  },
  "E" : "echo",
  "A" : "alfa",
  "C" : "charlie",
  "B" : "bravo"
}

❌ ❌ 출력p dictionary

(Any?) $R0 = 7 key/value pairs {
  [0] = {
    key = "F"
    value = "foxtrot"
  }
  [1] = {
    key = "D"
    value = "delta"
  }
  [2] = {
    key = "embedded"
    value = 1 key/value pair {
      [0] = (key = "JustForTheSakeOfTheDemo", value = 42)
    }
  }
  [3] = {
    key = "E"
    value = "echo"
  }
  [4] = {
    key = "A"
    value = "alfa"
  }
  [5] = {
    key = "C"
    value = "charlie"
  }
  [6] = {
    key = "B"
    value = "bravo"
  }
}

❌ ❌ 출력p (dictionary as! NSDictionary)

(NSDictionary) $R18 = 0x0000000281e89710 {
  ObjectiveC.NSObject = {
    base__SwiftNativeNSDictionaryBase@0 = {
      baseNSDictionary@0 = {
        NSObject = {
          isa = Swift._SwiftDeferredNSDictionary<Swift.String, Any> with unmangled suffix "$"
        }
      }
    }
  }
}

❌ ❌ 출력po dictionary

▿ Optional<Any>
  ▿ some : 7 elements
    ▿ 0 : 2 elements
      - key : "F"
      - value : "foxtrot"
    ▿ 1 : 2 elements
      - key : "D"
      - value : "delta"
    ▿ 2 : 2 elements
      - key : "embedded"
      ▿ value : 1 element
        ▿ 0 : 2 elements
          - key : "JustForTheSakeOfTheDemo"
          - value : 42
    ▿ 3 : 2 elements
      - key : "E"
      - value : "echo"
    ▿ 4 : 2 elements
      - key : "A"
      - value : "alfa"
    ▿ 5 : 2 elements
      - key : "C"
      - value : "charlie"
    ▿ 6 : 2 elements
      - key : "B"
      - value : "bravo"

❌ ❌ 출력po print(dictionary)

Optional(["F": "foxtrot", "D": "delta", "embedded": ["JustForTheSakeOfTheDemo": 42], "E": "echo", "A": "alfa", "C": "charlie", "B": "bravo"])

for 루프를 사용하여 각 반복을 인쇄할 수 있습니다.

for (key,value) in dictionary { 
    print("\(key) = \(value)")
}

확장된 응용 프로그램:

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

    var prettyprint : String {
        for (key,value) in self {
            print("\(key) = \(value)")
        }

        return self.description
    }
}

대체 응용 프로그램:

extension Dictionary where Key: CustomDebugStringConvertible, Value:CustomDebugStringConvertible {

    func prettyPrint(){
        for (key,value) in self {
            print("\(key) = \(value)")
        }
    }
}

용도:

dictionary.prettyprint //var prettyprint
dictionary.prettyPrint //func prettyPrint

출력(Xcode 8 베타 2 Playground에서 테스트됨):

A = alfa
B = bravo
C = charlie
D = delta
E = echo
F = foxtrot

Swift Dictionary를 json과 back으로 변환하는 방법론이 가장 깔끔합니다.저는 스위프트 사전을 인쇄하기 위해 pjson 명령어가 있는 페이스북의 끌을 사용합니다.예:

(lldb) pjson dict as NSDictionary

이것은 사전을 예쁘게 인쇄해야 합니다.이것은 이미 제안된 것을 하는 훨씬 더 깨끗한 방법입니다.추신. Objective-C 런타임은 Swift 사전을 이해하지 못하기 때문에 현재로서는 NSDictionary로 캐스팅해야 합니다.저는 이미 그 제한을 없애기 위해 끌에 대한 홍보를 시작했습니다.

업데이트: 홍보에 합격했습니다.이제 위에서 언급한 pjson 대신 psjson 명령을 사용할 수 있습니다.

스위프트 3(& @Jalakoo의 훌륭한 답변을 바탕으로 구축)에 대해 다음과 같이 하십시오.Dictionary확장명:

extension Dictionary where Key: ExpressibleByStringLiteral, Value: Any {
    var prettyPrint: String {
        return String(describing: self as AnyObject)
    }
}

그런 다음 예쁜 방식으로 어떤 계층의 사전을 인쇄합니다.dump()) 사용:

print(dictionary!.prettyPrint)

세부 사항

  • Xcode 10.2.1(10E1001), Swift 5

해결책

extension Dictionary {
    func format(options: JSONSerialization.WritingOptions) -> Any? {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: options)
            return try JSONSerialization.jsonObject(with: jsonData, options: [.allowFragments])
        } catch {
            print(error.localizedDescription)
            return nil
        }
    }
}

사용.

let dictionary: [String : Any] = [
                                    "id": 0,
                                    "bool": true,
                                    "int_array": [1,3,5],
                                    "dict_array": [
                                        ["id": 1, "text": "text1"],
                                        ["id": 1, "text": "text2"]
                                    ]
                                 ]
print("Regualr print:\n\(dictionary)\n")
guard let formatedDictionary = dictionary.format(options: [.prettyPrinted, .sortedKeys]) else { return }
print("Pretty printed:\n\(formatedDictionary)\n")

결과.

여기에 이미지 설명 입력

swift 5, xcode 10.3:

po print(<your Plist container>)

어때요?

import Foundation

extension Dictionary {
    var myDesc: String {
        get {
            var v = ""
            for (key, value) in self {
                v += ("\(key) = \(value)\n")
            }
            return v
        }
    }
}


// Then, later, for any dictionary:
print(dictionary.myDesc)
extension String {

    var conslePrintString: String {

        guard let data = "\""
            .appending(
                replacingOccurrences(of: "\\u", with: "\\U")
                    .replacingOccurrences(of: "\"", with: "\\\"")
            )
            .appending("\"")
            .data(using: .utf8) else {

            return self
        }

        guard let propertyList = try? PropertyListSerialization.propertyList(from: data,
                                                                             options: [],
                                                                             format: nil) else {
            return self
        }

        guard let string = propertyList as? String else {
            return self
        }

        return string.replacingOccurrences(of: "\\r\\n", with: "\n")
    }
}

let code in extension String and it works fine 

let string = "\(jsonDictionary)".conslePrintString

디버깅할 때 Codable Protocol을 준수하는 구조체를 콘솔에 출력합니다.
json 형식을 사용합니다.

extension Encodable {
    var jsonData: Data? {
        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        return try? encoder.encode(self)
    }
}

extension Encodable where Self: CustomDebugStringConvertible {
    var debugDescription: String {
         if let data = self.jsonData,
             let string = String(data: data, encoding: .utf8) {
             return string
         }
         return "can not convert to json string"
     }
}

strcut 적합 사용자 지정 디버그 문자열변환 가능

struct Test: Codable, CustomDebugStringConvertible {
    let a: String
    let b: Int
}

let t = Test(a: "test string", b: 30)

디버그 인쇄 구조

(lldb) p print(t)
{
  "a" : "test string",
  "b" : 30
}

데이터 개체에서 인쇄:

let jsonObj = try JSONSerialization.jsonObject(with: data, options: [])
            let jsonData = try JSONSerialization.data(withJSONObject: jsonObj, options: [.prettyPrinted])
            print(String(data: jsonData, encoding: .utf8)!)
 print("{")
    for (key,value) in dictionary {
        if let stringValue = value as? String {
            print("\"\(key)\" = \"\(stringValue.description)\",")
        }else{
            print("\"\(key)\" = \(value),")
        }
    }
    print("}")

언급URL : https://stackoverflow.com/questions/38773979/is-there-a-way-to-pretty-print-swift-dictionaries-to-the-console

반응형