有没有办法将Swift词典打印到控制台?

时间:2016-08-04 17:37:25

标签: ios swift xcode

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中有没有办法将它用于漂亮的打印字典,其中每个键值对占用一个新行?

17 个答案:

答案 0 :(得分:67)

例如,如果目标是检查字典,则可以使用dumplet dictionary: [String : String] = ["A" : "alfa", "B" : "bravo", "C" : "charlie", "D" : "delta", "E" : "echo", "F" : "foxtrot"] dump(dictionary) 是Swift标准库的一部分。

用法:

dump

输出:

enter image description here

let names = ["Joe", "Jane", "Jim", "Joyce"] dump(names) 通过反射(镜像)打印对象的内容。

数组的详细视图:

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

打印:

  

▿4个元素
     - [0]:乔
     - [1]:简
     - [2]:吉姆      - [3]:乔伊斯

字典:

dump

打印:

  

▿3个键/值对
    ▿[0] :( 2个元素)
       - .0:bar
       - .1:33
    ▿[1] :( 2个元素)
       - .0:baz
       - .1:42
    ▿[2] :( 2个元素)
       - .0:foo
       - .1:10

dump(_:name:indent:maxDepth:maxItems:)被声明为name

第一个参数没有标签。

还有其他可用参数,例如dump(attributes, name: "mirroring") 为被检查对象设置标签:

maxItems:

打印:

  

▿镜像:3个键/值对
    ▿[0] :( 2个元素)
       - .0:bar
       - .1:33
    ▿[1] :( 2个元素)
       - .0:baz
       - .1:42
    ▿[2] :( 2个元素)
       - .0:foo
       - .1:10

您还可以选择仅使用maxDepth:打印一定数量的项目,使用indent:将对象解析到某个深度,并使用{{1更改打印对象的缩进}}

答案 1 :(得分:63)

SWIFT 3

将字典转换为' AnyObject'对我来说是最简单的解决方案:

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

enter image description here

这比转储选项更容易阅读,但请注意,它不会为您提供键值的总数。

答案 2 :(得分:56)

po解决方案

对于那些想要在控制台中看到带有转义序列的字典为JSON的人,这是一种简单的方法

(LLDB)In [234]: a = np.arange(0,10) ...: aa = np.arange(4,42) ...: y = 6 ...: In [235]: out Out[235]: array([[10, 11, 12, 13, 25, 40], [11, 12, 13, 14, 26, 41], [12, 13, 14, 15, 27, 0], [13, 14, 15, 16, 28, 0], [14, 15, 16, 17, 29, 0], [15, 16, 17, 18, 30, 0], [16, 17, 18, 19, 31, 0], [17, 18, 19, 20, 32, 0], [18, 19, 20, 21, 33, 0], [19, 20, 21, 22, 34, 0]])

答案 3 :(得分:30)

使用函数式编程的另一种方法

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

输出

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

答案 4 :(得分:17)

仅出于调试目的,我将数组或字典转换为漂亮的json:

public extension Collection {

    /// Convert self to JSON String.
    /// - Returns: Returns the JSON as String or empty string if error while parsing.
    func json() -> String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
            guard let jsonString = String(data: jsonData, encoding: String.Encoding.utf8) else {
                print("Can't create string with data.")
                return "{}"
            }
            return jsonString
        } catch let parseError {
            print("json serialization error: \(parseError)")
            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
}

答案 5 :(得分:6)

我不会考虑这里提供的很多答案真正的印刷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吐出到控制台中的可怕格式。

答案 6 :(得分: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 beta 2 Playground中测试):

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

答案 7 :(得分:4)

For Swift 3 (& building on the brilliant answer by @Jalakoo), make the following Dictionary extension:

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

then print a dictionary of any hierarchy in a pretty way (better than dump()) using this:

print(dictionary!.prettyPrint)

答案 8 :(得分:3)

根据我的其他答案here进行了调整。

使用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
  • 这将创建pjson别名,您可以在XCode的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"])

答案 9 :(得分:2)

将Swift词典转换为json和back的方法是最好的。我通常使用Facebook的chisel,它有 pjson 命令来打印Swift词典。 例如:

(lldb) pjson dict as NSDictionary

这应该打印字典。这是一种更清洁的方式来做已经建议的事情。 附: 目前,您必须将dict转换为NSDictionary,因为Objective-C运行时并不了解Swift词典。我已经用凿子提出了PR来摆脱这种限制。

答案 10 :(得分:1)

从数据对象中打印出精美图片:

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

答案 11 :(得分:1)

调试时,将符合Codable协议的结构输出到控制台
使用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符合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
}

答案 12 :(得分:0)

语言:Objective-C


<块引用>

NSString+PrettyPrint.h

@interface NSString (PrettyPrint)

+ (NSString * _Nonnull)prettifiedJsonStringFromData:(nullable NSData *)data;
+ (NSString * _Nonnull)prettifiedStringFromDictionary:(nullable NSDictionary *)dictionary;

@end

<块引用>

NSString+PrettyPrint.m

#import "NSString+PrettyPrint.h"

@implementation NSString (Print)

+ (NSString *)prettifiedStringFromDictionary:(nullable NSDictionary *)dictionary {
    
    if (dictionary == nil) { return @"nil"; }
    
    NSMutableString *returnStr = [NSMutableString stringWithString:@"[ \n"];
    
    for (NSString *key in dictionary) {
        [returnStr appendFormat:@"  %@: %@,\n", key, [dictionary valueForKey:key]];
    }

    [returnStr appendFormat:@"]"];

    return returnStr;
}

+ (NSString *)prettifiedJsonStringFromData:(nullable NSData *)data {
    
    if (data == nil) { return @"nil"; }
    
    NSData *jsonData;
    NSError *error = nil;
    
    NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:&error];
    if (jsonObject == nil) {
        return @"nil (json object from data)";
    } else {
        BOOL isValidJsonObject = [NSJSONSerialization isValidJSONObject:jsonObject];
        if (isValidJsonObject) {
            NSData *finalData = [NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:&error];
            //TODO: error description
            NSString *prettyJson = [[NSString alloc] initWithData:finalData encoding:NSUTF8StringEncoding];
            return prettyJson;
        } else {
            return [NSString stringWithFormat:@"%@\n%@", jsonStr, @" (⚠️ Invalid json object ⚠️)\n"];
        }
    }
}

@end

然后在需要使用方法时调用它们。

ex1。为正文、响应等打印 NSData

NSLog(@"body: %@", [NSString prettifiedJsonStringFromData:[request HTTPBody]]);

ex2。打印 NSDictionary

NSLog(@"headers: %@", [NSString prettifiedStringFromDictionary:[request allHTTPHeaderFields]]);

可能你会在日志中得到这些结果。

enter image description here

enter image description here

答案 13 :(得分:0)

swift 5,xcode 10.3:

po print(<your Plist container>)

答案 14 :(得分:0)

详细信息

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

结果

enter image description here

答案 15 :(得分: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

答案 16 :(得分: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)