Newer
Older
Productization_H5_IOS / template / Common / Tool / SYLog.swift
@zhangfeng zhangfeng on 8 Aug 2023 5 KB commit first
//
//  SYLog.swift
//  syApp
//

import Foundation

protocol SYLogProtocol {
    func myDescription(level: Int) -> String
}

public func SYLog<N>(_ message: N, fileName: String = #file, methodName: String = #function, line: Int = #line) {
    #if DEBUG
    if message is [String: Any] {
        print("\(Date().dateToString("HH:mm:ss.SSS")) \((fileName as NSString).lastPathComponent)-\(methodName)-line:\(line)\n \((message as? [String: Any])?.myDescription(level: 0) ?? "")")
        } else if message is [Any] {
            print("\(Date().dateToString("HH:mm:ss.SSS")) \((fileName as NSString).lastPathComponent)-\(methodName)-line:\(line)\n \((message as? [Any])?.myDescription(level: 0) ?? "")")
        } else {
            print("\(Date().dateToString("HH:mm:ss.SSS")) \((fileName as NSString).lastPathComponent)-\(methodName)-line:\(line)\n \(message)")
        }
    #endif
}

// MARK: - 重写字典型description
extension Dictionary: SYLogProtocol {
    public var description: String {
        var str = ""
        str.append(contentsOf: "{\n")
        for (key, value) in self {
            if value is String {
                let s = value as? String ?? ""
                str.append(contentsOf: String(format: "\t%@ = \"%@\",\n", key as? CVarArg ?? "", s.unicodeStr))
            } else if value is Dictionary {
                str.append(contentsOf: String(format: "\t%@ = \"%@\",\n", key as? CVarArg ?? "", (value as? Dictionary)?.description ?? ""))
            } else if value is [Any] {
                str.append(contentsOf: String(format: "\t%@ = \"%@\",\n", key as? CVarArg ?? "", (value as? [Any])?.description ?? ""))
            } else {
                str.append(contentsOf: String(format: "\t%@ = \"%@\",\n", key as? CVarArg ?? "", "\(value)"))
            }
        }
        str.append(contentsOf: "}")
        return str
    }

    func myDescription(level: Int) -> String {
        var str = ""
        var tab = ""
        for _ in 0 ..< level {
            tab.append(contentsOf: "\t")
        }
        str.append(contentsOf: "{\n")
        for (key, value) in self {
            if value is String {
                let s = value as? String ?? ""
                str.append(contentsOf: String(format: "%@\t%@ = \"%@\",\n", tab, key as? CVarArg ?? "", s.unicodeStrWith(level: level)))
            } else if value is Dictionary {
                str.append(contentsOf: String(format: "%@\t%@ = %@,\n", tab, key as? CVarArg ?? "", (value as? Dictionary)?.myDescription(level: level + 1) ?? ""))
            } else if value is [Any] {
                str.append(contentsOf: String(format: "%@\t%@ = %@,\n", tab, key as? CVarArg ?? "", (value as? [Any])?.myDescription(level: level + 1) ?? ""))
            } else {
                str.append(contentsOf: String(format: "%@\t%@ = %@,\n", tab, key as? CVarArg ?? "", "\(value)"))
            }
        }
        str.append(contentsOf: String(format: "%@}", tab))
        return str
    }
}

extension Array: SYLogProtocol {
    func myDescription(level: Int) -> String {
        var str = ""
        var tab = ""
        str.append(contentsOf: "[\n")
        for _ in 0 ..< level {
            tab.append(contentsOf: "\t")
        }
        for value in self {
            if value is String {
                let s = value as? String ?? ""
                str.append(contentsOf: String(format: "%@\t\"%@\",\n", tab, s.unicodeStrWith(level: level)))
            } else if value is [String: Any] {
                str.append(contentsOf: String(format: "%@\t%@,\n", tab, (value as? [String: Any])?.myDescription(level: level + 1) ?? ""))
            } else if value is [Any] {
                str.append(contentsOf: String(format: "%@\t%@,\n", tab, (value as? [Any])?.myDescription(level: level + 1) ?? ""))
            } else {
                str.append(contentsOf: String(format: "%@\t%@,\n", tab, "\(value)"))
            }
        }
        str.append(contentsOf: String(format: "%@ ]", tab))
        return str
    }

    public var description: String {
        var str = ""
        str.append(contentsOf: "[\n")
        for value in self {
            if value is String {
                let s = value as? String ?? ""
                str.append(contentsOf: String(format: "\t\"%@\",\n", s.unicodeStr))
            } else if value is [String: Any] {
                str.append(contentsOf: String(format: "\t%@,\n", (value as? [String: Any] ?? [String: Any]()).description))
            } else if value is [Any] {
                str.append(contentsOf: String(format: "\t%@,\n", (value as? [Any] ?? [Any]()).description))
            } else {
                str.append(contentsOf: String(format: "\t%@,\n", "\(value)"))
            }
        }
        str.append(contentsOf: "]")
        return str
    }
}

// MARK: - unicode转码
extension String {
    func unicodeStrWith(level: Int) -> String {
        let s = self
        let data = s.data(using: .utf8)
        if let data = data {
            if let id = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) {
                if id is [Any] {
                    return (id as? [Any])?.myDescription(level: level + 1) ?? ""
                } else if id is [String: Any] {
                    return (id as? [String: Any])?.myDescription(level: level + 1) ?? ""
                }
            }
        }
        let tempStr1 = self.replacingOccurrences(of: "\\u", with: "\\U")
        let tempStr2 = tempStr1.replacingOccurrences(of: "\"", with: "\\\"")
        let tempStr3 = "\"".appending(tempStr2).appending("\"")
        let tempData = tempStr3.data(using: String.Encoding.utf8)
        var returnStr: String = ""
        do {
            returnStr = try PropertyListSerialization.propertyList(from: tempData!, options: [.mutableContainers], format: nil) as? String ?? ""
        } catch {
            print(error)
        }
        return returnStr.replacingOccurrences(of: "\\r\\n", with: "\n")
    }

    var unicodeStr: String {
        return self.unicodeStrWith(level: 1)
    }
}