├── LogKitExample ├── LogKitExample │ ├── zh-Hans.lproj │ │ ├── Main.strings │ │ └── LaunchScreen.strings │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── AppDelegate.m │ ├── ViewController.m │ ├── Info.plist │ └── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard ├── podfile └── LogKitExample.xcodeproj │ └── project.pbxproj ├── Preview ├── en_0.png ├── en_1.png ├── en_2.png ├── zh_0.png ├── zh_1.png ├── zh_2.png ├── debugView.gif └── xcode_console.png ├── CocoaLogKit ├── Logkit.bundle │ ├── log_close_btn@2x.png │ ├── log_assistive_btn@2x.png │ ├── en.lproj │ │ └── Localizable.strings │ └── zh-Hans.lproj │ │ └── Localizable.strings ├── LogKitDebugView.h ├── LogKitAssistiveButton.h ├── LogKitFormatter.h ├── LogKitConsoleLogger.h ├── NSBundle+Logkit.h ├── LogKitMailSender.h ├── LogKit.h ├── LogKitFormatter.m ├── LogKitMacros.h ├── LogKitMailSender.m ├── NSBundle+Logkit.m ├── LogKitAssistiveButton.m ├── LogKitConsoleLogger.m ├── LogKitDebugView.m └── LogKit.m ├── CocoaLogKit.podspec ├── LICENSE ├── README_zh.md └── README.md /LogKitExample/LogKitExample/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Preview/en_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/en_0.png -------------------------------------------------------------------------------- /Preview/en_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/en_1.png -------------------------------------------------------------------------------- /Preview/en_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/en_2.png -------------------------------------------------------------------------------- /Preview/zh_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/zh_0.png -------------------------------------------------------------------------------- /Preview/zh_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/zh_1.png -------------------------------------------------------------------------------- /Preview/zh_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/zh_2.png -------------------------------------------------------------------------------- /Preview/debugView.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/debugView.gif -------------------------------------------------------------------------------- /Preview/xcode_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/Preview/xcode_console.png -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /CocoaLogKit/Logkit.bundle/log_close_btn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/CocoaLogKit/Logkit.bundle/log_close_btn@2x.png -------------------------------------------------------------------------------- /CocoaLogKit/Logkit.bundle/log_assistive_btn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/CocoaLogKit/Logkit.bundle/log_assistive_btn@2x.png -------------------------------------------------------------------------------- /CocoaLogKit/Logkit.bundle/en.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/CocoaLogKit/Logkit.bundle/en.lproj/Localizable.strings -------------------------------------------------------------------------------- /CocoaLogKit/Logkit.bundle/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apdevzhang/CocoaLogKit/HEAD/CocoaLogKit/Logkit.bundle/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // LogKitExample 4 | // 5 | // Created by BANYAN on 2018/10/15. 6 | // Copyright © 2018年 BANYAN. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LogKitExample 4 | // 5 | // Created by BANYAN on 2018/10/15. 6 | // Copyright © 2018年 BANYAN. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /LogKitExample/podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'LogKitExample' do 5 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks 6 | # use_frameworks! 7 | 8 | # Pods for LogKitExample 9 | #pod 'CocoaLogKit' 10 | pod 'CocoaLumberjack' 11 | pod 'SSZipArchive' 12 | end 13 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LogKitExample 4 | // 5 | // Created by BANYAN on 2018/10/15. 6 | // Copyright © 2018年 BANYAN. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /CocoaLogKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "CocoaLogKit" 3 | s.version = "1.0.0" 4 | s.summary = "Log framework based on CocoaLumberjack and ZipArchive" 5 | s.homepage = "https://github.com/skooal/LogKit" 6 | s.license = "MIT" 7 | s.author = { "BANYAN" => "greenbanyan@163.com" } 8 | s.platform = :ios,'8.0' 9 | s.source = { :git => "https://github.com/skooal/LogKit.git", :tag => s.version } 10 | s.source_files = "CocoaLogKit/**/*.{h,m}" 11 | s.resource = "CocoaLogKit/LogKit.bundle" 12 | "public_header_files": [ 13 | "CocoaLogKit/LogKit.h" 14 | ], 15 | s.dependency 'CocoaLumberjack/Swift' 16 | s.dependency 'SSZipArchive' 17 | "frameworks": [ 18 | "UIKit", 19 | "Foundation", 20 | "MessageUI" 21 | ], 22 | s.requires_arc = true 23 | end 24 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LogKitExample 4 | // 5 | // Created by BANYAN on 2018/10/15. 6 | // Copyright © 2018年 BANYAN. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | //#import 11 | #import "LogKit.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | [LogKit addTTYLogger]; 21 | 22 | [LogKit addFileLogger]; 23 | 24 | #ifdef DEBUG 25 | [LogKit addDashboardLogger]; 26 | #endif 27 | 28 | [LogKit setDefaultMailAddress:@[@"testMailAddress@gmail.com"]]; 29 | 30 | [LogKit setDefaultLogPassword:@"101001"]; 31 | 32 | return YES; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 BANYAN 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitDebugView.h: -------------------------------------------------------------------------------- 1 | // LogKitDebugView.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | @interface LogKitDebugView : UIView 26 | 27 | + (LogKitDebugView *)sharedInstance; 28 | 29 | - (void)open; 30 | - (void)close; 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitAssistiveButton.h: -------------------------------------------------------------------------------- 1 | // LogKitAssistiveButton.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | @interface LogKitAssistiveButton : UIButton 26 | 27 | + (LogKitAssistiveButton *)sharedInstance; 28 | 29 | - (void)open; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitFormatter.h: -------------------------------------------------------------------------------- 1 | // LogKitFormatter.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | @interface LogKitFormatter : DDDispatchQueueLogFormatter 26 | 27 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitConsoleLogger.h: -------------------------------------------------------------------------------- 1 | // LogKitConsoleLogger.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | #import "LogKitMacros.h" 26 | 27 | @interface LogKitConsoleLogger : NSObject 28 | 29 | + (LogKitConsoleLogger *)sharedInstance; 30 | 31 | - (void)showConsoleLoggerInView:(UIView *)view; 32 | - (void)clearConsoleLogger; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // LogKitExample 4 | // 5 | // Created by BANYAN on 2018/10/15. 6 | // Copyright © 2018年 BANYAN. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "LogKit.h" 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | DLogTrace(); // 输出当前控制器及函数名称 22 | 23 | [self printRandomLogMessage]; 24 | } 25 | 26 | - (void)printRandomLogMessage { 27 | NSInteger randomLevel = arc4random() % 5; 28 | 29 | switch (randomLevel) { 30 | case 4: 31 | DLogError(@"this is a test error log message"); 32 | break; 33 | 34 | case 3: 35 | DLogWarn(@"this is a test warn log message"); 36 | break; 37 | 38 | case 2: 39 | DLogInfo(@"this is a test info log message"); 40 | break; 41 | 42 | case 1: 43 | DLogDebug(@"this is a test debug log message"); 44 | break; 45 | 46 | default: 47 | DLogVerbose(@"this is a test verbose log message"); 48 | break; 49 | } 50 | 51 | NSTimeInterval logInterval = 1.f; 52 | dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, logInterval * NSEC_PER_SEC); 53 | dispatch_after(timer, dispatch_get_main_queue(), ^(void){ 54 | [self printRandomLogMessage]; 55 | }); 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /CocoaLogKit/NSBundle+Logkit.h: -------------------------------------------------------------------------------- 1 | // NSBundle+Logkit.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | @interface NSBundle (Logkit) 26 | 27 | + (instancetype)logkitBundle; 28 | 29 | + (NSString *)log_localizedStringForKey:(NSString *)key; 30 | + (NSString *)log_localizedStringForKey:(NSString *)key value:(NSString *)value; 31 | 32 | + (UIImage *)log_assistiveButtonImage; 33 | + (UIImage *)log_closeButtonImage; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitMailSender.h: -------------------------------------------------------------------------------- 1 | // LogKitMailSender.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | typedef void (^SendMailBuilder)(MFMailComposeViewController *controller); 26 | typedef void (^SendMailComplete)(MFMailComposeViewController *controller, MFMailComposeResult result, NSError *error); 27 | 28 | @interface LogKitMailSender : NSObject 29 | 30 | + (instancetype)sendMail:(SendMailBuilder)builder complete:(SendMailComplete)complete; 31 | 32 | - (void)showFromViewController:(UIViewController *) viewController completion:(void(^)(void))completion; 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/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 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/Base.lproj/LaunchScreen.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 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample/Assets.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 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /README_zh.md: -------------------------------------------------------------------------------- 1 | # LogKit 2 | 3 | 基于[CocoaLumberjack][3]和[ZipArchive][4]的日志框架 4 | 5 | ## 功能 6 | - 易于测试和收集应用的日志信息或是难以重现的问题,我们可以在离开Xcode的情况下将日志发送到邮箱 7 | - 根据日志级别,在Xcode控制台或iPhone中输出不同颜色的日志信息(若要在Xcode控制台输出不同的颜色则依赖[__XcodeColors__][2]插件) 8 | 9 | ## 预览 10 | GIF| 11 | -------------| 12 | ![DebugView](Preview/debugView.gif)| 13 | 14 | 15 | 辅助按钮 | 调试视图 | 发送日志 | Xcode控制台 | 16 | -----|-----|-----|-----| 17 | ![Preview/zh_0.png](Preview/zh_0.png) | ![Preview/zh_1.png](Preview/zh_1.png) | ![Preview/zh_3.png](Preview/zh_2.png) | ![Preview/xcode_console.png](Preview/xcode_console.png) | 18 | 19 | ## 使用 20 | ```obj-c 21 | DLogTrace(); // 输出当前函数名 22 | 23 | DLogVerbose(@""); // 输出详细级别日志文本 24 | 25 | DLogDebug(@""); // 输出调试级别日志文本 26 | 27 | DLogInfo(@""); // 输出信息级别日志文本 28 | 29 | DLogWarn(@""); // 输出警告级别日志文本 30 | 31 | DLogError(@""); // 输出错误级别日志文本 32 | ``` 33 | 34 | ## 配置 35 | 在项目AppDelegate.m中进行框架配置 36 | 37 | ```obj-c 38 | // #import 'LogKit.h' 39 | // #import 40 | 41 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 42 | [LogKit addTTYLogger]; // 配置并添加一个DDTTYLogger(苹果系统日志和Xcode控制台) 43 | 44 | [LogKit addFileLogger]; // 把日志语句发送至文件 (默认情况下为非调试版本添加的注释),如果需要发送日志文件到邮箱的功能则需要此方法 45 | 46 | #ifdef DEBUG 47 | [LogKit addDashboardLogger]; // 配置并添加一个带有调试视图的日志控制台 (如果只需要在Xcode下调试可不添加此行) 48 | #endif 49 | 50 | [LogKit setDefaultMailAddress:@[@"testMailAddress@gmail.com"]]; // 设置接收压缩日志文件的邮箱集合 (默认为空) 51 | 52 | [LogKit setDefaultLogPassword:@"101001"]; // 设置日志文件的解压密码 (默认为空) 53 | 54 | return YES; 55 | } 56 | ``` 57 | ## 安装 58 | ```ruby 59 | source 'https://github.com/CocoaPods/Specs.git' 60 | 61 | pod 'CocoaLogKit' 62 | ``` 63 | 64 | ## 开源许可 65 | `CocoaLogKit`use [__MIT license__][1] 66 | 67 | [1]: https://github.com/skooal/LogKit/blob/master/LICENSE "MIT License" 68 | [2]: https://github.com/robbiehanson/XcodeColors "XcodeColors" 69 | [3]: https://github.com/CocoaLumberjack/CocoaLumberjack "CocoaLumberjack" 70 | [4]: https://github.com/ZipArchive/ZipArchive "ZipArchive" 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LogKit 2 | 3 | Log framework based on [CocoaLumberjack][3] and [ZipArchive][4] 4 | 5 | ## Features 6 | - Easy to test and collect problems that are difficult to reproduce,we can send logs to mailBox without Xcode 7 | - Output different log information with corresponding colors in the Xcode console or iPhone depending on the log level(Xcode console required[__XcodeColors__][2] plug-in) 8 | 9 | ## Preview 10 | GIF | 11 | ----------------------| 12 | ![DebugView](Preview/debugView.gif)| 13 | 14 | assistiveButton | debugView | logMail | XcodeConsole | 15 | -----|-----|-----|-----| 16 | ![Preview/en_0.png](Preview/en_0.png) | ![Preview/en_1.png](Preview/en_1.png) | ![Preview/en_3.png](Preview/en_2.png) | ![Preview/xcode_console.png](Preview/xcode_console.png) | 17 | 18 | ## Usage 19 | ```obj-c 20 | DLogTrace(); // ouput current function 21 | 22 | DLogVerbose(@""); // ouput verbose level log message 23 | 24 | DLogDebug(@""); // ouput debug level log message 25 | 26 | DLogInfo(@""); // ouput info level log message 27 | 28 | DLogWarn(@""); // ouput warn level log message 29 | 30 | DLogError(@""); // ouput error level log message 31 | ``` 32 | 33 | ## Configuration 34 | Configuration Settings in project's AppDelegate.m 35 | 36 | ```obj-c 37 | // #import 'LogKit.h' 38 | // #import 39 | 40 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 41 | [LogKit addTTYLogger]; // Configure and add a DDTTYLogger (Apple System Log and Xcode console) 42 | 43 | [LogKit addFileLogger]; // Send the log to the file (default for non debug builds),requied this method if you want send log files to mail 44 | 45 | #ifdef DEBUG 46 | [LogKit addDashboardLogger]; // Configure and add a recorder with console logs 47 | #endif 48 | 49 | [LogKit setDefaultMailAddress:@[@"testMailAddress@gmail.com"]]; // Sets the mailbox collection that receives log files (default is empty) 50 | 51 | [LogKit setDefaultLogPassword:@"101001"]; // Set the password for the log file (default is empty) 52 | 53 | return YES; 54 | } 55 | ``` 56 | 57 | ## Installation 58 | ```ruby 59 | source 'https://github.com/CocoaPods/Specs.git' 60 | 61 | pod 'CocoaLogKit' 62 | ``` 63 | 64 | ## License 65 | `CocoaLogKit`use [__MIT license__][1] 66 | 67 | [1]: https://github.com/skooal/LogKit/blob/master/LICENSE "MIT License" 68 | [2]: https://github.com/robbiehanson/XcodeColors "XcodeColors" 69 | [3]: https://github.com/CocoaLumberjack/CocoaLumberjack "CocoaLumberjack" 70 | [4]: https://github.com/ZipArchive/ZipArchive "ZipArchive" 71 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKit.h: -------------------------------------------------------------------------------- 1 | // LogKit.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import "LogKitMacros.h" 25 | #import "LogKitFormatter.h" 26 | #import "LogKitMailSender.h" 27 | #import "LogKitConsoleLogger.h" 28 | #import "NSBundle+Logkit.h" 29 | 30 | @interface LogKit : DDLog 31 | 32 | ///------------------------- 33 | #pragma mark - Log 34 | ///------------------------- 35 | /**! 36 | * @brief Configure and add a recorder with console logs to APP -> (配置并添加日志记录至APP) 37 | */ 38 | + (void)addDashboardLogger; 39 | 40 | /**! 41 | * @brief Configure and add a DDASLLogger (Apple System Log) -> (配置添加日志记录到苹果系统日志) 42 | */ 43 | + (void)addASLLogger; 44 | 45 | /**! 46 | * @brief Configure and add a DDTTYLogger (Apple System Log and Xcode console),if the method has already been executed, there is no need to perform the function 'addASLLogger' -> (添加日志记录到苹果系统日志及Xcode控制台,如果此方法以及添加,则不再需要方法‘addASLLogger’) 47 | */ 48 | + (void)addTTYLogger; 49 | 50 | /**! 51 | * @brief Send the log to the file (default for non debug builds),requied this method if you want send log files to mail -> (发生日志至文件,默认为DEBUG模式,如果期望发送日志到邮箱则需要此方法) 52 | */ 53 | + (void)addFileLogger; 54 | 55 | ///------------------------- 56 | #pragma mark - Mail 57 | ///------------------------- 58 | /**! 59 | * 60 | * @brief Sets the mailbox collection that receives log files (default is empty) -> (设置接收日志文件的邮箱集合) 61 | */ 62 | + (void)setDefaultMailAddress:(NSArray *)defaultMailAddress; 63 | 64 | /**! 65 | * @brief Set the password for the log file (default is empty) -> (设置日志文件解压密码,默认为空) 66 | */ 67 | + (void)setDefaultLogPassword:(NSString *)defaultLogPassword; 68 | 69 | /**! 70 | * @brief Send compressed log files to mailbox (default this method is not required if you add the perform the function `[Logkit addDashboardLogger]`) -> (发生压缩日志文件至邮箱,当添加函数`[Logkit addDashboardLogger]`后此方法才生效) 71 | */ 72 | + (void)sendLogFilesToMail; 73 | 74 | @end 75 | 76 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitFormatter.m: -------------------------------------------------------------------------------- 1 | // LogKitFormatter.m 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LogKitFormatter.h" 24 | 25 | @interface LogKitFormatter () 26 | @property (strong, nonatomic) NSDateFormatter *dateFormatter; 27 | @property (copy, nonatomic) NSString *processName; 28 | @end 29 | 30 | @implementation LogKitFormatter 31 | 32 | #pragma mark - Public Methods 33 | - (NSString *)formatLogMessage:(DDLogMessage *)logMessage { 34 | return [NSString stringWithFormat:@"%@ %@[%@] %@ %@:%@ %@", 35 | [self.dateFormatter stringFromDate:logMessage.timestamp], 36 | self.processName, 37 | [self queueThreadLabelForLogMessage:logMessage], 38 | [self formatLogFlag:logMessage.flag], 39 | logMessage.fileName, 40 | @(logMessage.line), 41 | logMessage.message]; 42 | } 43 | 44 | #pragma mark - Private Methods 45 | - (NSString *)formatLogFlag:(DDLogFlag)logFlag { 46 | switch (logFlag) { 47 | case DDLogFlagError: 48 | return @"Error"; 49 | break; 50 | 51 | case DDLogFlagWarning: 52 | return @"Warning"; 53 | break; 54 | 55 | case DDLogFlagInfo: 56 | return @"Info"; 57 | break; 58 | 59 | case DDLogFlagDebug: 60 | return @"Debug"; 61 | break; 62 | 63 | default: 64 | return @"Verbose"; 65 | break; 66 | } 67 | } 68 | 69 | #pragma mark - Setter/Getter 70 | - (NSDateFormatter *)dateFormatter { 71 | if (!_dateFormatter) { 72 | _dateFormatter = NSDateFormatter.new; 73 | [_dateFormatter setDateFormat:@"yyyy:MM:dd HH:mm:ss"]; 74 | } 75 | return _dateFormatter; 76 | } 77 | 78 | - (NSString *)processName { 79 | if (!_processName) { 80 | _processName = NSProcessInfo.processInfo.processName; 81 | } 82 | return _processName; 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitMacros.h: -------------------------------------------------------------------------------- 1 | // LogKitMacros.h 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #ifndef LogKitMacros_h 24 | #define LogKitMacros_h 25 | 26 | #ifdef DEBUG 27 | static const int ddLogLevel = DDLogLevelVerbose; 28 | #else 29 | static const int ddLogLevel = DDLogLevelError; 30 | #endif 31 | 32 | #define DLOG_VERBOSE_COLOR [DDColor colorWithRed:0.65 green:0.65 blue:0.65 alpha:1.0] 33 | #define DLOG_DEBUG_COLOR [DDColor colorWithRed:0.4 green:0.4 blue:0.4 alpha:1.0] 34 | #define DLOG_INFO_COLOR [DDColor colorWithRed:26.0/255.0 green:158.0/255.0 blue:4.0/255.0 alpha:1.0] 35 | #define DLOG_WARNING_COLOR [DDColor colorWithRed:244.0/255.0 green:103.0/255.0 blue:8.0/255.0 alpha:1.0] 36 | #define DLOG_ERROR_COLOR [DDColor redColor] 37 | 38 | #define DLogError(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) 39 | #define DLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) 40 | #define DLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) 41 | #define DLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) 42 | #define DLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) 43 | 44 | #define DLogTrace() DLogDebug(@"%s", __PRETTY_FUNCTION__) 45 | 46 | #define DAssert(condition, frmt, ...) if (!(condition)) { \ 47 | NSString *description = [NSString stringWithFormat:frmt, ##__VA_ARGS__]; \ 48 | DLogError(@"%@", description); \ 49 | NSAssert(NO, description);} 50 | 51 | #define DAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition) 52 | 53 | #endif 54 | 55 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitMailSender.m: -------------------------------------------------------------------------------- 1 | // LogKitMailSender.m 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LogKitMailSender.h" 24 | #import "LogKit.h" 25 | 26 | @interface LogKitMailSender () 27 | @property (copy, nonatomic) SendMailComplete completeAction; 28 | @property (strong, nonatomic) id keepInMemory; 29 | @property (strong, nonatomic) MFMailComposeViewController *mailComposeViewController; 30 | @end 31 | 32 | @implementation LogKitMailSender 33 | 34 | #pragma mark - Public Methods 35 | + (instancetype)sendMail:(SendMailBuilder)builder complete:(SendMailComplete)complete { 36 | return [[self alloc] initWithBuilder:builder complete:complete]; 37 | } 38 | 39 | - (void)showFromViewController:(UIViewController *)viewController completion:(void(^)(void))completion { 40 | if ([MFMailComposeViewController canSendMail]) { 41 | [viewController presentViewController:self.mailComposeViewController animated:YES completion:completion]; 42 | [self setKeepInMemory:self]; 43 | } 44 | } 45 | 46 | #pragma mark - Private Methods 47 | - (instancetype)initWithBuilder:(SendMailBuilder)builder complete:(SendMailComplete)complete { 48 | self = [super init]; 49 | if (self) { 50 | MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init]; 51 | self.completeAction = complete; 52 | self.mailComposeViewController = mailComposeViewController; 53 | mailComposeViewController.mailComposeDelegate = self; 54 | builder(mailComposeViewController); 55 | } 56 | return self; 57 | } 58 | 59 | #pragma mark - MFMailComposeViewControllerDelegate 60 | - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error { 61 | NSString *message; 62 | switch (result) { 63 | case MFMailComposeResultCancelled: message = @"The user cancels the edit log file."; break; 64 | case MFMailComposeResultSaved: message = @"The user saved the log file successfully."; break; 65 | case MFMailComposeResultSent: message = @"The user sent the log file successfully."; break; 66 | case MFMailComposeResultFailed: message = @"User attempts to save or send log file failed."; break; 67 | default: break; 68 | } 69 | DLogInfo(@"%@", [NSBundle log_localizedStringForKey:message]); 70 | self.completeAction(controller, result, error); 71 | self.keepInMemory = nil; 72 | [controller dismissViewControllerAnimated:YES completion:nil]; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /CocoaLogKit/NSBundle+Logkit.m: -------------------------------------------------------------------------------- 1 | // NSBundle+Logkit.m 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "NSBundle+Logkit.h" 24 | 25 | @implementation NSBundle (Logkit) 26 | 27 | #pragma mark - Init 28 | + (instancetype)logkitBundle { 29 | static NSBundle *logkitBundle = nil; 30 | if (logkitBundle == nil) { 31 | logkitBundle = [self bundleWithName:@"Logkit.bundle"]; 32 | } 33 | return logkitBundle; 34 | } 35 | 36 | #pragma mark - Public Methods 37 | + (NSString *)log_localizedStringForKey:(NSString *)key { 38 | return [self log_localizedStringForKey:key value:nil]; 39 | } 40 | 41 | + (NSString *)log_localizedStringForKey:(NSString *)key value:(NSString *)value { 42 | static NSBundle *bundle = nil; 43 | if (bundle == nil) { 44 | NSString *language = [NSLocale preferredLanguages].firstObject; 45 | if ([language hasPrefix:@"en"]) { 46 | language = @"en"; 47 | } else if ([language hasPrefix:@"zh"]) { 48 | language = @"zh-Hans"; 49 | } else { 50 | language = @"en"; 51 | } 52 | bundle = [NSBundle bundleWithPath:[[NSBundle logkitBundle] pathForResource:language ofType:@"lproj"]]; 53 | } 54 | value = [bundle localizedStringForKey:key value:value table:nil]; 55 | return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil]; 56 | } 57 | 58 | + (UIImage *)log_assistiveButtonImage { 59 | static UIImage *assistiveButtonImage = nil; 60 | 61 | if (assistiveButtonImage == nil) { 62 | assistiveButtonImage = [[UIImage imageWithContentsOfFile:[[self logkitBundle] pathForResource:@"log_assistive_btn@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAutomatic]; 63 | } 64 | 65 | return assistiveButtonImage; 66 | } 67 | 68 | + (UIImage *)log_closeButtonImage { 69 | static UIImage *closeButtonImage = nil; 70 | 71 | if (closeButtonImage == nil) { 72 | closeButtonImage = [[UIImage imageWithContentsOfFile:[[self logkitBundle] pathForResource:@"log_close_btn@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAutomatic]; 73 | } 74 | 75 | return closeButtonImage; 76 | } 77 | 78 | #pragma mark - Private Methods 79 | + (NSBundle *)bundleWithName:(NSString *)name { 80 | NSString *mainBundlePath = [[NSBundle mainBundle] resourcePath]; 81 | 82 | NSString *logKitBundlePath = [mainBundlePath stringByAppendingPathComponent:name]; 83 | 84 | if ([[NSFileManager defaultManager] fileExistsAtPath:logKitBundlePath]) { 85 | return [NSBundle bundleWithPath:logKitBundlePath]; 86 | } 87 | return nil; 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitAssistiveButton.m: -------------------------------------------------------------------------------- 1 | // LogKitAssistiveButton.m 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LogKitAssistiveButton.h" 24 | #import "LogKitDebugView.h" 25 | #import "NSBundle+Logkit.h" 26 | 27 | @interface LogKitAssistiveButton () 28 | @property (assign, nonatomic) UIEdgeInsets safeAreaInsets; 29 | @end 30 | 31 | @implementation LogKitAssistiveButton 32 | 33 | #pragma mark - Init 34 | + (LogKitAssistiveButton *)sharedInstance { 35 | static LogKitAssistiveButton *sharedInstance; 36 | static dispatch_once_t onceToken; 37 | dispatch_once(&onceToken, ^{ 38 | sharedInstance = LogKitAssistiveButton.new; 39 | 40 | [sharedInstance commonInit]; 41 | }); 42 | return sharedInstance; 43 | } 44 | 45 | - (void)commonInit { 46 | _safeAreaInsets = UIEdgeInsetsMake(5, 5, 5, 5); 47 | 48 | UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; 49 | [self addGestureRecognizer:panGestureRecognizer]; 50 | 51 | NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"]; 52 | NSString *systemVersion = [[UIDevice currentDevice] systemVersion]; 53 | NSString *localizabledAppVersion = [NSString stringWithFormat:@"%@ : %@", [NSBundle log_localizedStringForKey:@"APP Version"], appVersion]; 54 | NSString *localizabledSystemVersion = [NSString stringWithFormat:@"%@ : %@", [NSBundle log_localizedStringForKey:@"System Version"], systemVersion]; 55 | NSString *placeholderString = [NSString stringWithFormat:@"%@ \n %@", localizabledAppVersion, localizabledSystemVersion]; 56 | 57 | self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 58 | self.titleLabel.font = [UIFont systemFontOfSize:9.]; 59 | self.titleLabel.textAlignment = NSTextAlignmentCenter; 60 | [self setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; 61 | [self setBackgroundImage:[NSBundle log_assistiveButtonImage] forState:UIControlStateNormal]; 62 | [self setTitle:placeholderString forState:UIControlStateNormal]; 63 | [self addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside]; 64 | } 65 | 66 | #pragma mark - Public Methods 67 | - (void)open { 68 | self.frame = CGRectMake(UIScreen.mainScreen.bounds.size.width - 100, UIScreen.mainScreen.bounds.size.height - 100, 100, 50); 69 | 70 | [UIApplication.sharedApplication.delegate.window.rootViewController.view addSubview:self]; 71 | } 72 | 73 | #pragma mark - Action 74 | - (void)buttonAction:(UIButton *)sender { 75 | [LogKitDebugView.sharedInstance open]; 76 | } 77 | 78 | #pragma mark - Gesture 79 | - (void)panGesture:(UIPanGestureRecognizer *)recognizer { 80 | UIWindow *parentWindow = UIApplication.sharedApplication.keyWindow; 81 | 82 | CGPoint translationPoint = [recognizer translationInView:parentWindow]; 83 | 84 | CGPoint movedPoint = CGPointMake(recognizer.view.center.x + translationPoint.x, recognizer.view.center.y + translationPoint.y); 85 | 86 | // mark - top,left,bottom,right 87 | movedPoint.y = MAX(recognizer.view.frame.size.height / 2 + _safeAreaInsets.top, movedPoint.y); 88 | movedPoint.x = MAX(recognizer.view.frame.size.width / 2, movedPoint.x); 89 | movedPoint.y = MIN(parentWindow.frame.size.height - _safeAreaInsets.bottom - recognizer.view.frame.size.height / 2, movedPoint.y); 90 | movedPoint.x = MIN(parentWindow.frame.size.width - recognizer.view.frame.size.width / 2, movedPoint.x); 91 | 92 | recognizer.view.center = movedPoint; 93 | 94 | [recognizer setTranslation:CGPointZero inView:parentWindow]; 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitConsoleLogger.m: -------------------------------------------------------------------------------- 1 | // LogKitConsoleLogger.m 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LogKitConsoleLogger.h" 24 | #import "LogKitFormatter.h" 25 | 26 | @interface LogKitConsoleLogger () 27 | @property (strong, nonatomic) UITableView *tableView; 28 | @property (strong, nonatomic) NSMutableArray *messages; 29 | @end 30 | 31 | @implementation LogKitConsoleLogger 32 | 33 | @synthesize logFormatter; 34 | 35 | #pragma mark - Init 36 | + (LogKitConsoleLogger *)sharedInstance { 37 | static LogKitConsoleLogger *sharedInstance; 38 | static dispatch_once_t onceToken; 39 | dispatch_once(&onceToken, ^{ 40 | sharedInstance = LogKitConsoleLogger.new; 41 | }); 42 | return sharedInstance; 43 | } 44 | 45 | #pragma mark - Delegate 46 | #pragma mark UITableViewDataSource 47 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 48 | return self.messages.count; 49 | } 50 | 51 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 52 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(UITableViewCell.class)]; 53 | 54 | [self configureCell:cell forRowAtIndexPath:indexPath]; 55 | 56 | return cell; 57 | } 58 | 59 | #pragma mark UITableViewDelegate 60 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 61 | DDLogMessage *message = self.messages[indexPath.row]; 62 | 63 | CGFloat messageMargin = 10.0; 64 | 65 | return ceil([[self textOfMessage:message] boundingRectWithSize:CGSizeMake(tableView.bounds.size.width - 30, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [self fontOfMessage]} context:nil].size.height + messageMargin); 66 | } 67 | 68 | #pragma mark - Public Methods 69 | - (void)showConsoleLoggerInView:(UIView *)view { 70 | [view addSubview:self.tableView]; 71 | 72 | UITableView *consoleLoggerTableView = self.tableView; 73 | 74 | [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[consoleLoggerTableView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(consoleLoggerTableView)]]; 75 | [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[consoleLoggerTableView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(consoleLoggerTableView)]]; 76 | } 77 | 78 | - (void)clearConsoleLogger { 79 | [self.messages removeAllObjects]; 80 | 81 | [self.tableView reloadData]; 82 | } 83 | 84 | #pragma mark - Private Methods 85 | - (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath { 86 | DDLogMessage *message = self.messages[indexPath.row]; 87 | 88 | cell.textLabel.text = [self textOfMessage:message]; 89 | cell.textLabel.font = [self fontOfMessage]; 90 | cell.textLabel.textColor = [self colorOfMessage:message.flag]; 91 | cell.textLabel.numberOfLines = 0; 92 | cell.backgroundColor = UIColor.clearColor; 93 | } 94 | 95 | - (void)logMessage:(DDLogMessage *)logMessage { 96 | dispatch_async(dispatch_get_main_queue(), ^{ 97 | [self.messages addObject:logMessage]; 98 | 99 | BOOL scroll = (self.tableView.contentOffset.y + self.tableView.bounds.size.height >= self.tableView.contentSize.height) ? YES : NO; 100 | 101 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0]; 102 | [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom]; 103 | 104 | scroll ?: [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 105 | }); 106 | } 107 | 108 | #pragma mark Message Attribute 109 | - (NSString *)textOfMessage:(DDLogMessage *)message { 110 | LogKitFormatter *formatter = LogKitFormatter.new; 111 | 112 | return [formatter formatLogMessage:message]; 113 | } 114 | 115 | - (UIFont *)fontOfMessage { 116 | return [UIFont boldSystemFontOfSize:10.]; 117 | } 118 | 119 | - (UIColor *)colorOfMessage:(DDLogFlag)logFlag { 120 | switch (logFlag) { 121 | case DDLogFlagError: 122 | return DLOG_ERROR_COLOR; 123 | break; 124 | 125 | case DDLogFlagWarning: 126 | return DLOG_WARNING_COLOR; 127 | break; 128 | 129 | case DDLogFlagInfo: 130 | return DLOG_INFO_COLOR; 131 | break; 132 | 133 | case DDLogFlagDebug: 134 | return DLOG_DEBUG_COLOR; 135 | break; 136 | 137 | case DDLogFlagVerbose: 138 | return DLOG_VERBOSE_COLOR; 139 | break; 140 | 141 | default: 142 | return UIColor.whiteColor; 143 | break; 144 | } 145 | } 146 | 147 | #pragma mark - Setter/Getter 148 | - (UITableView *)tableView { 149 | if (!_tableView) { 150 | _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; 151 | [_tableView registerClass:UITableViewCell.class forCellReuseIdentifier:NSStringFromClass(UITableViewCell.class)]; 152 | _tableView.delegate = self; 153 | _tableView.dataSource = self; 154 | _tableView.backgroundColor = UIColor.whiteColor; 155 | _tableView.alpha = 0.8; 156 | _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 157 | _tableView.translatesAutoresizingMaskIntoConstraints = NO; 158 | } 159 | return _tableView; 160 | } 161 | 162 | - (NSMutableArray *)messages { 163 | if (!_messages) { 164 | _messages = NSMutableArray.new; 165 | } 166 | return _messages; 167 | } 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKitDebugView.m: -------------------------------------------------------------------------------- 1 | // LogKitDebugView.m 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LogKitDebugView.h" 24 | #import "LogKit.h" 25 | 26 | @interface LogKitDebugView () 27 | @property (strong, nonatomic) UIView *backgroundView; 28 | @property (strong, nonatomic) UIView *navigationView; 29 | @property (strong, nonatomic) UISegmentedControl *segementedControl; 30 | @property (strong, nonatomic) UIButton *closeButton; 31 | @property (strong, nonatomic) CAGradientLayer *gradientLayer; 32 | @property (strong, nonatomic) UIView *consoleLoggerView; 33 | @end 34 | 35 | @implementation LogKitDebugView 36 | 37 | #pragma mark - Init 38 | + (LogKitDebugView *)sharedInstance { 39 | static LogKitDebugView *sharedInstance; 40 | static dispatch_once_t onceToken; 41 | dispatch_once(&onceToken, ^{ 42 | sharedInstance = [[LogKitDebugView alloc] init]; 43 | 44 | [sharedInstance commonInit]; 45 | }); 46 | return sharedInstance; 47 | } 48 | 49 | - (void)commonInit { 50 | self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 51 | 52 | self.backgroundView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 53 | [self addSubview:self.backgroundView]; 54 | 55 | [self.backgroundView addSubview:self.navigationView]; 56 | self.navigationView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [self sizeAdaptation] ? 78 : 54); 57 | 58 | self.gradientLayer.frame = self.navigationView.bounds; 59 | [self.navigationView.layer addSublayer:self.gradientLayer]; 60 | 61 | self.closeButton.frame = CGRectMake([UIScreen mainScreen].bounds.size.width - 44 - 10, [self sizeAdaptation] ? 45 : 25, 20, 20); 62 | [self.navigationView addSubview:self.closeButton]; 63 | 64 | self.segementedControl.frame = CGRectMake((self.navigationView.frame.size.width - 160) / 2, [self sizeAdaptation] ? 40 : 20, 160, 30); 65 | [self.navigationView addSubview:self.segementedControl]; 66 | 67 | self.consoleLoggerView.frame = CGRectMake(0, CGRectGetMaxY(self.navigationView.frame), [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - self.navigationView.frame.size.height); 68 | [self.backgroundView addSubview:self.consoleLoggerView]; 69 | 70 | [LogKitConsoleLogger.sharedInstance showConsoleLoggerInView:self.consoleLoggerView]; 71 | } 72 | 73 | #pragma mark - Public Methods 74 | - (void)open { 75 | [UIApplication.sharedApplication.keyWindow addSubview:self]; 76 | } 77 | 78 | - (void)close { 79 | [self removeFromSuperview]; 80 | } 81 | 82 | #pragma mark - Action 83 | - (void)closeButtonAction { 84 | [self close]; 85 | } 86 | 87 | - (void)segmentedControlValueChanged:(UISegmentedControl *)sender { 88 | NSInteger index = [sender selectedSegmentIndex]; 89 | if (index == 0) { 90 | [LogKitConsoleLogger.sharedInstance clearConsoleLogger]; 91 | } else if (index == 1) { 92 | [self removeFromSuperview]; 93 | 94 | [LogKit sendLogFilesToMail]; 95 | } 96 | } 97 | 98 | #pragma mark - Private Methods 99 | - (BOOL)sizeAdaptation { 100 | return UIApplication.sharedApplication.keyWindow.frame.size.height >= 812.f ? YES : NO; 101 | } 102 | 103 | #pragma mark - Setter/Getter 104 | - (UIView *)backgroundView { 105 | if (!_backgroundView) { 106 | _backgroundView = UIView.new; 107 | _backgroundView.backgroundColor = UIColor.whiteColor; 108 | } 109 | return _backgroundView; 110 | } 111 | 112 | - (UIView *)navigationView { 113 | if (!_navigationView) { 114 | _navigationView = UIView.new; 115 | _navigationView.backgroundColor = UIColor.whiteColor; 116 | } 117 | return _navigationView; 118 | } 119 | 120 | - (UISegmentedControl *)segementedControl { 121 | if (!_segementedControl) { 122 | _segementedControl = [[UISegmentedControl alloc] initWithItems:@[[NSBundle log_localizedStringForKey:@"Clear Console"], [NSBundle log_localizedStringForKey:@"Mail Logs"]]]; 123 | _segementedControl.tintColor = UIColor.whiteColor; 124 | NSDictionary *normalAttributes = @{ 125 | NSFontAttributeName : [UIFont boldSystemFontOfSize:10.f], 126 | NSForegroundColorAttributeName : UIColor.whiteColor 127 | }; 128 | [_segementedControl setTitleTextAttributes:normalAttributes forState:UIControlStateNormal]; 129 | _segementedControl.momentary = YES; 130 | [_segementedControl addTarget:self action:@selector(segmentedControlValueChanged:) forControlEvents:UIControlEventValueChanged]; 131 | } 132 | return _segementedControl; 133 | } 134 | 135 | - (UIButton *)closeButton { 136 | if (!_closeButton) { 137 | _closeButton = UIButton.new; 138 | [_closeButton setBackgroundImage:[NSBundle log_closeButtonImage] forState:UIControlStateNormal]; 139 | [_closeButton addTarget:self action:@selector(closeButtonAction) forControlEvents:UIControlEventTouchUpInside]; 140 | } 141 | return _closeButton; 142 | } 143 | 144 | - (CAGradientLayer *)gradientLayer { 145 | if (!_gradientLayer) { 146 | _gradientLayer = CAGradientLayer.layer; 147 | _gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:237. / 255 green:156. / 255 blue:119. / 255 alpha:1].CGColor, (__bridge id)[UIColor colorWithRed:234. / 255 green:133. / 255 blue:114. / 255 alpha:1].CGColor, (__bridge id)[UIColor colorWithRed:233. / 255 green:120. / 255 blue:114. / 255 alpha:1].CGColor, (__bridge id)[UIColor colorWithRed:232. / 255 green:115. / 255 blue:112. / 255 alpha:1].CGColor]; 148 | _gradientLayer.startPoint = CGPointMake(0, 0); 149 | _gradientLayer.endPoint = CGPointMake(1, 0); 150 | } 151 | return _gradientLayer; 152 | } 153 | 154 | - (UIView *)consoleLoggerView { 155 | if (!_consoleLoggerView) { 156 | _consoleLoggerView = UIView.new; 157 | _consoleLoggerView.backgroundColor = UIColor.whiteColor; 158 | } 159 | return _consoleLoggerView; 160 | } 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /CocoaLogKit/LogKit.m: -------------------------------------------------------------------------------- 1 | // LogKit.m 2 | // 3 | // Copyright (c) 2018 BANYAN 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "LogKit.h" 24 | #import 25 | #import 26 | #import 27 | #import 28 | #import "LogKitConsoleLogger.h" 29 | #import "LogKitDebugView.h" 30 | #import "LogKitAssistiveButton.h" 31 | 32 | static NSArray *_defaultMailAddress; 33 | static NSString *_defaultLogPassword; 34 | 35 | @implementation LogKit 36 | 37 | #pragma mark - Init 38 | + (void)initialize { 39 | #ifdef DEBUG 40 | [self addTTYLogger]; 41 | #endif 42 | } 43 | 44 | + (id)logKitFormatter { 45 | static id _logKitFormatter; 46 | static dispatch_once_t onceToken; 47 | dispatch_once(&onceToken, ^{ 48 | _logKitFormatter = LogKitFormatter.new; 49 | }); 50 | return _logKitFormatter; 51 | } 52 | 53 | #pragma mark - Public Methods 54 | + (void)addDashboardLogger { 55 | static dispatch_once_t onceToken; 56 | dispatch_once(&onceToken, ^{ 57 | [DDLog addLogger:LogKitConsoleLogger.sharedInstance]; 58 | [LogKitAssistiveButton.sharedInstance open]; 59 | }); 60 | } 61 | 62 | + (void)addASLLogger { 63 | static dispatch_once_t onceToken; 64 | dispatch_once(&onceToken, ^{ 65 | DDASLLogger *aslLogger = [DDASLLogger sharedInstance]; 66 | aslLogger.logFormatter = [self logKitFormatter]; 67 | [self addLogger:aslLogger]; 68 | }); 69 | } 70 | 71 | + (void)addTTYLogger { 72 | static dispatch_once_t onceToken; 73 | dispatch_once(&onceToken, ^{ 74 | DDTTYLogger *ttyLogger = [DDTTYLogger sharedInstance]; 75 | ttyLogger.logFormatter = [self logKitFormatter]; 76 | [self addLogger:ttyLogger]; 77 | 78 | char *xcode_colors = getenv("XcodeColors"); 79 | if (xcode_colors && (strcmp(xcode_colors, "YES") == 0)) { 80 | [ttyLogger setForegroundColor:DLOG_VERBOSE_COLOR 81 | backgroundColor:nil 82 | forFlag:DDLogFlagVerbose]; 83 | [ttyLogger setForegroundColor:DLOG_DEBUG_COLOR 84 | backgroundColor:nil 85 | forFlag:DDLogFlagDebug]; 86 | [ttyLogger setForegroundColor:DLOG_INFO_COLOR 87 | backgroundColor:nil 88 | forFlag:DDLogFlagInfo]; 89 | [ttyLogger setForegroundColor:DLOG_WARNING_COLOR 90 | backgroundColor:nil 91 | forFlag:DDLogFlagWarning]; 92 | [ttyLogger setForegroundColor:DLOG_ERROR_COLOR 93 | backgroundColor:nil 94 | forFlag:DDLogFlagError]; 95 | [ttyLogger setColorsEnabled:YES]; 96 | } 97 | }); 98 | } 99 | 100 | + (void)addFileLogger { 101 | static dispatch_once_t onceToken; 102 | dispatch_once(&onceToken, ^{ 103 | DDFileLogger * fileLogger = [DDFileLogger new]; 104 | fileLogger.rollingFrequency = 60 * 60 * 24 * 7; 105 | fileLogger.logFileManager.maximumNumberOfLogFiles = 7; 106 | fileLogger.maximumFileSize = 1024 * 1024 * 10; 107 | fileLogger.logFormatter = [self logKitFormatter]; 108 | [self addLogger:fileLogger]; 109 | }); 110 | } 111 | 112 | + (void)setDefaultMailAddress:(NSArray *)defaultMailAddress { 113 | _defaultMailAddress = defaultMailAddress; 114 | } 115 | 116 | + (void)setDefaultLogPassword:(NSString *)defaultLogPassword { 117 | _defaultLogPassword = defaultLogPassword; 118 | } 119 | 120 | + (void)sendLogFilesToMail { 121 | if (_defaultMailAddress.count == 0) { 122 | if (_defaultLogPassword.length == 0 || [_defaultLogPassword isKindOfClass:[NSNull class]]) { 123 | [self sendLogFilesToMail:nil password:nil]; 124 | } else { 125 | [self sendLogFilesToMail:nil password:_defaultLogPassword]; 126 | } 127 | } else { 128 | if (_defaultLogPassword.length == 0 || [_defaultLogPassword isKindOfClass:[NSNull class]]) { 129 | [self sendLogFilesToMail:_defaultMailAddress password:nil]; 130 | } else { 131 | [self sendLogFilesToMail:_defaultMailAddress password:_defaultLogPassword]; 132 | } 133 | } 134 | } 135 | 136 | #pragma mark - Private Methods 137 | + (NSArray *)logFileNames { 138 | DDFileLogger *fileLogger = DDFileLogger.new; 139 | NSArray *logFileNames = [fileLogger.logFileManager sortedLogFileNames]; 140 | return logFileNames; 141 | } 142 | 143 | + (NSString *)logDirectory { 144 | DDFileLogger *fileLogger = DDFileLogger.new; 145 | NSString *logDirectory = [fileLogger.logFileManager logsDirectory]; 146 | return logDirectory; 147 | } 148 | 149 | + (void)sendLogFilesToMail:(NSArray *)mailAddress password:(NSString *)password { 150 | NSString *logDirectory = [self logDirectory]; 151 | NSArray *logFileNames = [self logFileNames]; 152 | 153 | NSMutableArray *logFiles = NSMutableArray.new; 154 | [logFileNames enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 155 | NSString *logFile = [logDirectory stringByAppendingPathComponent:obj]; 156 | [logFiles addObject:logFile]; 157 | }]; 158 | 159 | NSString *logSaveDirectory = NSTemporaryDirectory(); 160 | 161 | BOOL success; 162 | if (password.length == 0 || [password isKindOfClass:[NSNull class]]) { 163 | success = [SSZipArchive createZipFileAtPath:[NSString stringWithFormat:@"%@.zip", [logSaveDirectory stringByAppendingPathComponent:[NSBundle log_localizedStringForKey:@"LogFile"]]] withFilesAtPaths:logFiles]; 164 | } else { 165 | success = [SSZipArchive createZipFileAtPath:[NSString stringWithFormat:@"%@.zip", [logSaveDirectory stringByAppendingPathComponent:[NSBundle log_localizedStringForKey:@"LogFile"]]] withFilesAtPaths:logFiles withPassword:password]; 166 | } 167 | 168 | if (success) { 169 | DLogInfo(@"%@", [NSBundle log_localizedStringForKey:@"LogFile Compression Successed"]); 170 | } else { 171 | DLogError(@"%@", [NSBundle log_localizedStringForKey:@"LogFile Compression Failed"]); 172 | } 173 | 174 | Class mailClass = NSClassFromString((@"MFMailComposeViewController")); 175 | 176 | if (!mailClass) { 177 | #ifdef DEBUG 178 | DAssert(mailClass, @"%@", [NSBundle log_localizedStringForKey:@"Sending mail within the application is not supported in the current system version"]); 179 | #endif 180 | DLogError(@"%@", [NSBundle log_localizedStringForKey:@"Sending mail within the application is not supported in the current system version"]); 181 | return; 182 | } 183 | 184 | if (![mailClass canSendMail]) { 185 | #ifdef DEBUG 186 | DAssert([mailClass canSendMail], @"%@", [NSBundle log_localizedStringForKey:@"The current user did not set up an email account"]); 187 | #endif 188 | DLogError(@"%@", [NSBundle log_localizedStringForKey:@"The current user did not set up an email account"]); 189 | return; 190 | } 191 | 192 | NSData *logData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@.zip", [logSaveDirectory stringByAppendingPathComponent:[NSBundle log_localizedStringForKey:@"LogFile"]]]]; 193 | 194 | NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]; 195 | NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleShortVersionString"]; 196 | NSString *systemVersion = [[UIDevice currentDevice] systemVersion]; 197 | 198 | // appName:XX - LogFile (appVersionX.X、systemVersionX.X) 199 | NSString *mailContent = [NSString stringWithFormat:@"%@ - %@ (%@、%@)", [NSString stringWithFormat:@"%@:%@", [NSBundle log_localizedStringForKey:@"APP Name"], appName], [NSBundle log_localizedStringForKey:@"LogFile"], [NSString stringWithFormat:@"%@ %@", [NSBundle log_localizedStringForKey:@"APP Version"], appVersion], [NSString stringWithFormat:@"%@ %@", [NSBundle log_localizedStringForKey:@"System Version"], systemVersion]]; 200 | 201 | LogKitMailSender *mailSender = [LogKitMailSender sendMail:^(MFMailComposeViewController *controller) { 202 | [controller setToRecipients:mailAddress]; 203 | [controller setSubject:[NSBundle log_localizedStringForKey:@"LogFile"]]; 204 | [controller setMessageBody:mailContent isHTML:NO]; 205 | [controller addAttachmentData:logData mimeType:@"plain/zip" fileName:[[NSBundle log_localizedStringForKey:@"LogFile"] stringByAppendingString:@".zip"]]; 206 | } complete:^(MFMailComposeViewController *controller, MFMailComposeResult result, NSError *error) { 207 | [controller dismissViewControllerAnimated:YES completion:nil]; 208 | }]; 209 | [mailSender showFromViewController:UIApplication.sharedApplication.delegate.window.rootViewController completion:nil]; 210 | } 211 | 212 | @end 213 | -------------------------------------------------------------------------------- /LogKitExample/LogKitExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2332F17122B542A600D56004 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16722B542A600D56004 /* README.md */; }; 11 | 2332F17222B542A600D56004 /* en_2.png in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16922B542A600D56004 /* en_2.png */; }; 12 | 2332F17322B542A600D56004 /* en_0.png in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16A22B542A600D56004 /* en_0.png */; }; 13 | 2332F17422B542A600D56004 /* en_1.png in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16B22B542A600D56004 /* en_1.png */; }; 14 | 2332F17522B542A600D56004 /* zh_2.png in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16C22B542A600D56004 /* zh_2.png */; }; 15 | 2332F17622B542A600D56004 /* xcode_console.png in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16D22B542A600D56004 /* xcode_console.png */; }; 16 | 2332F17722B542A600D56004 /* zh_1.png in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16E22B542A600D56004 /* zh_1.png */; }; 17 | 2332F17822B542A600D56004 /* zh_0.png in Resources */ = {isa = PBXBuildFile; fileRef = 2332F16F22B542A600D56004 /* zh_0.png */; }; 18 | 2332F17922B542A600D56004 /* README_zh.md in Resources */ = {isa = PBXBuildFile; fileRef = 2332F17022B542A600D56004 /* README_zh.md */; }; 19 | 238C8F0022B53AB400EFF517 /* CocoaLogKit.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 238C8EFF22B53AB400EFF517 /* CocoaLogKit.podspec */; }; 20 | 239DC4CA21742DEC0034CCEE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 239DC4C921742DEC0034CCEE /* AppDelegate.m */; }; 21 | 239DC4CD21742DEC0034CCEE /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 239DC4CC21742DEC0034CCEE /* ViewController.m */; }; 22 | 239DC4D021742DEC0034CCEE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 239DC4CE21742DEC0034CCEE /* Main.storyboard */; }; 23 | 239DC4D221742DEC0034CCEE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 239DC4D121742DEC0034CCEE /* Assets.xcassets */; }; 24 | 239DC4D521742DEC0034CCEE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 239DC4D321742DEC0034CCEE /* LaunchScreen.storyboard */; }; 25 | 239DC4D821742DEC0034CCEE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 239DC4D721742DEC0034CCEE /* main.m */; }; 26 | 239DC506217432920034CCEE /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 239DC505217432920034CCEE /* libz.tbd */; }; 27 | 239DC508217432980034CCEE /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 239DC507217432980034CCEE /* MessageUI.framework */; }; 28 | 239DC50A2174329E0034CCEE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 239DC5092174329E0034CCEE /* UIKit.framework */; }; 29 | 239DC50C217432A30034CCEE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 239DC50B217432A30034CCEE /* Foundation.framework */; }; 30 | 23DF729222E5969500FB5A78 /* LogKitFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 23DF728422E5969500FB5A78 /* LogKitFormatter.m */; }; 31 | 23DF729322E5969500FB5A78 /* NSBundle+Logkit.m in Sources */ = {isa = PBXBuildFile; fileRef = 23DF728722E5969500FB5A78 /* NSBundle+Logkit.m */; }; 32 | 23DF729422E5969500FB5A78 /* LogKitAssistiveButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 23DF728822E5969500FB5A78 /* LogKitAssistiveButton.m */; }; 33 | 23DF729522E5969500FB5A78 /* LogKitDebugView.m in Sources */ = {isa = PBXBuildFile; fileRef = 23DF728A22E5969500FB5A78 /* LogKitDebugView.m */; }; 34 | 23DF729622E5969500FB5A78 /* LogKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 23DF728B22E5969500FB5A78 /* LogKit.m */; }; 35 | 23DF729722E5969500FB5A78 /* LogKitConsoleLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 23DF728D22E5969500FB5A78 /* LogKitConsoleLogger.m */; }; 36 | 23DF729822E5969500FB5A78 /* LogKitMailSender.m in Sources */ = {isa = PBXBuildFile; fileRef = 23DF728E22E5969500FB5A78 /* LogKitMailSender.m */; }; 37 | 23DF729922E5969500FB5A78 /* Logkit.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 23DF728F22E5969500FB5A78 /* Logkit.bundle */; }; 38 | DC3BA49DBF4A0BF1BF3E4673 /* libPods-LogKitExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EF2F2ED20DE703A59C935F18 /* libPods-LogKitExample.a */; }; 39 | /* End PBXBuildFile section */ 40 | 41 | /* Begin PBXContainerItemProxy section */ 42 | 239DC500217431290034CCEE /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = 239DC4BD21742DEC0034CCEE /* Project object */; 45 | proxyType = 1; 46 | remoteGlobalIDString = 239DC4C421742DEC0034CCEE; 47 | remoteInfo = LogKitExample; 48 | }; 49 | /* End PBXContainerItemProxy section */ 50 | 51 | /* Begin PBXFileReference section */ 52 | 0AC412465772644C017DDA70 /* Pods-LogKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LogKitExample.debug.xcconfig"; path = "Target Support Files/Pods-LogKitExample/Pods-LogKitExample.debug.xcconfig"; sourceTree = ""; }; 53 | 19109B3FDD1D6B4EECDA8D58 /* Pods-LogKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LogKitExample.release.xcconfig"; path = "Target Support Files/Pods-LogKitExample/Pods-LogKitExample.release.xcconfig"; sourceTree = ""; }; 54 | 2332F16722B542A600D56004 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 55 | 2332F16922B542A600D56004 /* en_2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = en_2.png; sourceTree = ""; }; 56 | 2332F16A22B542A600D56004 /* en_0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = en_0.png; sourceTree = ""; }; 57 | 2332F16B22B542A600D56004 /* en_1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = en_1.png; sourceTree = ""; }; 58 | 2332F16C22B542A600D56004 /* zh_2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = zh_2.png; sourceTree = ""; }; 59 | 2332F16D22B542A600D56004 /* xcode_console.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = xcode_console.png; sourceTree = ""; }; 60 | 2332F16E22B542A600D56004 /* zh_1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = zh_1.png; sourceTree = ""; }; 61 | 2332F16F22B542A600D56004 /* zh_0.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = zh_0.png; sourceTree = ""; }; 62 | 2332F17022B542A600D56004 /* README_zh.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README_zh.md; path = ../README_zh.md; sourceTree = ""; }; 63 | 2332F17A22B543BB00D56004 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 64 | 2332F17B22B543BC00D56004 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; 65 | 238C8EFF22B53AB400EFF517 /* CocoaLogKit.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CocoaLogKit.podspec; path = ../CocoaLogKit.podspec; sourceTree = ""; }; 66 | 239DC4C521742DEC0034CCEE /* LogKitExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LogKitExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 239DC4C821742DEC0034CCEE /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 68 | 239DC4C921742DEC0034CCEE /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 69 | 239DC4CB21742DEC0034CCEE /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 70 | 239DC4CC21742DEC0034CCEE /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 71 | 239DC4CF21742DEC0034CCEE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 72 | 239DC4D121742DEC0034CCEE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 73 | 239DC4D421742DEC0034CCEE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 74 | 239DC4D621742DEC0034CCEE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | 239DC4D721742DEC0034CCEE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 76 | 239DC4FB217431280034CCEE /* LogKitExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LogKitExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 77 | 239DC505217432920034CCEE /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 78 | 239DC507217432980034CCEE /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; 79 | 239DC5092174329E0034CCEE /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 80 | 239DC50B217432A30034CCEE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 81 | 23DF728222E5969500FB5A78 /* LogKitConsoleLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogKitConsoleLogger.h; sourceTree = ""; }; 82 | 23DF728322E5969500FB5A78 /* LogKitMailSender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogKitMailSender.h; sourceTree = ""; }; 83 | 23DF728422E5969500FB5A78 /* LogKitFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogKitFormatter.m; sourceTree = ""; }; 84 | 23DF728522E5969500FB5A78 /* LogKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogKit.h; sourceTree = ""; }; 85 | 23DF728622E5969500FB5A78 /* LogKitDebugView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogKitDebugView.h; sourceTree = ""; }; 86 | 23DF728722E5969500FB5A78 /* NSBundle+Logkit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+Logkit.m"; sourceTree = ""; }; 87 | 23DF728822E5969500FB5A78 /* LogKitAssistiveButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogKitAssistiveButton.m; sourceTree = ""; }; 88 | 23DF728922E5969500FB5A78 /* LogKitMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogKitMacros.h; sourceTree = ""; }; 89 | 23DF728A22E5969500FB5A78 /* LogKitDebugView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogKitDebugView.m; sourceTree = ""; }; 90 | 23DF728B22E5969500FB5A78 /* LogKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogKit.m; sourceTree = ""; }; 91 | 23DF728C22E5969500FB5A78 /* LogKitFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogKitFormatter.h; sourceTree = ""; }; 92 | 23DF728D22E5969500FB5A78 /* LogKitConsoleLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogKitConsoleLogger.m; sourceTree = ""; }; 93 | 23DF728E22E5969500FB5A78 /* LogKitMailSender.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LogKitMailSender.m; sourceTree = ""; }; 94 | 23DF728F22E5969500FB5A78 /* Logkit.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Logkit.bundle; sourceTree = ""; }; 95 | 23DF729022E5969500FB5A78 /* NSBundle+Logkit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSBundle+Logkit.h"; sourceTree = ""; }; 96 | 23DF729122E5969500FB5A78 /* LogKitAssistiveButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogKitAssistiveButton.h; sourceTree = ""; }; 97 | EF2F2ED20DE703A59C935F18 /* libPods-LogKitExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LogKitExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 98 | /* End PBXFileReference section */ 99 | 100 | /* Begin PBXFrameworksBuildPhase section */ 101 | 239DC4C221742DEC0034CCEE /* Frameworks */ = { 102 | isa = PBXFrameworksBuildPhase; 103 | buildActionMask = 2147483647; 104 | files = ( 105 | 239DC50C217432A30034CCEE /* Foundation.framework in Frameworks */, 106 | 239DC50A2174329E0034CCEE /* UIKit.framework in Frameworks */, 107 | 239DC508217432980034CCEE /* MessageUI.framework in Frameworks */, 108 | 239DC506217432920034CCEE /* libz.tbd in Frameworks */, 109 | DC3BA49DBF4A0BF1BF3E4673 /* libPods-LogKitExample.a in Frameworks */, 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | 239DC4F8217431280034CCEE /* Frameworks */ = { 114 | isa = PBXFrameworksBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | ); 118 | runOnlyForDeploymentPostprocessing = 0; 119 | }; 120 | /* End PBXFrameworksBuildPhase section */ 121 | 122 | /* Begin PBXGroup section */ 123 | 2332F16822B542A600D56004 /* Preview */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 2332F16922B542A600D56004 /* en_2.png */, 127 | 2332F16A22B542A600D56004 /* en_0.png */, 128 | 2332F16B22B542A600D56004 /* en_1.png */, 129 | 2332F16C22B542A600D56004 /* zh_2.png */, 130 | 2332F16D22B542A600D56004 /* xcode_console.png */, 131 | 2332F16E22B542A600D56004 /* zh_1.png */, 132 | 2332F16F22B542A600D56004 /* zh_0.png */, 133 | ); 134 | name = Preview; 135 | path = ../Preview; 136 | sourceTree = ""; 137 | }; 138 | 239DC4BC21742DEC0034CCEE = { 139 | isa = PBXGroup; 140 | children = ( 141 | 2332F17022B542A600D56004 /* README_zh.md */, 142 | 2332F16722B542A600D56004 /* README.md */, 143 | 238C8EFF22B53AB400EFF517 /* CocoaLogKit.podspec */, 144 | 2332F16822B542A600D56004 /* Preview */, 145 | 23DF728122E5969500FB5A78 /* CocoaLogKit */, 146 | 239DC4C721742DEC0034CCEE /* LogKitExample */, 147 | 239DC4C621742DEC0034CCEE /* Products */, 148 | E0EA99EA622606AF9FBCAE48 /* Pods */, 149 | DD8A850EAA4591AFE5C5BDB6 /* Frameworks */, 150 | ); 151 | sourceTree = ""; 152 | }; 153 | 239DC4C621742DEC0034CCEE /* Products */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 239DC4C521742DEC0034CCEE /* LogKitExample.app */, 157 | 239DC4FB217431280034CCEE /* LogKitExampleTests.xctest */, 158 | ); 159 | name = Products; 160 | sourceTree = ""; 161 | }; 162 | 239DC4C721742DEC0034CCEE /* LogKitExample */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 239DC4C821742DEC0034CCEE /* AppDelegate.h */, 166 | 239DC4C921742DEC0034CCEE /* AppDelegate.m */, 167 | 239DC4CB21742DEC0034CCEE /* ViewController.h */, 168 | 239DC4CC21742DEC0034CCEE /* ViewController.m */, 169 | 239DC4CE21742DEC0034CCEE /* Main.storyboard */, 170 | 239DC4D121742DEC0034CCEE /* Assets.xcassets */, 171 | 239DC4D321742DEC0034CCEE /* LaunchScreen.storyboard */, 172 | 239DC4D621742DEC0034CCEE /* Info.plist */, 173 | 239DC4D721742DEC0034CCEE /* main.m */, 174 | ); 175 | path = LogKitExample; 176 | sourceTree = ""; 177 | }; 178 | 23DF728122E5969500FB5A78 /* CocoaLogKit */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 23DF728F22E5969500FB5A78 /* Logkit.bundle */, 182 | 23DF728522E5969500FB5A78 /* LogKit.h */, 183 | 23DF728B22E5969500FB5A78 /* LogKit.m */, 184 | 23DF729122E5969500FB5A78 /* LogKitAssistiveButton.h */, 185 | 23DF728822E5969500FB5A78 /* LogKitAssistiveButton.m */, 186 | 23DF728222E5969500FB5A78 /* LogKitConsoleLogger.h */, 187 | 23DF728D22E5969500FB5A78 /* LogKitConsoleLogger.m */, 188 | 23DF728622E5969500FB5A78 /* LogKitDebugView.h */, 189 | 23DF728A22E5969500FB5A78 /* LogKitDebugView.m */, 190 | 23DF728C22E5969500FB5A78 /* LogKitFormatter.h */, 191 | 23DF728422E5969500FB5A78 /* LogKitFormatter.m */, 192 | 23DF728922E5969500FB5A78 /* LogKitMacros.h */, 193 | 23DF728322E5969500FB5A78 /* LogKitMailSender.h */, 194 | 23DF728E22E5969500FB5A78 /* LogKitMailSender.m */, 195 | 23DF729022E5969500FB5A78 /* NSBundle+Logkit.h */, 196 | 23DF728722E5969500FB5A78 /* NSBundle+Logkit.m */, 197 | ); 198 | name = CocoaLogKit; 199 | path = ../CocoaLogKit; 200 | sourceTree = ""; 201 | }; 202 | DD8A850EAA4591AFE5C5BDB6 /* Frameworks */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | 239DC50B217432A30034CCEE /* Foundation.framework */, 206 | 239DC5092174329E0034CCEE /* UIKit.framework */, 207 | 239DC507217432980034CCEE /* MessageUI.framework */, 208 | 239DC505217432920034CCEE /* libz.tbd */, 209 | EF2F2ED20DE703A59C935F18 /* libPods-LogKitExample.a */, 210 | ); 211 | name = Frameworks; 212 | sourceTree = ""; 213 | }; 214 | E0EA99EA622606AF9FBCAE48 /* Pods */ = { 215 | isa = PBXGroup; 216 | children = ( 217 | 0AC412465772644C017DDA70 /* Pods-LogKitExample.debug.xcconfig */, 218 | 19109B3FDD1D6B4EECDA8D58 /* Pods-LogKitExample.release.xcconfig */, 219 | ); 220 | path = Pods; 221 | sourceTree = ""; 222 | }; 223 | /* End PBXGroup section */ 224 | 225 | /* Begin PBXNativeTarget section */ 226 | 239DC4C421742DEC0034CCEE /* LogKitExample */ = { 227 | isa = PBXNativeTarget; 228 | buildConfigurationList = 239DC4DB21742DEC0034CCEE /* Build configuration list for PBXNativeTarget "LogKitExample" */; 229 | buildPhases = ( 230 | FC3081AE1639068156BEB9AF /* [CP] Check Pods Manifest.lock */, 231 | 239DC4C121742DEC0034CCEE /* Sources */, 232 | 239DC4C221742DEC0034CCEE /* Frameworks */, 233 | 239DC4C321742DEC0034CCEE /* Resources */, 234 | ); 235 | buildRules = ( 236 | ); 237 | dependencies = ( 238 | ); 239 | name = LogKitExample; 240 | productName = LogKitExample; 241 | productReference = 239DC4C521742DEC0034CCEE /* LogKitExample.app */; 242 | productType = "com.apple.product-type.application"; 243 | }; 244 | 239DC4FA217431280034CCEE /* LogKitExampleTests */ = { 245 | isa = PBXNativeTarget; 246 | buildConfigurationList = 239DC502217431290034CCEE /* Build configuration list for PBXNativeTarget "LogKitExampleTests" */; 247 | buildPhases = ( 248 | 239DC4F7217431280034CCEE /* Sources */, 249 | 239DC4F8217431280034CCEE /* Frameworks */, 250 | 239DC4F9217431280034CCEE /* Resources */, 251 | ); 252 | buildRules = ( 253 | ); 254 | dependencies = ( 255 | 239DC501217431290034CCEE /* PBXTargetDependency */, 256 | ); 257 | name = LogKitExampleTests; 258 | productName = LogKitExampleTests; 259 | productReference = 239DC4FB217431280034CCEE /* LogKitExampleTests.xctest */; 260 | productType = "com.apple.product-type.bundle.unit-test"; 261 | }; 262 | /* End PBXNativeTarget section */ 263 | 264 | /* Begin PBXProject section */ 265 | 239DC4BD21742DEC0034CCEE /* Project object */ = { 266 | isa = PBXProject; 267 | attributes = { 268 | LastUpgradeCheck = 1000; 269 | ORGANIZATIONNAME = BANYAN; 270 | TargetAttributes = { 271 | 239DC4C421742DEC0034CCEE = { 272 | CreatedOnToolsVersion = 10.0; 273 | LastSwiftMigration = 1020; 274 | }; 275 | 239DC4FA217431280034CCEE = { 276 | CreatedOnToolsVersion = 10.0; 277 | TestTargetID = 239DC4C421742DEC0034CCEE; 278 | }; 279 | }; 280 | }; 281 | buildConfigurationList = 239DC4C021742DEC0034CCEE /* Build configuration list for PBXProject "LogKitExample" */; 282 | compatibilityVersion = "Xcode 9.3"; 283 | developmentRegion = en; 284 | hasScannedForEncodings = 0; 285 | knownRegions = ( 286 | en, 287 | Base, 288 | "zh-Hans", 289 | ); 290 | mainGroup = 239DC4BC21742DEC0034CCEE; 291 | productRefGroup = 239DC4C621742DEC0034CCEE /* Products */; 292 | projectDirPath = ""; 293 | projectRoot = ""; 294 | targets = ( 295 | 239DC4C421742DEC0034CCEE /* LogKitExample */, 296 | 239DC4FA217431280034CCEE /* LogKitExampleTests */, 297 | ); 298 | }; 299 | /* End PBXProject section */ 300 | 301 | /* Begin PBXResourcesBuildPhase section */ 302 | 239DC4C321742DEC0034CCEE /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | 239DC4D521742DEC0034CCEE /* LaunchScreen.storyboard in Resources */, 307 | 239DC4D221742DEC0034CCEE /* Assets.xcassets in Resources */, 308 | 2332F17922B542A600D56004 /* README_zh.md in Resources */, 309 | 2332F17522B542A600D56004 /* zh_2.png in Resources */, 310 | 2332F17722B542A600D56004 /* zh_1.png in Resources */, 311 | 23DF729922E5969500FB5A78 /* Logkit.bundle in Resources */, 312 | 2332F17122B542A600D56004 /* README.md in Resources */, 313 | 2332F17322B542A600D56004 /* en_0.png in Resources */, 314 | 2332F17622B542A600D56004 /* xcode_console.png in Resources */, 315 | 239DC4D021742DEC0034CCEE /* Main.storyboard in Resources */, 316 | 2332F17822B542A600D56004 /* zh_0.png in Resources */, 317 | 238C8F0022B53AB400EFF517 /* CocoaLogKit.podspec in Resources */, 318 | 2332F17422B542A600D56004 /* en_1.png in Resources */, 319 | 2332F17222B542A600D56004 /* en_2.png in Resources */, 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | 239DC4F9217431280034CCEE /* Resources */ = { 324 | isa = PBXResourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | /* End PBXResourcesBuildPhase section */ 331 | 332 | /* Begin PBXShellScriptBuildPhase section */ 333 | FC3081AE1639068156BEB9AF /* [CP] Check Pods Manifest.lock */ = { 334 | isa = PBXShellScriptBuildPhase; 335 | buildActionMask = 2147483647; 336 | files = ( 337 | ); 338 | inputPaths = ( 339 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 340 | "${PODS_ROOT}/Manifest.lock", 341 | ); 342 | name = "[CP] Check Pods Manifest.lock"; 343 | outputPaths = ( 344 | "$(DERIVED_FILE_DIR)/Pods-LogKitExample-checkManifestLockResult.txt", 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | shellPath = /bin/sh; 348 | 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"; 349 | showEnvVarsInLog = 0; 350 | }; 351 | /* End PBXShellScriptBuildPhase section */ 352 | 353 | /* Begin PBXSourcesBuildPhase section */ 354 | 239DC4C121742DEC0034CCEE /* Sources */ = { 355 | isa = PBXSourcesBuildPhase; 356 | buildActionMask = 2147483647; 357 | files = ( 358 | 23DF729722E5969500FB5A78 /* LogKitConsoleLogger.m in Sources */, 359 | 23DF729522E5969500FB5A78 /* LogKitDebugView.m in Sources */, 360 | 239DC4CD21742DEC0034CCEE /* ViewController.m in Sources */, 361 | 23DF729822E5969500FB5A78 /* LogKitMailSender.m in Sources */, 362 | 239DC4D821742DEC0034CCEE /* main.m in Sources */, 363 | 23DF729222E5969500FB5A78 /* LogKitFormatter.m in Sources */, 364 | 23DF729322E5969500FB5A78 /* NSBundle+Logkit.m in Sources */, 365 | 23DF729622E5969500FB5A78 /* LogKit.m in Sources */, 366 | 239DC4CA21742DEC0034CCEE /* AppDelegate.m in Sources */, 367 | 23DF729422E5969500FB5A78 /* LogKitAssistiveButton.m in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | 239DC4F7217431280034CCEE /* Sources */ = { 372 | isa = PBXSourcesBuildPhase; 373 | buildActionMask = 2147483647; 374 | files = ( 375 | ); 376 | runOnlyForDeploymentPostprocessing = 0; 377 | }; 378 | /* End PBXSourcesBuildPhase section */ 379 | 380 | /* Begin PBXTargetDependency section */ 381 | 239DC501217431290034CCEE /* PBXTargetDependency */ = { 382 | isa = PBXTargetDependency; 383 | target = 239DC4C421742DEC0034CCEE /* LogKitExample */; 384 | targetProxy = 239DC500217431290034CCEE /* PBXContainerItemProxy */; 385 | }; 386 | /* End PBXTargetDependency section */ 387 | 388 | /* Begin PBXVariantGroup section */ 389 | 239DC4CE21742DEC0034CCEE /* Main.storyboard */ = { 390 | isa = PBXVariantGroup; 391 | children = ( 392 | 239DC4CF21742DEC0034CCEE /* Base */, 393 | 2332F17A22B543BB00D56004 /* zh-Hans */, 394 | ); 395 | name = Main.storyboard; 396 | sourceTree = ""; 397 | }; 398 | 239DC4D321742DEC0034CCEE /* LaunchScreen.storyboard */ = { 399 | isa = PBXVariantGroup; 400 | children = ( 401 | 239DC4D421742DEC0034CCEE /* Base */, 402 | 2332F17B22B543BC00D56004 /* zh-Hans */, 403 | ); 404 | name = LaunchScreen.storyboard; 405 | sourceTree = ""; 406 | }; 407 | /* End PBXVariantGroup section */ 408 | 409 | /* Begin XCBuildConfiguration section */ 410 | 239DC4D921742DEC0034CCEE /* Debug */ = { 411 | isa = XCBuildConfiguration; 412 | buildSettings = { 413 | ALWAYS_SEARCH_USER_PATHS = NO; 414 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 415 | CLANG_ANALYZER_NONNULL = YES; 416 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 417 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 418 | CLANG_CXX_LIBRARY = "libc++"; 419 | CLANG_ENABLE_MODULES = YES; 420 | CLANG_ENABLE_OBJC_ARC = YES; 421 | CLANG_ENABLE_OBJC_WEAK = YES; 422 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 423 | CLANG_WARN_BOOL_CONVERSION = YES; 424 | CLANG_WARN_COMMA = YES; 425 | CLANG_WARN_CONSTANT_CONVERSION = YES; 426 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 427 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 428 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 429 | CLANG_WARN_EMPTY_BODY = YES; 430 | CLANG_WARN_ENUM_CONVERSION = YES; 431 | CLANG_WARN_INFINITE_RECURSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 434 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 435 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 436 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 437 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 438 | CLANG_WARN_STRICT_PROTOTYPES = YES; 439 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 440 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 441 | CLANG_WARN_UNREACHABLE_CODE = YES; 442 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 443 | CODE_SIGN_IDENTITY = "iPhone Developer"; 444 | COPY_PHASE_STRIP = NO; 445 | DEBUG_INFORMATION_FORMAT = dwarf; 446 | ENABLE_STRICT_OBJC_MSGSEND = YES; 447 | ENABLE_TESTABILITY = YES; 448 | GCC_C_LANGUAGE_STANDARD = gnu11; 449 | GCC_DYNAMIC_NO_PIC = NO; 450 | GCC_NO_COMMON_BLOCKS = YES; 451 | GCC_OPTIMIZATION_LEVEL = 0; 452 | GCC_PREPROCESSOR_DEFINITIONS = ( 453 | "DEBUG=1", 454 | "$(inherited)", 455 | ); 456 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 457 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 458 | GCC_WARN_UNDECLARED_SELECTOR = YES; 459 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 460 | GCC_WARN_UNUSED_FUNCTION = YES; 461 | GCC_WARN_UNUSED_VARIABLE = YES; 462 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 463 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 464 | MTL_FAST_MATH = YES; 465 | ONLY_ACTIVE_ARCH = YES; 466 | SDKROOT = iphoneos; 467 | }; 468 | name = Debug; 469 | }; 470 | 239DC4DA21742DEC0034CCEE /* Release */ = { 471 | isa = XCBuildConfiguration; 472 | buildSettings = { 473 | ALWAYS_SEARCH_USER_PATHS = NO; 474 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 475 | CLANG_ANALYZER_NONNULL = YES; 476 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 477 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 478 | CLANG_CXX_LIBRARY = "libc++"; 479 | CLANG_ENABLE_MODULES = YES; 480 | CLANG_ENABLE_OBJC_ARC = YES; 481 | CLANG_ENABLE_OBJC_WEAK = YES; 482 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 483 | CLANG_WARN_BOOL_CONVERSION = YES; 484 | CLANG_WARN_COMMA = YES; 485 | CLANG_WARN_CONSTANT_CONVERSION = YES; 486 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 487 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 488 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 489 | CLANG_WARN_EMPTY_BODY = YES; 490 | CLANG_WARN_ENUM_CONVERSION = YES; 491 | CLANG_WARN_INFINITE_RECURSION = YES; 492 | CLANG_WARN_INT_CONVERSION = YES; 493 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 494 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 495 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 496 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 497 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 498 | CLANG_WARN_STRICT_PROTOTYPES = YES; 499 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 500 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 501 | CLANG_WARN_UNREACHABLE_CODE = YES; 502 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 503 | CODE_SIGN_IDENTITY = "iPhone Developer"; 504 | COPY_PHASE_STRIP = NO; 505 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 506 | ENABLE_NS_ASSERTIONS = NO; 507 | ENABLE_STRICT_OBJC_MSGSEND = YES; 508 | GCC_C_LANGUAGE_STANDARD = gnu11; 509 | GCC_NO_COMMON_BLOCKS = YES; 510 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 511 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 512 | GCC_WARN_UNDECLARED_SELECTOR = YES; 513 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 514 | GCC_WARN_UNUSED_FUNCTION = YES; 515 | GCC_WARN_UNUSED_VARIABLE = YES; 516 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 517 | MTL_ENABLE_DEBUG_INFO = NO; 518 | MTL_FAST_MATH = YES; 519 | SDKROOT = iphoneos; 520 | VALIDATE_PRODUCT = YES; 521 | }; 522 | name = Release; 523 | }; 524 | 239DC4DC21742DEC0034CCEE /* Debug */ = { 525 | isa = XCBuildConfiguration; 526 | baseConfigurationReference = 0AC412465772644C017DDA70 /* Pods-LogKitExample.debug.xcconfig */; 527 | buildSettings = { 528 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 529 | CLANG_ENABLE_MODULES = YES; 530 | CODE_SIGN_IDENTITY = "iPhone Developer"; 531 | CODE_SIGN_STYLE = Automatic; 532 | DEVELOPMENT_TEAM = Q6J92FA9UY; 533 | INFOPLIST_FILE = LogKitExample/Info.plist; 534 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 535 | LD_RUNPATH_SEARCH_PATHS = ( 536 | "$(inherited)", 537 | "@executable_path/Frameworks", 538 | ); 539 | PRODUCT_BUNDLE_IDENTIFIER = com.BANYAN.LogKit.LogKitExample; 540 | PRODUCT_NAME = "$(TARGET_NAME)"; 541 | PROVISIONING_PROFILE_SPECIFIER = ""; 542 | SWIFT_OBJC_BRIDGING_HEADER = "../Logkit/LogKitExample-Bridging-Header.h"; 543 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 544 | SWIFT_VERSION = 5.0; 545 | TARGETED_DEVICE_FAMILY = 1; 546 | }; 547 | name = Debug; 548 | }; 549 | 239DC4DD21742DEC0034CCEE /* Release */ = { 550 | isa = XCBuildConfiguration; 551 | baseConfigurationReference = 19109B3FDD1D6B4EECDA8D58 /* Pods-LogKitExample.release.xcconfig */; 552 | buildSettings = { 553 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 554 | CLANG_ENABLE_MODULES = YES; 555 | CODE_SIGN_IDENTITY = "iPhone Developer"; 556 | CODE_SIGN_STYLE = Automatic; 557 | DEVELOPMENT_TEAM = Q6J92FA9UY; 558 | INFOPLIST_FILE = LogKitExample/Info.plist; 559 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 560 | LD_RUNPATH_SEARCH_PATHS = ( 561 | "$(inherited)", 562 | "@executable_path/Frameworks", 563 | ); 564 | PRODUCT_BUNDLE_IDENTIFIER = com.BANYAN.LogKit.LogKitExample; 565 | PRODUCT_NAME = "$(TARGET_NAME)"; 566 | PROVISIONING_PROFILE_SPECIFIER = ""; 567 | SWIFT_OBJC_BRIDGING_HEADER = "../Logkit/LogKitExample-Bridging-Header.h"; 568 | SWIFT_VERSION = 5.0; 569 | TARGETED_DEVICE_FAMILY = 1; 570 | }; 571 | name = Release; 572 | }; 573 | 239DC503217431290034CCEE /* Debug */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | BUNDLE_LOADER = "$(TEST_HOST)"; 577 | CODE_SIGN_STYLE = Automatic; 578 | DEVELOPMENT_TEAM = W335NUPQPJ; 579 | INFOPLIST_FILE = LogKitExampleTests/Info.plist; 580 | LD_RUNPATH_SEARCH_PATHS = ( 581 | "$(inherited)", 582 | "@executable_path/Frameworks", 583 | "@loader_path/Frameworks", 584 | ); 585 | PRODUCT_BUNDLE_IDENTIFIER = com.BANYAN.LogKit.LogKitExampleTests; 586 | PRODUCT_NAME = "$(TARGET_NAME)"; 587 | TARGETED_DEVICE_FAMILY = "1,2"; 588 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LogKitExample.app/LogKitExample"; 589 | }; 590 | name = Debug; 591 | }; 592 | 239DC504217431290034CCEE /* Release */ = { 593 | isa = XCBuildConfiguration; 594 | buildSettings = { 595 | BUNDLE_LOADER = "$(TEST_HOST)"; 596 | CODE_SIGN_STYLE = Automatic; 597 | DEVELOPMENT_TEAM = W335NUPQPJ; 598 | INFOPLIST_FILE = LogKitExampleTests/Info.plist; 599 | LD_RUNPATH_SEARCH_PATHS = ( 600 | "$(inherited)", 601 | "@executable_path/Frameworks", 602 | "@loader_path/Frameworks", 603 | ); 604 | PRODUCT_BUNDLE_IDENTIFIER = com.BANYAN.LogKit.LogKitExampleTests; 605 | PRODUCT_NAME = "$(TARGET_NAME)"; 606 | TARGETED_DEVICE_FAMILY = "1,2"; 607 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LogKitExample.app/LogKitExample"; 608 | }; 609 | name = Release; 610 | }; 611 | /* End XCBuildConfiguration section */ 612 | 613 | /* Begin XCConfigurationList section */ 614 | 239DC4C021742DEC0034CCEE /* Build configuration list for PBXProject "LogKitExample" */ = { 615 | isa = XCConfigurationList; 616 | buildConfigurations = ( 617 | 239DC4D921742DEC0034CCEE /* Debug */, 618 | 239DC4DA21742DEC0034CCEE /* Release */, 619 | ); 620 | defaultConfigurationIsVisible = 0; 621 | defaultConfigurationName = Release; 622 | }; 623 | 239DC4DB21742DEC0034CCEE /* Build configuration list for PBXNativeTarget "LogKitExample" */ = { 624 | isa = XCConfigurationList; 625 | buildConfigurations = ( 626 | 239DC4DC21742DEC0034CCEE /* Debug */, 627 | 239DC4DD21742DEC0034CCEE /* Release */, 628 | ); 629 | defaultConfigurationIsVisible = 0; 630 | defaultConfigurationName = Release; 631 | }; 632 | 239DC502217431290034CCEE /* Build configuration list for PBXNativeTarget "LogKitExampleTests" */ = { 633 | isa = XCConfigurationList; 634 | buildConfigurations = ( 635 | 239DC503217431290034CCEE /* Debug */, 636 | 239DC504217431290034CCEE /* Release */, 637 | ); 638 | defaultConfigurationIsVisible = 0; 639 | defaultConfigurationName = Release; 640 | }; 641 | /* End XCConfigurationList section */ 642 | }; 643 | rootObject = 239DC4BD21742DEC0034CCEE /* Project object */; 644 | } 645 | --------------------------------------------------------------------------------