iOS 更好用的打Log方式-显示文件名、行数

Object-C版本,将下面代码添加到全局header文件中

#ifdef DEBUG
#   define DDLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#   define DDLog(...)
#endif

Swift版本 创建一个Swift文件:DDLog.swift

import Foundation

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

//封装的日志输出功能(T表示不指定日志信息参数类型)
public func DDLog(_ message:T, file:String = #file, function:String = #function,
              line:Int = #line) {
    #if DEBUG
    let fileName = (file as NSString).lastPathComponent
    if message is Dictionary {
        print("[\(fileName):line:\(line)]- \((message as! Dictionary).myDescription(level: 0))")
    }else if message is Array {
        print("[\(fileName):line:\(line)]- \((message as! Array ).myDescription(level: 0))")
    }else if message is CustomStringConvertible {
        print("[\(fileName):line:\(line)]- \((message as! CustomStringConvertible).description)")
    }else {
        print("[\(fileName):line:\(line)]- \(message)")
    }
    
    #endif
}

public func DDDLog(_ messsage : T, file : String = #file, funcName : String = #function, lineNum : Int = #line) {
    
    #if DEBUG
    
    let fileName = (file as NSString).lastPathComponent
    
    print("\(fileName):行号(\(lineNum))-\(messsage)")
    
    #endif
}



// MARK: - 重写可选型description
extension Optional: CustomStringConvertible {
    public var description: String {
        switch self {
        case .none:
            return "Optional(null)"
        case .some(let obj):
            if let obj = obj as? CustomStringConvertible, obj is Dictionary {
                return "Optional:" + "\((obj as! Dictionary).myDescription(level: 0))"
            }
            if let obj = obj as? CustomStringConvertible, obj is Array {
                return "Optional:" + "\((obj as! Array).myDescription(level: 0))"
            }
            return  "Optional" + "(\(obj))"
        }
    }
}

// MARK: - 重写字典型description
extension Dictionary: LogLevel {
    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.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, s.unicodeStr))
            }else if value is Dictionary {
                str.append(contentsOf: String.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, (value as! Dictionary).description))
            }else if value is Array {
                str.append(contentsOf: String.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, (value as! Array).description))
            }else {
                str.append(contentsOf: String.init(format: "\t%@ = \"%@\",\n", key as! CVarArg, "\(value)"))
            }
        }
        str.append(contentsOf: "}")
        return str
    }
    
   public func myDescription(level: Int) -> String{
        var str = ""
        var tab = ""
        for _ in 0.. {
                str.append(contentsOf: String.init(format: "%@\t%@ = %@,\n", tab, key as! CVarArg, (value as! Array).myDescription(level: level + 1)))
            }else {
                str.append(contentsOf: String.init(format: "%@\t%@ = %@,\n", tab, key as! CVarArg, "\(value)"))
            }
        }
        str.append(contentsOf: String.init(format: "%@}", tab))
        return str
    }
}

extension Array: LogLevel {
    public func myDescription(level: Int) -> String {
        var str = ""
        var tab = ""
        str.append(contentsOf: "[\n")
        for _ in 0.. {
                str.append(contentsOf: String.init(format: "%@\t%@,\n", tab, (value as! Dictionary).myDescription(level: level + 1)))
            }else if value is Array {
                str.append(contentsOf: String.init(format: "%@\t%@,\n", tab, (value as! Array).myDescription(level: level + 1)))
            }else {
                str.append(contentsOf: String.init(format: "%@\t%@,\n", tab, "\(value)"))
            }
        }
        str.append(contentsOf: String.init(format: "%@]", tab))
        return str
    }
    
    public var description: String {
        var str = ""
        str.append(contentsOf: "[\n")
        for (_, value) in self.enumerated() {
            if value is String {
                let s = value as! String
                str.append(contentsOf: String.init(format: "\t\"%@\",\n", s.unicodeStr))
            }else if value is Dictionary {
                str.append(contentsOf: String.init(format: "\t%@,\n", (value as! Dictionary).description))
            }else if value is Array {
                str.append(contentsOf: String.init(format: "\t%@,\n", (value as! Array).description))
            }else {
                str.append(contentsOf: String.init(format: "\t%@,\n", "\(value)"))
            }
        }
        str.append(contentsOf: "]")
        return str
    }
}

// MARK: - unicode转码
extension String {
   public 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 Array {
                    return (id as! Array).myDescription(level: level + 1)
                }else if id is Dictionary {
                    return (id as! Dictionary).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")
    }
    public var unicodeStr:String {
        return self.unicodeStrWith(level: 1)
    }
}

你可能感兴趣的:(iOS 更好用的打Log方式-显示文件名、行数)