├── .gitignore ├── BLoger.podspec ├── BLoger ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── BLogAutoTask.swift │ ├── BLogDefine.swift │ ├── BLogFormatter.swift │ ├── BLogView.swift │ ├── BLoger.swift │ └── ViewController+ShankExt.swift ├── Example ├── BLoger.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── BLoger-Example.xcscheme ├── BLoger.xcworkspace │ └── contents.xcworkspacedata ├── BLoger │ ├── AppDelegate.swift │ ├── BLogExt.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── icon-1.png │ │ │ ├── icon-1024.png │ │ │ ├── icon-2.png │ │ │ ├── icon-3.png │ │ │ └── icon.png │ ├── Info.plist │ └── ViewController.swift ├── Podfile └── Podfile.lock ├── LICENSE ├── README.md └── _Pods.xcodeproj /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | Pods/ 38 | -------------------------------------------------------------------------------- /BLoger.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint BLoger.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'BLoger' 11 | s.version = '2.0.1' 12 | s.summary = 'A Loger Demo of CocoaLumberjack/Swift' 13 | s.swift_version = '4.0' 14 | 15 | s.description = <<-DESC 16 | A Loger Demo of CocoaLumberjack Swift. 17 | DESC 18 | 19 | s.homepage = 'https://github.com/iosBob/BLoger' 20 | s.license = { :type => 'MIT', :file => 'LICENSE' } 21 | s.author = { 'linbo' => 'ok@linbok.com' } 22 | s.source = { :git => 'https://github.com/iosBob/BLoger.git', :tag => s.version.to_s } 23 | 24 | s.ios.deployment_target = '8.0' 25 | s.source_files = 'BLoger/Classes/**/*' 26 | 27 | s.frameworks = 'UIKit', 'Foundation' 28 | s.dependency 'CocoaLumberjack/Swift' 29 | s.dependency 'SnapKit' 30 | 31 | end 32 | -------------------------------------------------------------------------------- /BLoger/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rocket2048/BLoger/694c683148849f6457982dd8d1549f2eadc2bc3f/BLoger/Assets/.gitkeep -------------------------------------------------------------------------------- /BLoger/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rocket2048/BLoger/694c683148849f6457982dd8d1549f2eadc2bc3f/BLoger/Classes/.gitkeep -------------------------------------------------------------------------------- /BLoger/Classes/BLogAutoTask.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BLogAutoTask.swift 3 | // BLoger 4 | // 5 | // Created by lin bo on 2019/3/20. 6 | // Copyright © lin bo. All rights reserved. 7 | // 8 | 9 | // 定时器每秒随机生成一条数据 10 | import UIKit 11 | 12 | public class BLogAutoTask { 13 | 14 | public static let shared = BLogAutoTask() 15 | 16 | public private(set) var started = false 17 | 18 | fileprivate var timer: Timer? 19 | 20 | /// 开始自动输出(请测试的时候下使用,无实际意义) 21 | /// 22 | /// - Parameter interval: 间隔 23 | public func start(_ interval: TimeInterval = 1.0) { 24 | 25 | stop() 26 | 27 | started = true 28 | timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(repet), userInfo: nil, repeats: true) 29 | timer?.fire() 30 | } 31 | 32 | /// 停止 33 | public func stop() { 34 | 35 | started = false 36 | if timer != nil { 37 | timer?.invalidate() 38 | timer = nil 39 | } 40 | } 41 | 42 | @objc private func repet() { 43 | 44 | let random = arc4random() % 7 45 | 46 | switch random { 47 | case 0: 48 | BLog("\(random)") 49 | case 1: 50 | BLog_v("\(random)") 51 | case 2: 52 | BLog_d("\(random)") 53 | case 3: 54 | BLog_i("\(random)") 55 | case 4: 56 | BLog_w("\(random)") 57 | case 5: 58 | BLog_e("\(random)") 59 | default: 60 | BLog("\(random)") 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /BLoger/Classes/BLogDefine.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BLogDefine.swift 3 | // BLoger 4 | // 5 | // Created by lin bo on 2019/3/21. 6 | // Copyright © 2019 lin bo. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CocoaLumberjack 11 | 12 | public let DDDefaultLogLevel: DDLogLevel = .all 13 | 14 | /// Common 15 | fileprivate func _BLog(_ message: @autoclosure () -> String, 16 | level: DDLogLevel = DDDefaultLogLevel, 17 | flag: DDLogFlag, 18 | context: Int = 0, 19 | file: StaticString = #file, 20 | function: StaticString = #function, 21 | line: UInt = #line, 22 | tag: Any? = nil, 23 | asynchronous async: Bool = false, 24 | ddlog: DDLog = .sharedInstance) { 25 | 26 | _DDLogMessage(message, level: level, flag: flag, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) 27 | } 28 | 29 | /// Default (Verbose) 30 | public func BLog(_ message: @autoclosure () -> String = "-", 31 | level: DDLogLevel = DDDefaultLogLevel, 32 | context: Int = 0, 33 | file: StaticString = #file, 34 | function: StaticString = #function, 35 | line: UInt = #line, 36 | tag: Any? = nil, 37 | asynchronous async: Bool = false, 38 | ddlog: DDLog = .sharedInstance) { 39 | _BLog(message, level: level, flag: .verbose, context: context, file: file, function: function, line: line, tag: "none", asynchronous: async, ddlog: ddlog) 40 | } 41 | 42 | /// Verbose 43 | public func BLog_v(_ verbose: @autoclosure () -> String = "-", 44 | level: DDLogLevel = DDDefaultLogLevel, 45 | context: Int = 0, 46 | file: StaticString = #file, 47 | function: StaticString = #function, 48 | line: UInt = #line, 49 | tag: Any? = nil, 50 | asynchronous async: Bool = false, 51 | ddlog: DDLog = .sharedInstance) { 52 | _BLog(verbose, level: level, flag: .verbose, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) 53 | } 54 | 55 | /// Debug 56 | public func BLog_d(_ debug: @autoclosure () -> String = "-", 57 | level: DDLogLevel = DDDefaultLogLevel, 58 | context: Int = 0, 59 | file: StaticString = #file, 60 | function: StaticString = #function, 61 | line: UInt = #line, 62 | tag: Any? = nil, 63 | asynchronous async: Bool = false, 64 | ddlog: DDLog = .sharedInstance) { 65 | _BLog(debug, level: level, flag: .debug, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) 66 | } 67 | 68 | /// Info 69 | public func BLog_i(_ info: @autoclosure () -> String = "-", 70 | level: DDLogLevel = DDDefaultLogLevel, 71 | context: Int = 0, 72 | file: StaticString = #file, 73 | function: StaticString = #function, 74 | line: UInt = #line, 75 | tag: Any? = nil, 76 | asynchronous async: Bool = false, 77 | ddlog: DDLog = .sharedInstance) { 78 | _BLog(info, level: level, flag: .info, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) 79 | } 80 | 81 | /// Warning 82 | public func BLog_w(_ warning: @autoclosure () -> String = "-", 83 | level: DDLogLevel = DDDefaultLogLevel, 84 | context: Int = 0, 85 | file: StaticString = #file, 86 | function: StaticString = #function, 87 | line: UInt = #line, 88 | tag: Any? = nil, 89 | asynchronous async: Bool = false, 90 | ddlog: DDLog = .sharedInstance) { 91 | _BLog(warning, level: level, flag: .warning, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) 92 | } 93 | 94 | /// Error 95 | public func BLog_e(_ error: @autoclosure () -> String = "-", 96 | level: DDLogLevel = DDDefaultLogLevel, 97 | context: Int = 0, 98 | file: StaticString = #file, 99 | function: StaticString = #function, 100 | line: UInt = #line, 101 | tag: Any? = nil, 102 | asynchronous async: Bool = false, 103 | ddlog: DDLog = .sharedInstance) { 104 | _BLog(error, level: level, flag: .error, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) 105 | } 106 | -------------------------------------------------------------------------------- /BLoger/Classes/BLogFormatter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BLogFormatter.swift 3 | // BLoger 4 | // 5 | // Created by lin bo on 2019/2/13. 6 | // Copyright © 2019 lin bo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import CocoaLumberjack 11 | 12 | enum BLogFlag: String { 13 | 14 | case verbose = "1" 15 | case debug = "2" 16 | case info = "3" 17 | case warning = "4" 18 | case error = "5" 19 | case none = "0" 20 | 21 | public var flag: String { 22 | 23 | switch self { 24 | case .verbose: 25 | return "🍏" 26 | case .debug: 27 | return "🛠" 28 | case .info: 29 | return "🥏" 30 | case .warning: 31 | return "⚠️" 32 | case .error: 33 | return "🚫" 34 | case .none: 35 | return "➡️" 36 | } 37 | } 38 | 39 | /// 返回一个简化的标记 40 | public static func flag(_ log: DDLogMessage) -> BLogFlag { 41 | 42 | if let tag = log.tag as? String, tag == "none" { 43 | return BLogFlag.none 44 | } 45 | 46 | let flag = log.flag 47 | 48 | switch flag { 49 | case DDLogFlag.verbose: 50 | return BLogFlag.verbose 51 | case DDLogFlag.debug: 52 | return BLogFlag.debug 53 | case DDLogFlag.info: 54 | return BLogFlag.info 55 | case DDLogFlag.warning: 56 | return BLogFlag.warning 57 | case DDLogFlag.error: 58 | return BLogFlag.error 59 | default: 60 | return BLogFlag.none 61 | } 62 | } 63 | 64 | /// 时间格式 65 | static fileprivate func dateToLocalStr(_ date: Date) -> String { 66 | 67 | let formatter = DateFormatter() 68 | formatter.dateStyle = .full 69 | formatter.dateFormat = "yyMMdd.HHmmss" 70 | 71 | return formatter.string(from: date) 72 | } 73 | 74 | /// 方法名简化 75 | static fileprivate func funcCut(_ funcStr: String?) -> String { 76 | 77 | guard let funcStr = funcStr else { 78 | return "-" 79 | } 80 | 81 | guard let range = funcStr.range(of: "(") else { 82 | return funcStr 83 | } 84 | 85 | return String(funcStr[funcStr.startIndex ..< range.lowerBound]) 86 | } 87 | } 88 | 89 | class BLogFormatter: NSObject, DDLogFormatter { 90 | 91 | // 继承 重写格式 92 | func format(message logMessage: DDLogMessage) -> String? { 93 | 94 | let funcStr = BLogFlag.funcCut(logMessage.function) 95 | 96 | return "\(BLogFlag.flag(logMessage).flag)[\(BLogFlag.flag(logMessage).rawValue) \(logMessage.fileName) \(funcStr) L:\(logMessage.line)] \(logMessage.message)" 97 | } 98 | } 99 | 100 | class JYFileLogFormatter: NSObject, DDLogFormatter { 101 | 102 | // 继承 重写格式 103 | func format(message logMessage: DDLogMessage) -> String? { 104 | 105 | let dateStr = BLogFlag.dateToLocalStr(logMessage.timestamp) 106 | 107 | let funcStr = BLogFlag.funcCut(logMessage.function) 108 | 109 | let message = BLoger.convertMessage(msg: logMessage.message) 110 | 111 | return "\(BLogFlag.flag(logMessage).flag)[\(BLogFlag.flag(logMessage).rawValue) \(dateStr) \(logMessage.fileName) \(funcStr) L:\(logMessage.line)] \(message)" 112 | } 113 | } 114 | 115 | class JYFileLogFormatter2: NSObject, DDLogFormatter { 116 | 117 | // 继承 重写格式 118 | func format(message logMessage: DDLogMessage) -> String? { 119 | 120 | let dateStr = BLogFlag.dateToLocalStr(logMessage.timestamp) 121 | 122 | let funcStr = BLogFlag.funcCut(logMessage.function) 123 | 124 | let message = BLoger.convertMessage(msg: logMessage.message) 125 | 126 | return "\(BLogFlag.flag(logMessage).flag)[\(BLogFlag.flag(logMessage).rawValue) \(dateStr) \(logMessage.fileName) \(funcStr) L:\(logMessage.line)] \(message)" 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /BLoger/Classes/BLogView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BLogView.swift 3 | // BLoger 4 | // 5 | // Created by lin bo on 2019/3/21. 6 | // Copyright © 2019 lin bo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SnapKit 11 | 12 | class BLogView: UIView { 13 | 14 | fileprivate var timer: Timer? // 刷新定时器 15 | fileprivate var autoShowLog: Bool = false // 是否自动刷新日志(状态) 16 | fileprivate var isMoving: Bool = false // 页面正在拖动 17 | 18 | fileprivate var relushTime: UInt = 0 // 10 19 | fileprivate var relushNowTime: UInt = 0 // 0/1/2/3... 20 | 21 | fileprivate let cancelBtn: UIButton = { 22 | 23 | let btn = UIButton.init(type: .custom) 24 | btn.backgroundColor = UIColor.init(white: 0, alpha: 0.6) 25 | btn.setTitleColor(.white, for: .normal) 26 | btn.setTitle("❌", for: .normal) 27 | btn.titleLabel?.font = UIFont.systemFont(ofSize: 12) 28 | btn.addTarget(self, action: #selector(cancelAction(_:)), for: .touchUpInside) 29 | return btn 30 | }() 31 | 32 | fileprivate let midView: UIView = { 33 | 34 | let lb = UILabel() 35 | lb.backgroundColor = UIColor.init(white: 0, alpha: 0.6) 36 | lb.textColor = .white 37 | lb.font = UIFont.systemFont(ofSize: 12) 38 | lb.textAlignment = .center 39 | lb.text = "Drag me" 40 | 41 | let view = UIView() 42 | view .addSubview(lb) 43 | lb.snp.makeConstraints({ (make) in 44 | make.edges.equalToSuperview() 45 | }) 46 | return view 47 | }() 48 | 49 | fileprivate let rightBtn: UIButton = { 50 | 51 | let btn = UIButton.init(type: .custom) 52 | btn.backgroundColor = UIColor.init(white: 0, alpha: 0.6) 53 | btn.setTitleColor(.white, for: .normal) 54 | btn.setTitle("Auto", for: .normal) 55 | btn.titleLabel?.font = UIFont.systemFont(ofSize: 14) 56 | btn.addTarget(self, action: #selector(RefreshAction(_:)), for: .touchUpInside) 57 | return btn 58 | }() 59 | 60 | fileprivate let textView: UITextView = { 61 | 62 | let tv = UITextView() 63 | tv.backgroundColor = .clear 64 | tv.textColor = .white 65 | tv.font = UIFont.systemFont(ofSize: 10) 66 | tv.isEditable = false 67 | return tv 68 | }() 69 | 70 | override init(frame: CGRect) { 71 | 72 | super.init(frame: frame) 73 | 74 | self.layer.cornerRadius = 10 75 | self.layer.masksToBounds = true 76 | 77 | self.backgroundColor = UIColor.init(white: 0, alpha: 0.8) 78 | textView.layoutManager.allowsNonContiguousLayout = false 79 | 80 | addSubview(textView) 81 | addSubview(cancelBtn) 82 | addSubview(midView) 83 | addSubview(rightBtn) 84 | 85 | textView.snp.makeConstraints { (make) in 86 | make.edges.equalToSuperview().inset(2) 87 | } 88 | 89 | cancelBtn.snp.makeConstraints { (make) in 90 | make.left.equalToSuperview().offset(10) 91 | if #available(iOS 11.0, *) { 92 | make.top.equalTo(self.safeAreaLayoutGuide).offset(10) 93 | } else { 94 | make.top.equalToSuperview().offset(10) 95 | } 96 | make.width.height.equalTo(30) 97 | } 98 | 99 | midView.snp.makeConstraints { (make) in 100 | make.left.equalTo(cancelBtn.snp.right).offset(10) 101 | make.height.equalTo(cancelBtn) 102 | make.top.equalTo(cancelBtn) 103 | } 104 | 105 | rightBtn.snp.makeConstraints { (make) in 106 | make.left.equalTo(midView.snp.right).offset(10) 107 | make.right.equalToSuperview().offset(-10) 108 | make.top.equalTo(midView) 109 | make.height.equalTo(midView) 110 | } 111 | } 112 | 113 | required init?(coder aDecoder: NSCoder) { 114 | 115 | super.init(coder: aDecoder) 116 | } 117 | 118 | /// 显示到页面,这是一个单例,若不指定View,默认显示到Window 119 | /// 120 | /// - Parameter inView: 指定View 121 | func show(inView: UIView? = nil) { 122 | 123 | var tmpView: UIView? = inView 124 | if inView == nil { 125 | tmpView = UIApplication.shared.keyWindow 126 | } 127 | 128 | guard let disView = tmpView else { 129 | return 130 | } 131 | 132 | let maxHeight = min(UIScreen.main.bounds.size.width, UIScreen.main.bounds.size.height) - 40 133 | 134 | self.frame = CGRect(x: 0, y: 0, width: min(maxHeight * 0.8, disView.bounds.size.width - 20), height: min(maxHeight, disView.bounds.size.height - 20)) 135 | self.center = disView.center 136 | disView.addSubview(self) 137 | 138 | // 不延迟 会有卡顿 139 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { 140 | self.start() 141 | } 142 | } 143 | 144 | /// 隐藏Log View 145 | func dismiss() { 146 | 147 | self.stop() 148 | self.removeFromSuperview() 149 | } 150 | 151 | @objc fileprivate func cancelAction(_ sender: UIButton) { 152 | 153 | self.removeFromSuperview() 154 | 155 | stop() 156 | } 157 | 158 | @objc fileprivate func RefreshAction(_ sender: UIButton) { 159 | 160 | if autoShowLog { 161 | stop() 162 | sender.setTitle("Auto", for: .normal) 163 | 164 | }else { 165 | start() 166 | sender.setTitle("Stop", for: .normal) 167 | } 168 | } 169 | 170 | fileprivate func start(_ interval: TimeInterval = 10.0) { 171 | 172 | stop() 173 | 174 | relushTime = UInt(interval) 175 | relushNowTime = 0 176 | 177 | autoShowLog = true 178 | timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(repet), userInfo: nil, repeats: true) 179 | timer?.fire() 180 | } 181 | 182 | fileprivate func stop() { 183 | 184 | autoShowLog = false 185 | if timer != nil { 186 | timer?.invalidate() 187 | timer = nil 188 | } 189 | } 190 | 191 | @objc fileprivate func repet() { 192 | 193 | if isMoving { 194 | return 195 | } 196 | 197 | if relushTime > 0 { 198 | 199 | rightBtn.setTitle("\(relushTime - relushNowTime % relushTime)s", for: .normal) 200 | relushNowTime = relushNowTime + 1 201 | if (relushNowTime % relushTime) != 1 { 202 | 203 | return 204 | } 205 | } 206 | 207 | guard let str = BLoger.shared.getNewDoc() else { 208 | return 209 | } 210 | 211 | textView.text = str 212 | textView.scrollRangeToVisible(NSRange.init(location: textView.text.lengthOfBytes(using: .utf8), length: 1)) 213 | } 214 | 215 | func adapterScreen() { 216 | 217 | DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { 218 | 219 | var rect = self.frame 220 | if let superview = self.superview { 221 | rect.origin.x = min(rect.origin.x, superview.bounds.size.width - 100) 222 | rect.origin.y = min(rect.origin.y, superview.bounds.size.height - 60) 223 | } 224 | 225 | rect.origin.x = max(rect.origin.x, -rect.size.width + 100) 226 | rect.origin.y = max(rect.origin.y, 20) 227 | self.frame = rect 228 | } 229 | } 230 | } 231 | 232 | extension BLogView { 233 | 234 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 235 | } 236 | 237 | override func touchesMoved(_ touches: Set, with event: UIEvent?) { 238 | //获取手指 239 | let touch = (touches as NSSet).anyObject() as! UITouch 240 | let nowLocation = touch.location(in: self) 241 | let preLocation = touch.previousLocation(in: self) 242 | 243 | //获取两个手指的偏移量 244 | let offsetX = nowLocation.x - preLocation.x 245 | let offsetY = nowLocation.y - preLocation.y 246 | 247 | var center = self.center 248 | center.x += offsetX 249 | center.y += offsetY 250 | 251 | self.center = center 252 | 253 | isMoving = true 254 | } 255 | 256 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 257 | 258 | adapterScreen() 259 | 260 | isMoving = false 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /BLoger/Classes/BLoger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BLoger.swift 3 | // BLoger 4 | // 5 | // Created by lin bo on 2019/2/13. 6 | // Copyright © 2019 lin bo. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import CocoaLumberjack 12 | 13 | public class BLoger { 14 | 15 | public static let shared = BLoger() 16 | 17 | init() { 18 | 19 | NotificationCenter.default.addObserver(self, selector: #selector(receivedRotation), name: .UIDeviceOrientationDidChange, object: nil) 20 | } 21 | 22 | deinit { 23 | NotificationCenter.default.removeObserver(self) 24 | } 25 | 26 | /// 摇一摇显示 27 | public var shankShow = false 28 | 29 | /// 弹出式LogView 30 | fileprivate var logView: BLogView = { 31 | 32 | let view = BLogView() 33 | return view 34 | }() 35 | 36 | /// 第一个File Logger 所有都接收 37 | public let fileLogger: DDFileLogger = { 38 | 39 | let fileLogger = DDFileLogger() 40 | let fileFormat = JYFileLogFormatter() 41 | fileLogger.logFormatter = fileFormat 42 | 43 | return fileLogger 44 | }() 45 | 46 | /// 第二个File Logger 只接收错误和警告 并长期存储 47 | public let fileLogger2: DDFileLogger = { 48 | 49 | let path = "\(NSHomeDirectory())/Library/Preferences/Logs" 50 | if FileManager.default.fileExists(atPath: path) == false { 51 | try? FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil) 52 | } 53 | 54 | let manager = DDLogFileManagerDefault(logsDirectory: path) 55 | let fileLogger = DDFileLogger.init(logFileManager: manager) 56 | let fileFormat = JYFileLogFormatter2() 57 | fileLogger.logFormatter = fileFormat 58 | 59 | return fileLogger 60 | }() 61 | 62 | /// 控制输出到文件每条的Message最大字符数 63 | private var maxMessageSize: UInt = 0 64 | 65 | /// 开启(配置) 66 | public func start(_ config: BLogConfig = BLogConfig()) { 67 | 68 | let format = BLogFormatter() 69 | /// 下面功能有待确认,请忽略 70 | // DDTTYLogger.sharedInstance.logFormatter = format 71 | // DDLog.add(DDTTYLogger.sharedInstance) // TTY = Xcode console 72 | 73 | DDASLLogger.sharedInstance.logFormatter = format 74 | DDLog.add(DDASLLogger.sharedInstance) // ASL = Apple System Logs 75 | 76 | DDLog.add(fileLogger, with: .all) 77 | fileLogger.maximumFileSize = config.maximumFileSize 78 | fileLogger.logFileManager.maximumNumberOfLogFiles = config.maximumNumberOfLogFiles 79 | 80 | DDLog.add(fileLogger2, with: .warning) 81 | fileLogger2.maximumFileSize = config.maximumFileSize 82 | fileLogger2.logFileManager.maximumNumberOfLogFiles = config.maximumNumberOfLogFiles 83 | 84 | maxMessageSize = config.maxMessageSize 85 | } 86 | 87 | /// 显示Log View 88 | public func showLogView(_ inView: UIView? = nil) { 89 | 90 | logView.show(inView: inView) 91 | } 92 | 93 | /// 隐藏Log View 94 | public func dismissLogView() { 95 | 96 | logView.dismiss() 97 | } 98 | 99 | /// 获取当前日志(字符串) 100 | func getNewDoc() -> String? { 101 | 102 | guard let path = BLoger.shared.fileLogger.currentLogFileInfo?.filePath else { 103 | return nil 104 | } 105 | let url = URL(fileURLWithPath: path) 106 | guard let data = try? Data(contentsOf: url) else { 107 | return nil 108 | } 109 | let str = String.init(data: data, encoding: .utf8) 110 | return str 111 | } 112 | 113 | /// 设置message长度后需要处理message的格式 114 | static func convertMessage(msg :String) -> String { 115 | 116 | if BLoger.shared.maxMessageSize == 0 { 117 | return msg 118 | } 119 | 120 | let msg = msg.replacingOccurrences(of: "\n", with: " ") 121 | 122 | if msg.count <= BLoger.shared.maxMessageSize { 123 | return msg 124 | } 125 | return "\(String(msg.prefix(Int(BLoger.shared.maxMessageSize))))...\(msg.count)" 126 | } 127 | 128 | @objc fileprivate func receivedRotation() { 129 | 130 | logView.adapterScreen() 131 | } 132 | } 133 | 134 | public class BLogConfig { 135 | 136 | public init() { 137 | 138 | } 139 | 140 | /// 每个文件大小 141 | public var maximumFileSize: UInt64 = 1024*1024 142 | 143 | /// 缓存几个文件 144 | public var maximumNumberOfLogFiles: UInt = 30 145 | 146 | /// 信息长度限制大于0时,回车转空格; 若设置为0,则不限制; 仅限制Log文件s格式,不限制控制台输出 147 | public var maxMessageSize: UInt = 0 148 | 149 | } 150 | -------------------------------------------------------------------------------- /BLoger/Classes/ViewController+ShankExt.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController+ShankExt.swift 3 | // BLoger 4 | // 5 | // Created by lin bo on 2019/3/22. 6 | // Copyright © 2019 lin bo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIViewController { 12 | 13 | //开始摇晃 14 | override open func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) { 15 | 16 | } 17 | 18 | //摇晃结束 19 | override open func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) { 20 | 21 | if BLoger.shared.shankShow { 22 | if #available(iOS 10.0, *) { 23 | let imp = UIImpactFeedbackGenerator.init(style: .medium) 24 | imp.impactOccurred() 25 | 26 | } else { 27 | // Fallback on earlier versions 28 | } 29 | BLoger.shared.showLogView() 30 | } 31 | } 32 | 33 | //摇晃被意外终止 34 | override open func motionCancelled(_ motion: UIEventSubtype, with event: UIEvent?) { 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Example/BLoger.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5E3C24AF22D353CB00670C85 /* BLogExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E3C24AE22D353CB00670C85 /* BLogExt.swift */; }; 11 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 12 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 13 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 16 | 96AC476BE453FB5BA2307977 /* Pods_BLoger_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C543789A7543625CB7B17B60 /* Pods_BLoger_Example.framework */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 34355C93428B1FCDF9DED5D6 /* BLoger.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = BLoger.podspec; path = ../BLoger.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 21 | 5DFFB6ED80ACE5150103DA8C /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 22 | 5E3C24AE22D353CB00670C85 /* BLogExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BLogExt.swift; sourceTree = ""; }; 23 | 607FACD01AFB9204008FA782 /* BLoger_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BLoger_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 26 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 27 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 28 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 29 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 30 | 737E4A7367E490250679D4FB /* Pods-BLoger_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BLoger_Example.debug.xcconfig"; path = "Target Support Files/Pods-BLoger_Example/Pods-BLoger_Example.debug.xcconfig"; sourceTree = ""; }; 31 | BC9FB907ACE442D2AB95953B /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 32 | C45A960327A42455189D258F /* Pods_BLoger_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BLoger_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | C543789A7543625CB7B17B60 /* Pods_BLoger_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BLoger_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | E6E6AA4EB6BB466C186F6DD2 /* Pods-BLoger_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BLoger_Example.release.xcconfig"; path = "Target Support Files/Pods-BLoger_Example/Pods-BLoger_Example.release.xcconfig"; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | 96AC476BE453FB5BA2307977 /* Pods_BLoger_Example.framework in Frameworks */, 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXFrameworksBuildPhase section */ 47 | 48 | /* Begin PBXGroup section */ 49 | 12A9876CC054786B54D085D4 /* Pods */ = { 50 | isa = PBXGroup; 51 | children = ( 52 | 737E4A7367E490250679D4FB /* Pods-BLoger_Example.debug.xcconfig */, 53 | E6E6AA4EB6BB466C186F6DD2 /* Pods-BLoger_Example.release.xcconfig */, 54 | ); 55 | path = Pods; 56 | sourceTree = ""; 57 | }; 58 | 607FACC71AFB9204008FA782 = { 59 | isa = PBXGroup; 60 | children = ( 61 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 62 | 607FACD21AFB9204008FA782 /* Example for BLoger */, 63 | 607FACD11AFB9204008FA782 /* Products */, 64 | 12A9876CC054786B54D085D4 /* Pods */, 65 | 904C409D94BC22981CB87436 /* Frameworks */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | 607FACD11AFB9204008FA782 /* Products */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 607FACD01AFB9204008FA782 /* BLoger_Example.app */, 73 | ); 74 | name = Products; 75 | sourceTree = ""; 76 | }; 77 | 607FACD21AFB9204008FA782 /* Example for BLoger */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 81 | 5E3C24AE22D353CB00670C85 /* BLogExt.swift */, 82 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 83 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 84 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 85 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 86 | 607FACD31AFB9204008FA782 /* Supporting Files */, 87 | ); 88 | name = "Example for BLoger"; 89 | path = BLoger; 90 | sourceTree = ""; 91 | }; 92 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 607FACD41AFB9204008FA782 /* Info.plist */, 96 | ); 97 | name = "Supporting Files"; 98 | sourceTree = ""; 99 | }; 100 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 34355C93428B1FCDF9DED5D6 /* BLoger.podspec */, 104 | 5DFFB6ED80ACE5150103DA8C /* README.md */, 105 | BC9FB907ACE442D2AB95953B /* LICENSE */, 106 | ); 107 | name = "Podspec Metadata"; 108 | sourceTree = ""; 109 | }; 110 | 904C409D94BC22981CB87436 /* Frameworks */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | C543789A7543625CB7B17B60 /* Pods_BLoger_Example.framework */, 114 | C45A960327A42455189D258F /* Pods_BLoger_Tests.framework */, 115 | ); 116 | name = Frameworks; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | 607FACCF1AFB9204008FA782 /* BLoger_Example */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "BLoger_Example" */; 125 | buildPhases = ( 126 | A0B4095BE8227ADCB0565F94 /* [CP] Check Pods Manifest.lock */, 127 | 607FACCC1AFB9204008FA782 /* Sources */, 128 | 607FACCD1AFB9204008FA782 /* Frameworks */, 129 | 607FACCE1AFB9204008FA782 /* Resources */, 130 | 214D6196063638386EBF341F /* [CP] Embed Pods Frameworks */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | ); 136 | name = BLoger_Example; 137 | productName = BLoger; 138 | productReference = 607FACD01AFB9204008FA782 /* BLoger_Example.app */; 139 | productType = "com.apple.product-type.application"; 140 | }; 141 | /* End PBXNativeTarget section */ 142 | 143 | /* Begin PBXProject section */ 144 | 607FACC81AFB9204008FA782 /* Project object */ = { 145 | isa = PBXProject; 146 | attributes = { 147 | LastSwiftUpdateCheck = 0830; 148 | LastUpgradeCheck = 0830; 149 | ORGANIZATIONNAME = CocoaPods; 150 | TargetAttributes = { 151 | 607FACCF1AFB9204008FA782 = { 152 | CreatedOnToolsVersion = 6.3.1; 153 | DevelopmentTeam = 4AA472B9Y2; 154 | LastSwiftMigration = 0900; 155 | }; 156 | }; 157 | }; 158 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "BLoger" */; 159 | compatibilityVersion = "Xcode 3.2"; 160 | developmentRegion = English; 161 | hasScannedForEncodings = 0; 162 | knownRegions = ( 163 | English, 164 | en, 165 | Base, 166 | ); 167 | mainGroup = 607FACC71AFB9204008FA782; 168 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 169 | projectDirPath = ""; 170 | projectRoot = ""; 171 | targets = ( 172 | 607FACCF1AFB9204008FA782 /* BLoger_Example */, 173 | ); 174 | }; 175 | /* End PBXProject section */ 176 | 177 | /* Begin PBXResourcesBuildPhase section */ 178 | 607FACCE1AFB9204008FA782 /* Resources */ = { 179 | isa = PBXResourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 183 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 184 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXResourcesBuildPhase section */ 189 | 190 | /* Begin PBXShellScriptBuildPhase section */ 191 | 214D6196063638386EBF341F /* [CP] Embed Pods Frameworks */ = { 192 | isa = PBXShellScriptBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | ); 196 | inputPaths = ( 197 | "${PODS_ROOT}/Target Support Files/Pods-BLoger_Example/Pods-BLoger_Example-frameworks.sh", 198 | "${BUILT_PRODUCTS_DIR}/BLoger/BLoger.framework", 199 | "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", 200 | "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework", 201 | ); 202 | name = "[CP] Embed Pods Frameworks"; 203 | outputPaths = ( 204 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BLoger.framework", 205 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework", 206 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework", 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | shellPath = /bin/sh; 210 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-BLoger_Example/Pods-BLoger_Example-frameworks.sh\"\n"; 211 | showEnvVarsInLog = 0; 212 | }; 213 | A0B4095BE8227ADCB0565F94 /* [CP] Check Pods Manifest.lock */ = { 214 | isa = PBXShellScriptBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | ); 218 | inputFileListPaths = ( 219 | ); 220 | inputPaths = ( 221 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 222 | "${PODS_ROOT}/Manifest.lock", 223 | ); 224 | name = "[CP] Check Pods Manifest.lock"; 225 | outputFileListPaths = ( 226 | ); 227 | outputPaths = ( 228 | "$(DERIVED_FILE_DIR)/Pods-BLoger_Example-checkManifestLockResult.txt", 229 | ); 230 | runOnlyForDeploymentPostprocessing = 0; 231 | shellPath = /bin/sh; 232 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 233 | showEnvVarsInLog = 0; 234 | }; 235 | /* End PBXShellScriptBuildPhase section */ 236 | 237 | /* Begin PBXSourcesBuildPhase section */ 238 | 607FACCC1AFB9204008FA782 /* Sources */ = { 239 | isa = PBXSourcesBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | 5E3C24AF22D353CB00670C85 /* BLogExt.swift in Sources */, 243 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 244 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 245 | ); 246 | runOnlyForDeploymentPostprocessing = 0; 247 | }; 248 | /* End PBXSourcesBuildPhase section */ 249 | 250 | /* Begin PBXVariantGroup section */ 251 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 252 | isa = PBXVariantGroup; 253 | children = ( 254 | 607FACDA1AFB9204008FA782 /* Base */, 255 | ); 256 | name = Main.storyboard; 257 | sourceTree = ""; 258 | }; 259 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 260 | isa = PBXVariantGroup; 261 | children = ( 262 | 607FACDF1AFB9204008FA782 /* Base */, 263 | ); 264 | name = LaunchScreen.xib; 265 | sourceTree = ""; 266 | }; 267 | /* End PBXVariantGroup section */ 268 | 269 | /* Begin XCBuildConfiguration section */ 270 | 607FACED1AFB9204008FA782 /* Debug */ = { 271 | isa = XCBuildConfiguration; 272 | buildSettings = { 273 | ALWAYS_SEARCH_USER_PATHS = NO; 274 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 275 | CLANG_CXX_LIBRARY = "libc++"; 276 | CLANG_ENABLE_MODULES = YES; 277 | CLANG_ENABLE_OBJC_ARC = YES; 278 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 279 | CLANG_WARN_BOOL_CONVERSION = YES; 280 | CLANG_WARN_COMMA = YES; 281 | CLANG_WARN_CONSTANT_CONVERSION = YES; 282 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 283 | CLANG_WARN_EMPTY_BODY = YES; 284 | CLANG_WARN_ENUM_CONVERSION = YES; 285 | CLANG_WARN_INFINITE_RECURSION = YES; 286 | CLANG_WARN_INT_CONVERSION = YES; 287 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 288 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 289 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 290 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 291 | CLANG_WARN_STRICT_PROTOTYPES = YES; 292 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 293 | CLANG_WARN_UNREACHABLE_CODE = YES; 294 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 295 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 296 | COPY_PHASE_STRIP = NO; 297 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 298 | ENABLE_STRICT_OBJC_MSGSEND = YES; 299 | ENABLE_TESTABILITY = YES; 300 | GCC_C_LANGUAGE_STANDARD = gnu99; 301 | GCC_DYNAMIC_NO_PIC = NO; 302 | GCC_NO_COMMON_BLOCKS = YES; 303 | GCC_OPTIMIZATION_LEVEL = 0; 304 | GCC_PREPROCESSOR_DEFINITIONS = ( 305 | "DEBUG=1", 306 | "$(inherited)", 307 | ); 308 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 309 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 310 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 311 | GCC_WARN_UNDECLARED_SELECTOR = YES; 312 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 313 | GCC_WARN_UNUSED_FUNCTION = YES; 314 | GCC_WARN_UNUSED_VARIABLE = YES; 315 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 316 | MTL_ENABLE_DEBUG_INFO = YES; 317 | ONLY_ACTIVE_ARCH = YES; 318 | SDKROOT = iphoneos; 319 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 320 | }; 321 | name = Debug; 322 | }; 323 | 607FACEE1AFB9204008FA782 /* Release */ = { 324 | isa = XCBuildConfiguration; 325 | buildSettings = { 326 | ALWAYS_SEARCH_USER_PATHS = NO; 327 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 328 | CLANG_CXX_LIBRARY = "libc++"; 329 | CLANG_ENABLE_MODULES = YES; 330 | CLANG_ENABLE_OBJC_ARC = YES; 331 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 332 | CLANG_WARN_BOOL_CONVERSION = YES; 333 | CLANG_WARN_COMMA = YES; 334 | CLANG_WARN_CONSTANT_CONVERSION = YES; 335 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 336 | CLANG_WARN_EMPTY_BODY = YES; 337 | CLANG_WARN_ENUM_CONVERSION = YES; 338 | CLANG_WARN_INFINITE_RECURSION = YES; 339 | CLANG_WARN_INT_CONVERSION = YES; 340 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 341 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 343 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 344 | CLANG_WARN_STRICT_PROTOTYPES = YES; 345 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 346 | CLANG_WARN_UNREACHABLE_CODE = YES; 347 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 348 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 349 | COPY_PHASE_STRIP = NO; 350 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 351 | ENABLE_NS_ASSERTIONS = NO; 352 | ENABLE_STRICT_OBJC_MSGSEND = YES; 353 | GCC_C_LANGUAGE_STANDARD = gnu99; 354 | GCC_NO_COMMON_BLOCKS = YES; 355 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 356 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 357 | GCC_WARN_UNDECLARED_SELECTOR = YES; 358 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 359 | GCC_WARN_UNUSED_FUNCTION = YES; 360 | GCC_WARN_UNUSED_VARIABLE = YES; 361 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 362 | MTL_ENABLE_DEBUG_INFO = NO; 363 | SDKROOT = iphoneos; 364 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 365 | VALIDATE_PRODUCT = YES; 366 | }; 367 | name = Release; 368 | }; 369 | 607FACF01AFB9204008FA782 /* Debug */ = { 370 | isa = XCBuildConfiguration; 371 | baseConfigurationReference = 737E4A7367E490250679D4FB /* Pods-BLoger_Example.debug.xcconfig */; 372 | buildSettings = { 373 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 374 | DEVELOPMENT_TEAM = 4AA472B9Y2; 375 | GCC_PREPROCESSOR_DEFINITIONS = ( 376 | "$(inherited)", 377 | "COCOAPODS=1", 378 | ); 379 | INFOPLIST_FILE = BLoger/Info.plist; 380 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 381 | MODULE_NAME = ExampleApp; 382 | OTHER_SWIFT_FLAGS = "$(inherited) -D COCOAPODS -D DEBUG"; 383 | PRODUCT_BUNDLE_IDENTIFIER = com.linbo.BLoger; 384 | PRODUCT_NAME = "$(TARGET_NAME)"; 385 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 386 | SWIFT_VERSION = 4.0; 387 | TARGETED_DEVICE_FAMILY = "1,2"; 388 | }; 389 | name = Debug; 390 | }; 391 | 607FACF11AFB9204008FA782 /* Release */ = { 392 | isa = XCBuildConfiguration; 393 | baseConfigurationReference = E6E6AA4EB6BB466C186F6DD2 /* Pods-BLoger_Example.release.xcconfig */; 394 | buildSettings = { 395 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 396 | DEVELOPMENT_TEAM = 4AA472B9Y2; 397 | INFOPLIST_FILE = BLoger/Info.plist; 398 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 399 | MODULE_NAME = ExampleApp; 400 | PRODUCT_BUNDLE_IDENTIFIER = com.linbo.BLoger; 401 | PRODUCT_NAME = "$(TARGET_NAME)"; 402 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 403 | SWIFT_VERSION = 4.0; 404 | TARGETED_DEVICE_FAMILY = "1,2"; 405 | }; 406 | name = Release; 407 | }; 408 | /* End XCBuildConfiguration section */ 409 | 410 | /* Begin XCConfigurationList section */ 411 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "BLoger" */ = { 412 | isa = XCConfigurationList; 413 | buildConfigurations = ( 414 | 607FACED1AFB9204008FA782 /* Debug */, 415 | 607FACEE1AFB9204008FA782 /* Release */, 416 | ); 417 | defaultConfigurationIsVisible = 0; 418 | defaultConfigurationName = Release; 419 | }; 420 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "BLoger_Example" */ = { 421 | isa = XCConfigurationList; 422 | buildConfigurations = ( 423 | 607FACF01AFB9204008FA782 /* Debug */, 424 | 607FACF11AFB9204008FA782 /* Release */, 425 | ); 426 | defaultConfigurationIsVisible = 0; 427 | defaultConfigurationName = Release; 428 | }; 429 | /* End XCConfigurationList section */ 430 | }; 431 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 432 | } 433 | -------------------------------------------------------------------------------- /Example/BLoger.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/BLoger.xcodeproj/xcshareddata/xcschemes/BLoger-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Example/BLoger.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/BLoger/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BLoger 4 | // 5 | // Created by ok@linbok.com on 03/26/2019. 6 | // Copyright (c) 2019 ok@linbok.com. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import BLoger 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | 20 | /// ------------------------以下是我们需要配置的 21 | 22 | /// 可以使用这个做些配置(可选) 23 | let config = BLogConfig() 24 | 25 | /// 每条message最大字符限制,会把回车转空格(这个功能主要目的是限制每条日志长度,控制日志格式,但缺点是降低可读性) 26 | // config.maxMessageSize = 500 27 | 28 | /// 表示我已经启动 29 | BLoger.shared.start(config) 30 | 31 | /// Debug模式下开启摇一摇弹出功能(Release禁用哟!)(建议使用) 32 | /// 请注意Swift下DEBUG判断无效 需要添加如下: 33 | /// Build Settings -> Swift Compiler - Custom Flags -> Other Swift Flages -> Debug的路径下加入-D DEBUG 34 | #if DEBUG 35 | BLoger.shared.shankShow = true 36 | ALog("Debug") 37 | #else 38 | BLoger.shared.shankShow = false 39 | ALog("Not Debug") 40 | #endif 41 | 42 | /// ------------------------以上是全部我们需要配置的 43 | 44 | /// ------------------------以下属于测试Demo的功能 45 | 46 | /// 开启自动输出日志(这个功能会持续输出日志,给Demo测试用的) 47 | BLogAutoTask.shared.start() 48 | 49 | ALog("------------启动应用---------------") 50 | BLog("这是打开应用第一条输出") 51 | 52 | /// 以下验证日志格式(推荐使用ALog转换后的方法,避免每次import库) 53 | ALog() 54 | VLog("Verbose") 55 | DLog("Debug") 56 | ILog("Info") 57 | WLog("Warn") 58 | ELog("Error") 59 | ALog("abcdefg") 60 | ILog(BLoger.shared.fileLogger.currentLogFileInfo?.description ?? "-") // Log文件信息 61 | 62 | var text: String? 63 | text = nil 64 | guard let _ = text else { 65 | GLog() 66 | return true 67 | } 68 | 69 | return true 70 | } 71 | 72 | func applicationWillResignActive(_ application: UIApplication) { 73 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 74 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 75 | } 76 | 77 | func applicationDidEnterBackground(_ application: UIApplication) { 78 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 79 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 80 | ALog("------------切到后台---------------") 81 | 82 | } 83 | 84 | func applicationWillEnterForeground(_ application: UIApplication) { 85 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 86 | ALog("------------切到前端---------------") 87 | 88 | } 89 | 90 | func applicationDidBecomeActive(_ application: UIApplication) { 91 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 92 | } 93 | 94 | func applicationWillTerminate(_ application: UIApplication) { 95 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 96 | } 97 | 98 | 99 | } 100 | 101 | -------------------------------------------------------------------------------- /Example/BLoger/BLogExt.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // BLoger_Example 4 | // 5 | // Created by lin bo on 2019/7/8. 6 | // Copyright © 2019 CocoaPods. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import BLoger 11 | 12 | /// 推荐使用下列方法来输出,可以避免每次都import BLoger(建议使用) 13 | public func ALog(_ message: @autoclosure () -> String = "-", 14 | file: StaticString = #file, 15 | function: StaticString = #function, 16 | line: UInt = #line) { 17 | BLog(message(), file: file, function: function, line: line) 18 | } 19 | 20 | public func VLog(_ message: @autoclosure () -> String = "-", 21 | file: StaticString = #file, 22 | function: StaticString = #function, 23 | line: UInt = #line) { 24 | BLog_v(message(), file: file, function: function, line: line) 25 | } 26 | 27 | public func DLog(_ message: @autoclosure () -> String = "-", 28 | file: StaticString = #file, 29 | function: StaticString = #function, 30 | line: UInt = #line) { 31 | BLog_d(message(), file: file, function: function, line: line) 32 | } 33 | 34 | public func ILog(_ message: @autoclosure () -> String = "-", 35 | file: StaticString = #file, 36 | function: StaticString = #function, 37 | line: UInt = #line) { 38 | BLog_i(message(), file: file, function: function, line: line) 39 | } 40 | 41 | public func WLog(_ message: @autoclosure () -> String = "-", 42 | file: StaticString = #file, 43 | function: StaticString = #function, 44 | line: UInt = #line) { 45 | BLog_w(message(), file: file, function: function, line: line) 46 | } 47 | 48 | public func ELog(_ message: @autoclosure () -> String = "-", 49 | file: StaticString = #file, 50 | function: StaticString = #function, 51 | line: UInt = #line) { 52 | BLog_e(message(), file: file, function: function, line: line) 53 | } 54 | 55 | /// 可专门在Guard return 前调用,定位判断条件 56 | public func GLog(_ message: @autoclosure () -> String = "-", 57 | file: StaticString = #file, 58 | function: StaticString = #function, 59 | line: UInt = #line) { 60 | BLog_w("❗️\(message())", file: file, function: function, line: line) 61 | } 62 | -------------------------------------------------------------------------------- /Example/BLoger/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/BLoger/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 53 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 100 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /Example/BLoger/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "40x40", 25 | "idiom" : "iphone", 26 | "filename" : "icon-3.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "iphone", 32 | "filename" : "icon-2.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "size" : "60x60", 37 | "idiom" : "iphone", 38 | "filename" : "icon-1.png", 39 | "scale" : "2x" 40 | }, 41 | { 42 | "size" : "60x60", 43 | "idiom" : "iphone", 44 | "filename" : "icon.png", 45 | "scale" : "3x" 46 | }, 47 | { 48 | "size" : "1024x1024", 49 | "idiom" : "ios-marketing", 50 | "filename" : "icon-1024.png", 51 | "scale" : "1x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rocket2048/BLoger/694c683148849f6457982dd8d1549f2eadc2bc3f/Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-1.png -------------------------------------------------------------------------------- /Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rocket2048/BLoger/694c683148849f6457982dd8d1549f2eadc2bc3f/Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-1024.png -------------------------------------------------------------------------------- /Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rocket2048/BLoger/694c683148849f6457982dd8d1549f2eadc2bc3f/Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-2.png -------------------------------------------------------------------------------- /Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rocket2048/BLoger/694c683148849f6457982dd8d1549f2eadc2bc3f/Example/BLoger/Images.xcassets/AppIcon.appiconset/icon-3.png -------------------------------------------------------------------------------- /Example/BLoger/Images.xcassets/AppIcon.appiconset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rocket2048/BLoger/694c683148849f6457982dd8d1549f2eadc2bc3f/Example/BLoger/Images.xcassets/AppIcon.appiconset/icon.png -------------------------------------------------------------------------------- /Example/BLoger/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | BLoger 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationPortraitUpsideDown 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/BLoger/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // BLoger 4 | // 5 | // Created by ok@linbok.com on 03/26/2019. 6 | // Copyright (c) 2019 ok@linbok.com. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import BLoger 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet weak var sw: UISwitch! 15 | @IBOutlet weak var sw2: UISwitch! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | // Do any additional setup after loading the view, typically from a nib. 20 | 21 | title = "BLoger Demo \(String(describing: navigationController?.viewControllers.count))" 22 | 23 | } 24 | 25 | override func viewWillAppear(_ animated: Bool) { 26 | super.viewWillAppear(animated) 27 | 28 | sw.isOn = BLoger.shared.shankShow 29 | sw2.isOn = BLogAutoTask.shared.started 30 | } 31 | 32 | override func viewDidAppear(_ animated: Bool) { 33 | super.viewDidAppear(animated) 34 | 35 | } 36 | 37 | @IBAction func btnAction(_ sender: Any) { 38 | 39 | BLoger.shared.showLogView() 40 | BLog("点击弹出Log窗口") 41 | 42 | } 43 | 44 | @IBAction func btnAction1(_ sender: Any) { 45 | 46 | let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") 47 | navigationController?.pushViewController(vc, animated: true) 48 | 49 | BLog("点击进入下一个页面") 50 | } 51 | 52 | @IBAction func swAction(_ sender: UISwitch) { 53 | 54 | if sender.tag == 1 { 55 | 56 | BLog(sender.isOn ? "摇一摇开" : "摇一摇关") 57 | 58 | BLoger.shared.shankShow = sender.isOn 59 | } 60 | 61 | if sender.tag == 2 { 62 | 63 | BLog(sender.isOn ? "自动测试开" : "自动测试关") 64 | 65 | if sender.isOn { 66 | BLogAutoTask.shared.start() 67 | }else { 68 | BLogAutoTask.shared.stop() 69 | } 70 | } 71 | } 72 | 73 | } 74 | 75 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | source 'https://github.com/CocoaPods/Specs.git' 4 | 5 | target 'BLoger_Example' do 6 | 7 | pod 'CocoaLumberjack/Swift' 8 | pod 'SnapKit' 9 | pod 'BLoger', :path => '../' 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - BLoger (2.0.0): 3 | - CocoaLumberjack/Swift 4 | - SnapKit 5 | - CocoaLumberjack/Core (3.6.1) 6 | - CocoaLumberjack/Swift (3.6.1): 7 | - CocoaLumberjack/Core 8 | - SnapKit (4.2.0) 9 | 10 | DEPENDENCIES: 11 | - BLoger (from `../`) 12 | - CocoaLumberjack/Swift 13 | - SnapKit 14 | 15 | SPEC REPOS: 16 | https://github.com/CocoaPods/Specs.git: 17 | - CocoaLumberjack 18 | - SnapKit 19 | 20 | EXTERNAL SOURCES: 21 | BLoger: 22 | :path: "../" 23 | 24 | SPEC CHECKSUMS: 25 | BLoger: 0e97eb65ca171a64f801d2b4209ff09b0192dc13 26 | CocoaLumberjack: b17ae15142558d08bbacf69775fa10c4abbebcc9 27 | SnapKit: fe8a619752f3f27075cc9a90244d75c6c3f27e2a 28 | 29 | PODFILE CHECKSUM: 56a5e4ca960f1aef917422b02fc0246db4e4975e 30 | 31 | COCOAPODS: 1.9.1 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 ok@linbok.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BLoger 2 | 3 | [![CI Status](https://img.shields.io/travis/ok@linbok.com/BLoger.svg?style=flat)](https://travis-ci.org/ok@linbok.com/BLoger) 4 | [![Version](https://img.shields.io/cocoapods/v/BLoger.svg?style=flat)](https://cocoapods.org/pods/BLoger) 5 | [![License](https://img.shields.io/cocoapods/l/BLoger.svg?style=flat)](https://cocoapods.org/pods/BLoger) 6 | [![Platform](https://img.shields.io/cocoapods/p/BLoger.svg?style=flat)](https://cocoapods.org/pods/BLoger) 7 | [![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu) 8 | [![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE) 9 | 10 | # Demo screenshot 11 | 12 | 13 | 14 |
15 | 16 | 17 | # How to use 18 | 19 | 20 | AppDelegate application func Initialization BLoger 21 | 22 | code in Appdelegate 23 | ```swift 24 | 25 | /// ------------------------以下是我们需要配置的 26 | 27 | /// 可以使用这个做些配置(可选) 28 | let config = BLogConfig() 29 | 30 | /// 每条message最大字符限制,会把回车转空格(这个功能主要目的是限制每条日志长度,控制日志格式,但缺点是降低可读性) 31 | // config.maxMessageSize = 500 32 | 33 | /// 表示我已经启动 34 | BLoger.shared.start(config) 35 | 36 | /// Debug模式下开启摇一摇弹出功能(Release禁用哟!)(建议使用) 37 | /// 请注意Swift下DEBUG判断无效 需要添加如下: 38 | /// Build Settings -> Swift Compiler - Custom Flags -> Other Swift Flages -> Debug的路径下加入-D DEBUG 39 | #if DEBUG 40 | BLoger.shared.shankShow = true 41 | ALog("Debug") 42 | #else 43 | BLoger.shared.shankShow = false 44 | ALog("Not Debug") 45 | #endif 46 | 47 | /// ------------------------以上是全部我们需要配置的 48 | 49 | /// ------------------------以下属于测试Demo的功能 50 | 51 | /// 开启自动输出日志(这个功能会持续输出日志,给Demo测试用的) 52 | BLogAutoTask.shared.start() 53 | 54 | ALog("------------启动应用---------------") 55 | BLog("这是打开应用第一条输出") 56 | 57 | /// 以下验证日志格式(推荐使用ALog转换后的方法,避免每次import库) 58 | ALog() 59 | VLog("Verbose") 60 | DLog("Debug") 61 | ILog("Info") 62 | WLog("Warn") 63 | ELog("Error") 64 | ALog("abcdefg") 65 | ILog(BLoger.shared.fileLogger.currentLogFileInfo.description) // Log文件信息 66 | 67 | ``` 68 | 69 | ## Example 70 | 71 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 72 | 73 | ## Installation 74 | 75 | BLoger is available through [CocoaPods](https://cocoapods.org). To install 76 | it, simply add the following line to your Podfile: 77 | 78 | ```ruby 79 | pod 'BLoger' 80 | ``` 81 | 82 | ## Author 83 | 84 | linbo, ok@linbok.com 85 | 86 | ## License 87 | 88 | BLoger is available under the MIT license. See the LICENSE file for more info. 89 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj --------------------------------------------------------------------------------