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


92
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에서 각 키-값 쌍이 새 줄을 차지하는 예쁜 인쇄 사전으로 가져 오는 방법이 있습니까?


7
dump예를 들어 목표가 사전을 검사하는 경우를 사용할 수 있습니다 . stackoverflow.com/documentation/swift/3966/logging-in-swift/…
Eric Aya

13
print(dictionary as! NSDictionary) 가벼운 속임수?
BaseZen

코드를 작성하거나 캐스트 할 필요가 없기 때문에 실제로 dump () 제안입니다. @EricAya, 그 발언과 함께 답변을 게시하면 답변으로 표시하겠습니다.
Toland Hon

1
@TolandHon 완료. 출력 예를 들어 답했습니다.
Eric Aya

답변:


99

예를 들어 목표가 사전을 검사하는 경우 dump를 사용할 수 있습니다 . dumpSwift의 표준 라이브러리의 일부입니다.

용법:

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)

인쇄물:

▿ 4 개 요소
-[0] : Joe-
[1] : Jane-
[2] : Jim-
[3] : Joyce

사전의 경우 :

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

인쇄물:

▿ 키 / 값 쌍 3 개
▿ [0] : (2 개 요소)
- .0 : bar
-.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 개의 키 / 값 쌍
▿ [0] : (2 개 요소)
- .0 : bar
-.1 : 33
▿ [1] : (2 개 요소)
-.0 : baz
-.1 : 42
▿ [2] : (2 요소)
-.0 : foo
-.1 : 10

을 사용하여 특정 수의 항목 만 인쇄 maxItems:하고를 사용하여 특정 깊이까지 개체를 구문 분석 maxDepth:하고을 사용하여 인쇄 된 개체의 들여 쓰기를 변경 하도록 선택할 수도 있습니다 indent:.


5
이것은 꽤 인쇄 된 JSON이 아닙니다. 이것은 유효한 JSON이 아닌 콘솔에 변수를 덤프하는 것입니다. OP의 요구에 적합하지만 질문이 이것과 일치하도록 변경해야한다고 생각합니다.
James Wolfe

4
@JamesWolfe This is not pretty printed JSON아무도 그렇게 말하지 않았습니다. OP는 예쁜 인쇄 Swift 사전에 대해 물었습니다. 주제를 벗어난 응답자를 제외하고는 아무도 JSON에 대해 이야기하지 않습니다. OP의 질문은 JSON에 관한 것이 아닙니다.
Eric Aya

@JamesWolfe 또한 질문을 변경하지 마십시오. 그것은 기물 파손 일 것입니다. 질문은 명확하며 JSON에 관한 것이 아닙니다. 일부 답변이 다른 것에 대해 이야기한다고해서 질문을 변경하지 마십시오. 감사.
Eric Aya

112

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

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

이것은 콘솔 출력입니다

이것은 덤프 옵션보다 읽기 쉽지만 총 키-값 수를 제공하지는 않습니다.


11
그것은 덤프보다 훌륭한 방법과 방법입니다
AbdelHady

109

PO 솔루션

콘솔 에서 이스케이프 시퀀스가없는 JSON으로 Dictionary를보고 싶은 분 여기에 간단한 방법이 있습니다.

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


1
은 객체가 아니라 표현식이므로 'po'가 아닌 'p'여야합니다. 그러나이 솔루션에 대해 대단히 감사합니다! 나를 위해 잘 작동
알레산드로 Francucci

@AlessandroFrancucci가 중요합니까? 명령은 어느 쪽이든 동일한 작업을 수행하는 것 같습니다.
nickjwallin

이제 두 가지 방법 모두 작동합니다. 그러나 "po print"를하기 전에는 저에게 효과가 없었습니다. (po는 인쇄 개체를 의미합니다 .... 나중에 인쇄물이 있고 개체 imho가 아니라면 약간 혼란 스럽습니다.)
Alessandro Francucci 2018

대박! PushNotification에서 userInfo를 좋은 방식으로 인쇄하는 데 필요한 것
carmen_munich

이 주석 을 확인 하여 lldb 별칭에서이를 활용하면 매번 입력 할 필요가 없습니다!
agirault

36

함수형 프로그래밍을 사용하는 또 다른 방법

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

산출

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

1
이것이 최고의 답변이어야합니다. 완벽하게 작동합니다!
Yuri Doubov

또는 "더 많은 기능"이 될 수 있습니다 ... dictionary.map { "($ 0) : ($ 1)"} .forEach (인쇄) (혀 -에 - 뺨 주석)
존 윌리스

3
이것은 OP의 [String: String]딕셔너리에서 작동 하지만 [AnyHashable: Any], 값이 딕셔너리라면 Swift의 예쁘지 않은 인쇄로 돌아가는 딕셔너리에는 적합하지 않습니다.
Christopher Pickslay

나는 아직도이 구문 🙄 기억할 수 없기 때문에 나는이 answer🙂을 표시 책 한
니틴 Alabur

29

디버그 목적으로 만 Array 또는 Dictionary를 예쁜 인쇄 된 json으로 변환합니다.

public extension Collection {

    /// Convert self to JSON String.
    /// Returns: the pretty printed JSON string or an empty string if any error occur.
    func json() -> String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
            return String(data: jsonData, encoding: .utf8) ?? "{}"
        } catch {
            print("json serialization error: \(error)")
            return "{}"
        }
    }
}

그때:

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
}

여기서 bLog는 무엇입니까?
Nitesh

@Nitesh bLog는 내가 작성한 backtrace가있는 간단한 사용자 지정 로거로 print ()로 편집했습니다.
Marco M

가장 아름다운 솔루션.
Denis Kutlubaev

각 프로젝트에서 해당 코드 스 니펫을 추가하지 않으려면 lldb 별칭과 함께 해당 코드를 활용하여 디버그 터미널에서 json을 쉽게 계산할 수 있습니다 (자세한 내용은 여기 ).
agirault

14

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에 의해 콘솔에 튀어 나온 끔찍한 형식보다 데이터에 대해 훨씬 더 읽기 쉬운 형식이므로 실행 가능한 대답이라고 생각합니다.


1
고마워요, 이것으로 저는 디버깅 중에 꽤 인쇄 할 수있었습니다 e let jsonData = try! JSONSerialization.data(withJSONObject: response, options: .prettyPrinted);if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }
BangOperator

1
이것은 대단합니다! lldb 별칭과 함께이 코드를 활용하여 디버그 터미널에서 json을 쉽게 계산할 수 있습니다 (자세한 내용은 여기 ).
agirault

5

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 플레이 그라운드에서 테스트 됨) :

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

1
prettyprint를 함수 대신 var로 만든 이유가 있습니까?
Hayden Holligan

솔직히, 나는 그것이 중요하지 않다고 생각합니다 (나는 틀릴 수 있습니다). 그러나 많이 사용하면 입력하는 것이 적습니다. 그러나 흥미로운 질문을 제기하십시오.
Asdrubal

3
거기있어 때문에 description그리고 debugDescription이미 VAR를 호출하는 것이 더 적합 할 수 있습니다 prettyDescription포맷 된 문자열을 반환합니다.
Toland Hon

5

Swift Dictionary를 json으로 변환하는 방법은 가장 간단합니다. 나는 pjson 이있는 Facebook의 을 사용합니다.Swift 사전을 인쇄하기 위해 명령 합니다. 예 :

(lldb) pjson dict as NSDictionary

이것은 사전을 예쁘게 인쇄해야합니다. 이것은 이미 제안 된 작업을 수행하는 훨씬 더 깨끗한 방법입니다. 추신 : Objective-C 런타임은 Swift 사전을 이해하지 못하기 때문에 지금은 dict를 NSDictionary로 캐스팅해야합니다. 나는 이미 그 제한을 없애기 위해 끌에 대한 PR을 올렸습니다.

업데이트 : 내 PR이 수락되었습니다. 이제 위에서 언급 한 pjson 대신 psjson 명령을 사용할 수 있습니다 .


4

들어 스위프트 3 (&로 화려한 답변을 구축 @Jalakoo ), 다음 수 있도록 Dictionary확장 :

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

다음의 사전 인쇄 어떤 계층 구조를 A의 (보다 나은 방법 dump()이 사용) :

print(dictionary!.prettyPrint)

4

세부

  • 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")

결과

여기에 이미지 설명 입력


2

여기 내 다른 답변을 기반으로 조정 되었습니다 .

LLDB 별칭을 사용하는 PrettyPrint JSON 솔루션

코드가 필요하지 않습니다

  • 멋진 json 형식 (들여 쓰기, 줄 바꿈 등)을 얻으려면 lldb 터미널 ( source ) 에서 다음 명령을 실행하여 lldb 별칭을 정의 할 수 있습니다 .
command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'
  • XCode를 열 때마다 별칭을 다시 정의하고 싶지 않을 것이므로 다음 명령을 실행하여 별칭 정의를에 추가합니다 ~/.lldbinit.
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 : 423 : 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"])


1

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

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 준수 CustomDebugStringConvertible

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
}

1

데이터 개체에서 예쁜 인쇄 :

let jsonObj = try JSONSerialization.jsonObject(with: data, options: [])
            let jsonData = try JSONSerialization.data(withJSONObject: jsonObj, options: [.prettyPrinted])
            print(String(data: jsonData, encoding: .utf8)!)

1
이것은 대단합니다! lldb 별칭과 함께이 코드를 활용하여 디버그 터미널에서 json을 쉽게 계산할 수 있습니다 (자세한 내용은 여기 ).
agirault

0

어때 :

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)

0
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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.