@josuelmm/capacitor-background-geolocation 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/JosuelmmCapacitorBackgroundGeolocation.podspec +34 -0
  2. package/LICENSE +17 -0
  3. package/NOTICE.md +32 -0
  4. package/Package.swift +45 -0
  5. package/README.md +402 -0
  6. package/android/build.gradle +79 -0
  7. package/android/proguard-rules.pro +1 -0
  8. package/android/src/main/AndroidManifest.xml +83 -0
  9. package/android/src/main/java/com/evgenii/jsevaluator/HandlerWrapper.java +18 -0
  10. package/android/src/main/java/com/evgenii/jsevaluator/JavaScriptInterface.java +22 -0
  11. package/android/src/main/java/com/evgenii/jsevaluator/JsEvaluator.java +133 -0
  12. package/android/src/main/java/com/evgenii/jsevaluator/JsFunctionCallFormatter.java +37 -0
  13. package/android/src/main/java/com/evgenii/jsevaluator/WebViewWrapper.java +71 -0
  14. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/CallJavaResultInterface.java +8 -0
  15. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/HandlerWrapperInterface.java +5 -0
  16. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsCallback.java +10 -0
  17. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsEvaluatorInterface.java +18 -0
  18. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/WebViewWrapperInterface.java +14 -0
  19. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/BackgroundGeolocationPlugin.java +898 -0
  20. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/ConfigMapper.java +303 -0
  21. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/HeadlessTaskRegistry.java +34 -0
  22. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/JsEvaluatorTaskRunner.java +63 -0
  23. package/android/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java +699 -0
  24. package/android/src/main/java/com/marianhello/bgloc/BootCompletedReceiver.java +103 -0
  25. package/android/src/main/java/com/marianhello/bgloc/Config.java +1155 -0
  26. package/android/src/main/java/com/marianhello/bgloc/ConnectivityListener.java +5 -0
  27. package/android/src/main/java/com/marianhello/bgloc/HttpPostService.java +362 -0
  28. package/android/src/main/java/com/marianhello/bgloc/LocationManager.java +138 -0
  29. package/android/src/main/java/com/marianhello/bgloc/PluginDelegate.java +45 -0
  30. package/android/src/main/java/com/marianhello/bgloc/PluginException.java +38 -0
  31. package/android/src/main/java/com/marianhello/bgloc/PostLocationTask.java +238 -0
  32. package/android/src/main/java/com/marianhello/bgloc/ResourceResolver.java +55 -0
  33. package/android/src/main/java/com/marianhello/bgloc/data/AbstractLocationTemplate.java +69 -0
  34. package/android/src/main/java/com/marianhello/bgloc/data/ArrayListLocationTemplate.java +88 -0
  35. package/android/src/main/java/com/marianhello/bgloc/data/BackgroundActivity.java +108 -0
  36. package/android/src/main/java/com/marianhello/bgloc/data/BackgroundLocation.java +1088 -0
  37. package/android/src/main/java/com/marianhello/bgloc/data/ConfigJsonMapper.java +211 -0
  38. package/android/src/main/java/com/marianhello/bgloc/data/ConfigurationDAO.java +13 -0
  39. package/android/src/main/java/com/marianhello/bgloc/data/DAOFactory.java +17 -0
  40. package/android/src/main/java/com/marianhello/bgloc/data/HashMapLocationTemplate.java +82 -0
  41. package/android/src/main/java/com/marianhello/bgloc/data/LocationDAO.java +27 -0
  42. package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplate.java +12 -0
  43. package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplateFactory.java +71 -0
  44. package/android/src/main/java/com/marianhello/bgloc/data/LocationTransform.java +19 -0
  45. package/android/src/main/java/com/marianhello/bgloc/data/SessionLocationDAO.java +18 -0
  46. package/android/src/main/java/com/marianhello/bgloc/data/provider/ContentProviderLocationDAO.java +406 -0
  47. package/android/src/main/java/com/marianhello/bgloc/data/provider/LocationContentProvider.java +321 -0
  48. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationContract.java +94 -0
  49. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationDAO.java +227 -0
  50. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationContract.java +122 -0
  51. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationDAO.java +550 -0
  52. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteOpenHelper.java +189 -0
  53. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionContract.java +74 -0
  54. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionLocationDAO.java +169 -0
  55. package/android/src/main/java/com/marianhello/bgloc/driving/DrivingEventsDetector.java +265 -0
  56. package/android/src/main/java/com/marianhello/bgloc/headless/AbstractTaskRunner.java +15 -0
  57. package/android/src/main/java/com/marianhello/bgloc/headless/ActivityTask.java +48 -0
  58. package/android/src/main/java/com/marianhello/bgloc/headless/JsCallback.java +10 -0
  59. package/android/src/main/java/com/marianhello/bgloc/headless/LocationTask.java +60 -0
  60. package/android/src/main/java/com/marianhello/bgloc/headless/StationaryTask.java +25 -0
  61. package/android/src/main/java/com/marianhello/bgloc/headless/Task.java +8 -0
  62. package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunner.java +5 -0
  63. package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunnerFactory.java +8 -0
  64. package/android/src/main/java/com/marianhello/bgloc/http/UrlTemplateResolver.java +115 -0
  65. package/android/src/main/java/com/marianhello/bgloc/oem/BatteryOemHelper.java +214 -0
  66. package/android/src/main/java/com/marianhello/bgloc/provider/AbstractLocationProvider.java +218 -0
  67. package/android/src/main/java/com/marianhello/bgloc/provider/ActivityRecognitionLocationProvider.java +385 -0
  68. package/android/src/main/java/com/marianhello/bgloc/provider/DistanceFilterLocationProvider.java +685 -0
  69. package/android/src/main/java/com/marianhello/bgloc/provider/LocationProvider.java +32 -0
  70. package/android/src/main/java/com/marianhello/bgloc/provider/LocationProviderFactory.java +47 -0
  71. package/android/src/main/java/com/marianhello/bgloc/provider/ProviderDelegate.java +12 -0
  72. package/android/src/main/java/com/marianhello/bgloc/provider/RawLocationProvider.java +175 -0
  73. package/android/src/main/java/com/marianhello/bgloc/sensor/SensorFusionDetector.java +199 -0
  74. package/android/src/main/java/com/marianhello/bgloc/service/LocationService.java +16 -0
  75. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceImpl.java +1531 -0
  76. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfo.java +6 -0
  77. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfoImpl.java +41 -0
  78. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceIntentBuilder.java +203 -0
  79. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceProxy.java +156 -0
  80. package/android/src/main/java/com/marianhello/bgloc/sync/AccountHelper.java +39 -0
  81. package/android/src/main/java/com/marianhello/bgloc/sync/Authenticator.java +68 -0
  82. package/android/src/main/java/com/marianhello/bgloc/sync/AuthenticatorService.java +28 -0
  83. package/android/src/main/java/com/marianhello/bgloc/sync/BatchManager.java +311 -0
  84. package/android/src/main/java/com/marianhello/bgloc/sync/NotificationHelper.java +148 -0
  85. package/android/src/main/java/com/marianhello/bgloc/sync/SyncAdapter.java +301 -0
  86. package/android/src/main/java/com/marianhello/bgloc/sync/SyncService.java +68 -0
  87. package/android/src/main/java/com/marianhello/logging/DBLogReader.java +208 -0
  88. package/android/src/main/java/com/marianhello/logging/LogEntry.java +99 -0
  89. package/android/src/main/java/com/marianhello/logging/LoggerManager.java +70 -0
  90. package/android/src/main/java/com/marianhello/logging/UncaughtExceptionLogger.java +36 -0
  91. package/android/src/main/java/com/marianhello/utils/CloneHelper.java +22 -0
  92. package/android/src/main/java/com/marianhello/utils/Convert.java +56 -0
  93. package/android/src/main/java/com/marianhello/utils/TextUtils.java +72 -0
  94. package/android/src/main/java/com/marianhello/utils/ToneGenerator.java +68 -0
  95. package/android/src/main/java/org/apache/commons/io/Charsets.java +153 -0
  96. package/android/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +344 -0
  97. package/android/src/main/java/org/chromium/content/browser/ThreadUtils.java +134 -0
  98. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlExpression.java +398 -0
  99. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlSelectStatement.java +671 -0
  100. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlStatement.java +29 -0
  101. package/android/src/main/java/ru/andremoniy/utils/TextUtils.java +61 -0
  102. package/android/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  103. package/android/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  104. package/android/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  105. package/android/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  106. package/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  107. package/android/src/main/res/values/strings.xml +15 -0
  108. package/android/src/main/res/xml/authenticator.xml +7 -0
  109. package/android/src/main/res/xml/syncadapter.xml +9 -0
  110. package/dist/esm/definitions.d.ts +1052 -0
  111. package/dist/esm/definitions.js +142 -0
  112. package/dist/esm/definitions.js.map +1 -0
  113. package/dist/esm/index.d.ts +8 -0
  114. package/dist/esm/index.js +23 -0
  115. package/dist/esm/index.js.map +1 -0
  116. package/dist/esm/web.d.ts +92 -0
  117. package/dist/esm/web.js +242 -0
  118. package/dist/esm/web.js.map +1 -0
  119. package/dist/plugin.cjs.js +415 -0
  120. package/dist/plugin.cjs.js.map +1 -0
  121. package/dist/plugin.js +418 -0
  122. package/dist/plugin.js.map +1 -0
  123. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin-Bridging-Header.h +18 -0
  124. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.m +52 -0
  125. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.swift +750 -0
  126. package/ios/Tests/BackgroundGeolocationPluginTests/BackgroundGeolocationPluginTests.swift +12 -0
  127. package/ios/common/BackgroundGeolocation/CocoaLumberjack.h +1945 -0
  128. package/ios/common/BackgroundGeolocation/CocoaLumberjack.m +5255 -0
  129. package/ios/common/BackgroundGeolocation/FMDB.h +2357 -0
  130. package/ios/common/BackgroundGeolocation/FMDB.m +2672 -0
  131. package/ios/common/BackgroundGeolocation/FMDBLogger.h +42 -0
  132. package/ios/common/BackgroundGeolocation/FMDBLogger.m +264 -0
  133. package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.h +41 -0
  134. package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.m +68 -0
  135. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager+Internal.h +33 -0
  136. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.h +178 -0
  137. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.m +1025 -0
  138. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.h +103 -0
  139. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.m +238 -0
  140. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequestDefines.h +163 -0
  141. package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.h +39 -0
  142. package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.m +37 -0
  143. package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.h +51 -0
  144. package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.m +53 -0
  145. package/ios/common/BackgroundGeolocation/MAURActivity.h +23 -0
  146. package/ios/common/BackgroundGeolocation/MAURActivity.m +52 -0
  147. package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.h +18 -0
  148. package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.m +340 -0
  149. package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.h +88 -0
  150. package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.m +1193 -0
  151. package/ios/common/BackgroundGeolocation/MAURBackgroundSync.h +46 -0
  152. package/ios/common/BackgroundGeolocation/MAURBackgroundSync.m +283 -0
  153. package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.h +25 -0
  154. package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.m +105 -0
  155. package/ios/common/BackgroundGeolocation/MAURConfig.h +99 -0
  156. package/ios/common/BackgroundGeolocation/MAURConfig.m +636 -0
  157. package/ios/common/BackgroundGeolocation/MAURConfigurationContract.h +53 -0
  158. package/ios/common/BackgroundGeolocation/MAURConfigurationContract.m +54 -0
  159. package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.h +20 -0
  160. package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.m +550 -0
  161. package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.h +17 -0
  162. package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.m +124 -0
  163. package/ios/common/BackgroundGeolocation/MAURLocation.h +73 -0
  164. package/ios/common/BackgroundGeolocation/MAURLocation.m +392 -0
  165. package/ios/common/BackgroundGeolocation/MAURLocationContract.h +38 -0
  166. package/ios/common/BackgroundGeolocation/MAURLocationContract.m +39 -0
  167. package/ios/common/BackgroundGeolocation/MAURLocationManager.h +53 -0
  168. package/ios/common/BackgroundGeolocation/MAURLocationManager.m +305 -0
  169. package/ios/common/BackgroundGeolocation/MAURLogReader.h +26 -0
  170. package/ios/common/BackgroundGeolocation/MAURLogReader.m +122 -0
  171. package/ios/common/BackgroundGeolocation/MAURLogging.h +19 -0
  172. package/ios/common/BackgroundGeolocation/MAURPostLocationTask.h +53 -0
  173. package/ios/common/BackgroundGeolocation/MAURPostLocationTask.m +367 -0
  174. package/ios/common/BackgroundGeolocation/MAURProviderDelegate.h +52 -0
  175. package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.h +18 -0
  176. package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.m +138 -0
  177. package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.h +26 -0
  178. package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.m +335 -0
  179. package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.h +57 -0
  180. package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.m +93 -0
  181. package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.h +52 -0
  182. package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.m +520 -0
  183. package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.h +32 -0
  184. package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.m +276 -0
  185. package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.h +41 -0
  186. package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.m +137 -0
  187. package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.h +29 -0
  188. package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.m +31 -0
  189. package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.h +25 -0
  190. package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.m +153 -0
  191. package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.h +20 -0
  192. package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.m +62 -0
  193. package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.h +31 -0
  194. package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.m +107 -0
  195. package/ios/common/BackgroundGeolocation/Reachability.h +102 -0
  196. package/ios/common/BackgroundGeolocation/Reachability.m +475 -0
  197. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/README.md +170 -0
  198. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.h +55 -0
  199. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.m +47 -0
  200. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlDataManipulationCommand.h +27 -0
  201. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.h +250 -0
  202. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.m +259 -0
  203. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.h +360 -0
  204. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.m +427 -0
  205. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlStatement.h +37 -0
  206. package/ios/common/BackgroundGeolocation/module.modulemap +16 -0
  207. package/package.json +82 -0
@@ -0,0 +1,1945 @@
1
+ // Software License Agreement (BSD License)
2
+ //
3
+ // Copyright (c) 2010-2016, Deusty, LLC
4
+ // All rights reserved.
5
+ //
6
+ // Redistribution and use of this software in source and binary forms,
7
+ // with or without modification, are permitted provided that the following conditions are met:
8
+ //
9
+ // * Redistributions of source code must retain the above copyright notice,
10
+ // this list of conditions and the following disclaimer.
11
+ //
12
+ // * Neither the name of Deusty nor the names of its contributors may be used
13
+ // to endorse or promote products derived from this software without specific
14
+ // prior written permission of Deusty, LLC.
15
+
16
+ /**
17
+ * Legacy macros used for 1.9.x backwards compatibility.
18
+ *
19
+ * Imported by default when importing a DDLog.h directly and DD_LEGACY_MACROS is not defined and set to 0.
20
+ **/
21
+ #if DD_LEGACY_MACROS
22
+
23
+ #warning CocoaLumberjack 1.9.x legacy macros enabled. \
24
+ Disable legacy macros by importing CocoaLumberjack.h or DDLogMacros.h instead of DDLog.h or add `#define DD_LEGACY_MACROS 0` before importing DDLog.h.
25
+
26
+ #ifndef LOG_LEVEL_DEF
27
+ #define LOG_LEVEL_DEF ddLogLevel
28
+ #endif
29
+
30
+ #define LOG_FLAG_ERROR DDLogFlagError
31
+ #define LOG_FLAG_WARN DDLogFlagWarning
32
+ #define LOG_FLAG_INFO DDLogFlagInfo
33
+ #define LOG_FLAG_DEBUG DDLogFlagDebug
34
+ #define LOG_FLAG_VERBOSE DDLogFlagVerbose
35
+
36
+ #define LOG_LEVEL_OFF DDLogLevelOff
37
+ #define LOG_LEVEL_ERROR DDLogLevelError
38
+ #define LOG_LEVEL_WARN DDLogLevelWarning
39
+ #define LOG_LEVEL_INFO DDLogLevelInfo
40
+ #define LOG_LEVEL_DEBUG DDLogLevelDebug
41
+ #define LOG_LEVEL_VERBOSE DDLogLevelVerbose
42
+ #define LOG_LEVEL_ALL DDLogLevelAll
43
+
44
+ #define LOG_ASYNC_ENABLED YES
45
+
46
+ #define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED)
47
+ #define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED)
48
+ #define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED)
49
+ #define LOG_ASYNC_DEBUG (YES && LOG_ASYNC_ENABLED)
50
+ #define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED)
51
+
52
+ #define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
53
+ [DDLog log : isAsynchronous \
54
+ level : lvl \
55
+ flag : flg \
56
+ context : ctx \
57
+ file : __FILE__ \
58
+ function : fnct \
59
+ line : __LINE__ \
60
+ tag : atag \
61
+ format : (frmt), ## __VA_ARGS__]
62
+
63
+ #define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \
64
+ do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
65
+
66
+ #define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
67
+ LOG_MAYBE(async, lvl, flg, ctx, __PRETTY_FUNCTION__, frmt, ## __VA_ARGS__)
68
+
69
+ #define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__)
70
+ #define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__)
71
+ #define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__)
72
+ #define DDLogDebug(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ##__VA_ARGS__)
73
+ #define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
74
+
75
+ #endif
76
+ // Software License Agreement (BSD License)
77
+ //
78
+ // Copyright (c) 2010-2016, Deusty, LLC
79
+ // All rights reserved.
80
+ //
81
+ // Redistribution and use of this software in source and binary forms,
82
+ // with or without modification, are permitted provided that the following conditions are met:
83
+ //
84
+ // * Redistributions of source code must retain the above copyright notice,
85
+ // this list of conditions and the following disclaimer.
86
+ //
87
+ // * Neither the name of Deusty nor the names of its contributors may be used
88
+ // to endorse or promote products derived from this software without specific
89
+ // prior written permission of Deusty, LLC.
90
+
91
+ #import <Foundation/Foundation.h>
92
+
93
+ // Enable 1.9.x legacy macros if imported directly
94
+ #ifndef DD_LEGACY_MACROS
95
+ #define DD_LEGACY_MACROS 1
96
+ #endif
97
+
98
+ #if OS_OBJECT_USE_OBJC
99
+ #define DISPATCH_QUEUE_REFERENCE_TYPE strong
100
+ #else
101
+ #define DISPATCH_QUEUE_REFERENCE_TYPE assign
102
+ #endif
103
+
104
+ @class DDLogMessage;
105
+ @protocol DDLogger;
106
+ @protocol DDLogFormatter;
107
+
108
+ /**
109
+ * Define the standard options.
110
+ *
111
+ * We default to only 4 levels because it makes it easier for beginners
112
+ * to make the transition to a logging framework.
113
+ *
114
+ * More advanced users may choose to completely customize the levels (and level names) to suite their needs.
115
+ * For more information on this see the "Custom Log Levels" page:
116
+ * Documentation/CustomLogLevels.md
117
+ *
118
+ * Advanced users may also notice that we're using a bitmask.
119
+ * This is to allow for custom fine grained logging:
120
+ * Documentation/FineGrainedLogging.md
121
+ *
122
+ * -- Flags --
123
+ *
124
+ * Typically you will use the LOG_LEVELS (see below), but the flags may be used directly in certain situations.
125
+ * For example, say you have a lot of warning log messages, and you wanted to disable them.
126
+ * However, you still needed to see your error and info log messages.
127
+ * You could accomplish that with the following:
128
+ *
129
+ * static const DDLogLevel ddLogLevel = DDLogFlagError | DDLogFlagInfo;
130
+ *
131
+ * When LOG_LEVEL_DEF is defined as ddLogLevel.
132
+ *
133
+ * Flags may also be consulted when writing custom log formatters,
134
+ * as the DDLogMessage class captures the individual flag that caused the log message to fire.
135
+ *
136
+ * -- Levels --
137
+ *
138
+ * Log levels are simply the proper bitmask of the flags.
139
+ *
140
+ * -- Booleans --
141
+ *
142
+ * The booleans may be used when your logging code involves more than one line.
143
+ * For example:
144
+ *
145
+ * if (LOG_VERBOSE) {
146
+ * for (id sprocket in sprockets)
147
+ * DDLogVerbose(@"sprocket: %@", [sprocket description])
148
+ * }
149
+ *
150
+ * -- Async --
151
+ *
152
+ * Defines the default asynchronous options.
153
+ * The default philosophy for asynchronous logging is very simple:
154
+ *
155
+ * Log messages with errors should be executed synchronously.
156
+ * After all, an error just occurred. The application could be unstable.
157
+ *
158
+ * All other log messages, such as debug output, are executed asynchronously.
159
+ * After all, if it wasn't an error, then it was just informational output,
160
+ * or something the application was easily able to recover from.
161
+ *
162
+ * -- Changes --
163
+ *
164
+ * You are strongly discouraged from modifying this file.
165
+ * If you do, you make it more difficult on yourself to merge future bug fixes and improvements from the project.
166
+ * Instead, create your own MyLogging.h or ApplicationNameLogging.h or CompanyLogging.h
167
+ *
168
+ * For an example of customizing your logging experience, see the "Custom Log Levels" page:
169
+ * Documentation/CustomLogLevels.md
170
+ **/
171
+
172
+ /**
173
+ * Flags accompany each log. They are used together with levels to filter out logs.
174
+ */
175
+ typedef NS_OPTIONS(NSUInteger, DDLogFlag){
176
+ /**
177
+ * 0...00001 DDLogFlagError
178
+ */
179
+ DDLogFlagError = (1 << 0),
180
+
181
+ /**
182
+ * 0...00010 DDLogFlagWarning
183
+ */
184
+ DDLogFlagWarning = (1 << 1),
185
+
186
+ /**
187
+ * 0...00100 DDLogFlagInfo
188
+ */
189
+ DDLogFlagInfo = (1 << 2),
190
+
191
+ /**
192
+ * 0...01000 DDLogFlagDebug
193
+ */
194
+ DDLogFlagDebug = (1 << 3),
195
+
196
+ /**
197
+ * 0...10000 DDLogFlagVerbose
198
+ */
199
+ DDLogFlagVerbose = (1 << 4)
200
+ };
201
+
202
+ /**
203
+ * Log levels are used to filter out logs. Used together with flags.
204
+ */
205
+ typedef NS_ENUM(NSUInteger, DDLogLevel){
206
+ /**
207
+ * No logs
208
+ */
209
+ DDLogLevelOff = 0,
210
+
211
+ /**
212
+ * Error logs only
213
+ */
214
+ DDLogLevelError = (DDLogFlagError),
215
+
216
+ /**
217
+ * Error and warning logs
218
+ */
219
+ DDLogLevelWarning = (DDLogLevelError | DDLogFlagWarning),
220
+
221
+ /**
222
+ * Error, warning and info logs
223
+ */
224
+ DDLogLevelInfo = (DDLogLevelWarning | DDLogFlagInfo),
225
+
226
+ /**
227
+ * Error, warning, info and debug logs
228
+ */
229
+ DDLogLevelDebug = (DDLogLevelInfo | DDLogFlagDebug),
230
+
231
+ /**
232
+ * Error, warning, info, debug and verbose logs
233
+ */
234
+ DDLogLevelVerbose = (DDLogLevelDebug | DDLogFlagVerbose),
235
+
236
+ /**
237
+ * All logs (1...11111)
238
+ */
239
+ DDLogLevelAll = NSUIntegerMax
240
+ };
241
+
242
+ /**
243
+ * Extracts just the file name, no path or extension
244
+ *
245
+ * @param filePath input file path
246
+ * @param copy YES if we want the result to be copied
247
+ *
248
+ * @return the file name
249
+ */
250
+ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
251
+
252
+ /**
253
+ * The THIS_FILE macro gives you an NSString of the file name.
254
+ * For simplicity and clarity, the file name does not include the full path or file extension.
255
+ *
256
+ * For example: DDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy"
257
+ **/
258
+ #define THIS_FILE (DDExtractFileNameWithoutExtension(__FILE__, NO))
259
+
260
+ /**
261
+ * The THIS_METHOD macro gives you the name of the current objective-c method.
262
+ *
263
+ * For example: DDLogWarn(@"%@ - Requires non-nil strings", THIS_METHOD) -> @"setMake:model: requires non-nil strings"
264
+ *
265
+ * Note: This does NOT work in straight C functions (non objective-c).
266
+ * Instead you should use the predefined __FUNCTION__ macro.
267
+ **/
268
+ #define THIS_METHOD NSStringFromSelector(_cmd)
269
+
270
+
271
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
272
+ #pragma mark -
273
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
274
+
275
+ /**
276
+ * The main class, exposes all logging mechanisms, loggers, ...
277
+ * For most of the users, this class is hidden behind the logging functions like `DDLogInfo`
278
+ */
279
+ @interface DDLog : NSObject
280
+
281
+ /**
282
+ * Returns the singleton `DDLog`.
283
+ * The instance is used by `DDLog` class methods.
284
+ *
285
+ * @return The singleton `DDLog`.
286
+ */
287
+ + (instancetype)sharedInstance;
288
+
289
+ /**
290
+ * Provides access to the underlying logging queue.
291
+ * This may be helpful to Logger classes for things like thread synchronization.
292
+ **/
293
+ + (dispatch_queue_t)loggingQueue;
294
+
295
+ /**
296
+ * Logging Primitive.
297
+ *
298
+ * This method is used by the macros or logging functions.
299
+ * It is suggested you stick with the macros as they're easier to use.
300
+ *
301
+ * @param asynchronous YES if the logging is done async, NO if you want to force sync
302
+ * @param level the log level
303
+ * @param flag the log flag
304
+ * @param context the context (if any is defined)
305
+ * @param file the current file
306
+ * @param function the current function
307
+ * @param line the current code line
308
+ * @param tag potential tag
309
+ * @param format the log format
310
+ */
311
+ + (void)log:(BOOL)asynchronous
312
+ level:(DDLogLevel)level
313
+ flag:(DDLogFlag)flag
314
+ context:(NSInteger)context
315
+ file:(const char *)file
316
+ function:(const char *)function
317
+ line:(NSUInteger)line
318
+ tag:(id)tag
319
+ format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
320
+
321
+ /**
322
+ * Logging Primitive.
323
+ *
324
+ * This method is used by the macros or logging functions.
325
+ * It is suggested you stick with the macros as they're easier to use.
326
+ *
327
+ * @param asynchronous YES if the logging is done async, NO if you want to force sync
328
+ * @param level the log level
329
+ * @param flag the log flag
330
+ * @param context the context (if any is defined)
331
+ * @param file the current file
332
+ * @param function the current function
333
+ * @param line the current code line
334
+ * @param tag potential tag
335
+ * @param format the log format
336
+ */
337
+ - (void)log:(BOOL)asynchronous
338
+ level:(DDLogLevel)level
339
+ flag:(DDLogFlag)flag
340
+ context:(NSInteger)context
341
+ file:(const char *)file
342
+ function:(const char *)function
343
+ line:(NSUInteger)line
344
+ tag:(id)tag
345
+ format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
346
+
347
+ /**
348
+ * Logging Primitive.
349
+ *
350
+ * This method can be used if you have a prepared va_list.
351
+ * Similar to `log:level:flag:context:file:function:line:tag:format:...`
352
+ *
353
+ * @param asynchronous YES if the logging is done async, NO if you want to force sync
354
+ * @param level the log level
355
+ * @param flag the log flag
356
+ * @param context the context (if any is defined)
357
+ * @param file the current file
358
+ * @param function the current function
359
+ * @param line the current code line
360
+ * @param tag potential tag
361
+ * @param format the log format
362
+ * @param argList the arguments list as a va_list
363
+ */
364
+ + (void)log:(BOOL)asynchronous
365
+ level:(DDLogLevel)level
366
+ flag:(DDLogFlag)flag
367
+ context:(NSInteger)context
368
+ file:(const char *)file
369
+ function:(const char *)function
370
+ line:(NSUInteger)line
371
+ tag:(id)tag
372
+ format:(NSString *)format
373
+ args:(va_list)argList;
374
+
375
+ /**
376
+ * Logging Primitive.
377
+ *
378
+ * This method can be used if you have a prepared va_list.
379
+ * Similar to `log:level:flag:context:file:function:line:tag:format:...`
380
+ *
381
+ * @param asynchronous YES if the logging is done async, NO if you want to force sync
382
+ * @param level the log level
383
+ * @param flag the log flag
384
+ * @param context the context (if any is defined)
385
+ * @param file the current file
386
+ * @param function the current function
387
+ * @param line the current code line
388
+ * @param tag potential tag
389
+ * @param format the log format
390
+ * @param argList the arguments list as a va_list
391
+ */
392
+ - (void)log:(BOOL)asynchronous
393
+ level:(DDLogLevel)level
394
+ flag:(DDLogFlag)flag
395
+ context:(NSInteger)context
396
+ file:(const char *)file
397
+ function:(const char *)function
398
+ line:(NSUInteger)line
399
+ tag:(id)tag
400
+ format:(NSString *)format
401
+ args:(va_list)argList;
402
+
403
+ /**
404
+ * Logging Primitive.
405
+ *
406
+ * This method can be used if you manualy prepared DDLogMessage.
407
+ *
408
+ * @param asynchronous YES if the logging is done async, NO if you want to force sync
409
+ * @param logMessage the log message stored in a `DDLogMessage` model object
410
+ */
411
+ + (void)log:(BOOL)asynchronous
412
+ message:(DDLogMessage *)logMessage;
413
+
414
+ /**
415
+ * Logging Primitive.
416
+ *
417
+ * This method can be used if you manualy prepared DDLogMessage.
418
+ *
419
+ * @param asynchronous YES if the logging is done async, NO if you want to force sync
420
+ * @param logMessage the log message stored in a `DDLogMessage` model object
421
+ */
422
+ - (void)log:(BOOL)asynchronous
423
+ message:(DDLogMessage *)logMessage;
424
+
425
+ /**
426
+ * Since logging can be asynchronous, there may be times when you want to flush the logs.
427
+ * The framework invokes this automatically when the application quits.
428
+ **/
429
+ + (void)flushLog;
430
+
431
+ /**
432
+ * Since logging can be asynchronous, there may be times when you want to flush the logs.
433
+ * The framework invokes this automatically when the application quits.
434
+ **/
435
+ - (void)flushLog;
436
+
437
+ /**
438
+ * Loggers
439
+ *
440
+ * In order for your log statements to go somewhere, you should create and add a logger.
441
+ *
442
+ * You can add multiple loggers in order to direct your log statements to multiple places.
443
+ * And each logger can be configured separately.
444
+ * So you could have, for example, verbose logging to the console, but a concise log file with only warnings & errors.
445
+ **/
446
+
447
+ /**
448
+ * Adds the logger to the system.
449
+ *
450
+ * This is equivalent to invoking `[DDLog addLogger:logger withLogLevel:DDLogLevelAll]`.
451
+ **/
452
+ + (void)addLogger:(id <DDLogger>)logger;
453
+
454
+ /**
455
+ * Adds the logger to the system.
456
+ *
457
+ * This is equivalent to invoking `[DDLog addLogger:logger withLogLevel:DDLogLevelAll]`.
458
+ **/
459
+ - (void)addLogger:(id <DDLogger>)logger;
460
+
461
+ /**
462
+ * Adds the logger to the system.
463
+ *
464
+ * The level that you provide here is a preemptive filter (for performance).
465
+ * That is, the level specified here will be used to filter out logMessages so that
466
+ * the logger is never even invoked for the messages.
467
+ *
468
+ * More information:
469
+ * When you issue a log statement, the logging framework iterates over each logger,
470
+ * and checks to see if it should forward the logMessage to the logger.
471
+ * This check is done using the level parameter passed to this method.
472
+ *
473
+ * For example:
474
+ *
475
+ * `[DDLog addLogger:consoleLogger withLogLevel:DDLogLevelVerbose];`
476
+ * `[DDLog addLogger:fileLogger withLogLevel:DDLogLevelWarning];`
477
+ *
478
+ * `DDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
479
+ * `DDLogInfo(@"hi");` => gets forwarded to consoleLogger only
480
+ *
481
+ * It is important to remember that Lumberjack uses a BITMASK.
482
+ * Many developers & third party frameworks may define extra log levels & flags.
483
+ * For example:
484
+ *
485
+ * `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
486
+ *
487
+ * So if you specify `DDLogLevelVerbose` to this method, you won't see the framework's trace messages.
488
+ *
489
+ * `(SOME_FRAMEWORK_LOG_FLAG_TRACE & DDLogLevelVerbose) => (01000000 & 00011111) => NO`
490
+ *
491
+ * Consider passing `DDLogLevelAll` to this method, which has all bits set.
492
+ * You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
493
+ * except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
494
+ *
495
+ * `((DDLogLevelAll ^ DDLogLevelVerbose) | DDLogLevelInfo)`
496
+ **/
497
+ + (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
498
+
499
+ /**
500
+ * Adds the logger to the system.
501
+ *
502
+ * The level that you provide here is a preemptive filter (for performance).
503
+ * That is, the level specified here will be used to filter out logMessages so that
504
+ * the logger is never even invoked for the messages.
505
+ *
506
+ * More information:
507
+ * When you issue a log statement, the logging framework iterates over each logger,
508
+ * and checks to see if it should forward the logMessage to the logger.
509
+ * This check is done using the level parameter passed to this method.
510
+ *
511
+ * For example:
512
+ *
513
+ * `[DDLog addLogger:consoleLogger withLogLevel:DDLogLevelVerbose];`
514
+ * `[DDLog addLogger:fileLogger withLogLevel:DDLogLevelWarning];`
515
+ *
516
+ * `DDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
517
+ * `DDLogInfo(@"hi");` => gets forwarded to consoleLogger only
518
+ *
519
+ * It is important to remember that Lumberjack uses a BITMASK.
520
+ * Many developers & third party frameworks may define extra log levels & flags.
521
+ * For example:
522
+ *
523
+ * `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
524
+ *
525
+ * So if you specify `DDLogLevelVerbose` to this method, you won't see the framework's trace messages.
526
+ *
527
+ * `(SOME_FRAMEWORK_LOG_FLAG_TRACE & DDLogLevelVerbose) => (01000000 & 00011111) => NO`
528
+ *
529
+ * Consider passing `DDLogLevelAll` to this method, which has all bits set.
530
+ * You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
531
+ * except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
532
+ *
533
+ * `((DDLogLevelAll ^ DDLogLevelVerbose) | DDLogLevelInfo)`
534
+ **/
535
+ - (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
536
+
537
+ /**
538
+ * Remove the logger from the system
539
+ */
540
+ + (void)removeLogger:(id <DDLogger>)logger;
541
+
542
+ /**
543
+ * Remove the logger from the system
544
+ */
545
+ - (void)removeLogger:(id <DDLogger>)logger;
546
+
547
+ /**
548
+ * Remove all the current loggers
549
+ */
550
+ + (void)removeAllLoggers;
551
+
552
+ /**
553
+ * Remove all the current loggers
554
+ */
555
+ - (void)removeAllLoggers;
556
+
557
+ /**
558
+ * Return all the current loggers
559
+ */
560
+ + (NSArray *)allLoggers;
561
+
562
+ /**
563
+ * Return all the current loggers
564
+ */
565
+ - (NSArray *)allLoggers;
566
+
567
+ /**
568
+ * Registered Dynamic Logging
569
+ *
570
+ * These methods allow you to obtain a list of classes that are using registered dynamic logging,
571
+ * and also provides methods to get and set their log level during run time.
572
+ **/
573
+
574
+ /**
575
+ * Returns an array with the classes that are using registered dynamic logging
576
+ */
577
+ + (NSArray *)registeredClasses;
578
+
579
+ /**
580
+ * Returns an array with the classes names that are using registered dynamic logging
581
+ */
582
+ + (NSArray *)registeredClassNames;
583
+
584
+ /**
585
+ * Returns the current log level for a certain class
586
+ *
587
+ * @param aClass `Class` param
588
+ */
589
+ + (DDLogLevel)levelForClass:(Class)aClass;
590
+
591
+ /**
592
+ * Returns the current log level for a certain class
593
+ *
594
+ * @param aClassName string param
595
+ */
596
+ + (DDLogLevel)levelForClassWithName:(NSString *)aClassName;
597
+
598
+ /**
599
+ * Set the log level for a certain class
600
+ *
601
+ * @param level the new level
602
+ * @param aClass `Class` param
603
+ */
604
+ + (void)setLevel:(DDLogLevel)level forClass:(Class)aClass;
605
+
606
+ /**
607
+ * Set the log level for a certain class
608
+ *
609
+ * @param level the new level
610
+ * @param aClassName string param
611
+ */
612
+ + (void)setLevel:(DDLogLevel)level forClassWithName:(NSString *)aClassName;
613
+
614
+ @end
615
+
616
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
617
+ #pragma mark -
618
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
619
+
620
+ /**
621
+ * This protocol describes a basic logger behavior.
622
+ * Basically, it can log messages, store a logFormatter plus a bunch of optional behaviors.
623
+ * (i.e. flush, get its loggerQueue, get its name, ...
624
+ */
625
+ @protocol DDLogger <NSObject>
626
+
627
+ /**
628
+ * The log message method
629
+ *
630
+ * @param logMessage the message (model)
631
+ */
632
+ - (void)logMessage:(DDLogMessage *)logMessage;
633
+
634
+ /**
635
+ * Formatters may optionally be added to any logger.
636
+ *
637
+ * If no formatter is set, the logger simply logs the message as it is given in logMessage,
638
+ * or it may use its own built in formatting style.
639
+ **/
640
+ @property (nonatomic, strong) id <DDLogFormatter> logFormatter;
641
+
642
+ @optional
643
+
644
+ /**
645
+ * Since logging is asynchronous, adding and removing loggers is also asynchronous.
646
+ * In other words, the loggers are added and removed at appropriate times with regards to log messages.
647
+ *
648
+ * - Loggers will not receive log messages that were executed prior to when they were added.
649
+ * - Loggers will not receive log messages that were executed after they were removed.
650
+ *
651
+ * These methods are executed in the logging thread/queue.
652
+ * This is the same thread/queue that will execute every logMessage: invocation.
653
+ * Loggers may use these methods for thread synchronization or other setup/teardown tasks.
654
+ **/
655
+ - (void)didAddLogger;
656
+
657
+ /**
658
+ * See the above description for `didAddLoger`
659
+ */
660
+ - (void)willRemoveLogger;
661
+
662
+ /**
663
+ * Some loggers may buffer IO for optimization purposes.
664
+ * For example, a database logger may only save occasionaly as the disk IO is slow.
665
+ * In such loggers, this method should be implemented to flush any pending IO.
666
+ *
667
+ * This allows invocations of DDLog's flushLog method to be propogated to loggers that need it.
668
+ *
669
+ * Note that DDLog's flushLog method is invoked automatically when the application quits,
670
+ * and it may be also invoked manually by the developer prior to application crashes, or other such reasons.
671
+ **/
672
+ - (void)flush;
673
+
674
+ /**
675
+ * Each logger is executed concurrently with respect to the other loggers.
676
+ * Thus, a dedicated dispatch queue is used for each logger.
677
+ * Logger implementations may optionally choose to provide their own dispatch queue.
678
+ **/
679
+ @property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE, readonly) dispatch_queue_t loggerQueue;
680
+
681
+ /**
682
+ * If the logger implementation does not choose to provide its own queue,
683
+ * one will automatically be created for it.
684
+ * The created queue will receive its name from this method.
685
+ * This may be helpful for debugging or profiling reasons.
686
+ **/
687
+ @property (nonatomic, readonly) NSString *loggerName;
688
+
689
+ @end
690
+
691
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
692
+ #pragma mark -
693
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
694
+
695
+ /**
696
+ * This protocol describes the behavior of a log formatter
697
+ */
698
+ @protocol DDLogFormatter <NSObject>
699
+ @required
700
+
701
+ /**
702
+ * Formatters may optionally be added to any logger.
703
+ * This allows for increased flexibility in the logging environment.
704
+ * For example, log messages for log files may be formatted differently than log messages for the console.
705
+ *
706
+ * For more information about formatters, see the "Custom Formatters" page:
707
+ * Documentation/CustomFormatters.md
708
+ *
709
+ * The formatter may also optionally filter the log message by returning nil,
710
+ * in which case the logger will not log the message.
711
+ **/
712
+ - (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
713
+
714
+ @optional
715
+
716
+ /**
717
+ * A single formatter instance can be added to multiple loggers.
718
+ * These methods provides hooks to notify the formatter of when it's added/removed.
719
+ *
720
+ * This is primarily for thread-safety.
721
+ * If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
722
+ * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
723
+ * it could possibly use these hooks to switch to thread-safe versions of the code.
724
+ **/
725
+ - (void)didAddToLogger:(id <DDLogger>)logger;
726
+
727
+ /**
728
+ * See the above description for `didAddToLogger:`
729
+ */
730
+ - (void)willRemoveFromLogger:(id <DDLogger>)logger;
731
+
732
+ @end
733
+
734
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
735
+ #pragma mark -
736
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
737
+
738
+ /**
739
+ * This protocol describes a dynamic logging component
740
+ */
741
+ @protocol DDRegisteredDynamicLogging
742
+
743
+ /**
744
+ * Implement these methods to allow a file's log level to be managed from a central location.
745
+ *
746
+ * This is useful if you'd like to be able to change log levels for various parts
747
+ * of your code from within the running application.
748
+ *
749
+ * Imagine pulling up the settings for your application,
750
+ * and being able to configure the logging level on a per file basis.
751
+ *
752
+ * The implementation can be very straight-forward:
753
+ *
754
+ * ```
755
+ * + (int)ddLogLevel
756
+ * {
757
+ * return ddLogLevel;
758
+ * }
759
+ *
760
+ * + (void)ddSetLogLevel:(DDLogLevel)level
761
+ * {
762
+ * ddLogLevel = level;
763
+ * }
764
+ * ```
765
+ **/
766
+ + (DDLogLevel)ddLogLevel;
767
+
768
+ /**
769
+ * See the above description for `ddLogLevel`
770
+ */
771
+ + (void)ddSetLogLevel:(DDLogLevel)level;
772
+
773
+ @end
774
+
775
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
776
+ #pragma mark -
777
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
778
+
779
+ #ifndef NS_DESIGNATED_INITIALIZER
780
+ #define NS_DESIGNATED_INITIALIZER
781
+ #endif
782
+
783
+ /**
784
+ * Log message options, allow copying certain log elements
785
+ */
786
+ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
787
+ /**
788
+ * Use this to use a copy of the file path
789
+ */
790
+ DDLogMessageCopyFile = 1 << 0,
791
+ /**
792
+ * Use this to use a copy of the function name
793
+ */
794
+ DDLogMessageCopyFunction = 1 << 1
795
+ };
796
+
797
+ /**
798
+ * The `DDLogMessage` class encapsulates information about the log message.
799
+ * If you write custom loggers or formatters, you will be dealing with objects of this class.
800
+ **/
801
+ @interface DDLogMessage : NSObject <NSCopying>
802
+ {
803
+ // Direct accessors to be used only for performance
804
+ @public
805
+ NSString *_message;
806
+ DDLogLevel _level;
807
+ DDLogFlag _flag;
808
+ NSInteger _context;
809
+ NSString *_file;
810
+ NSString *_fileName;
811
+ NSString *_function;
812
+ NSUInteger _line;
813
+ id _tag;
814
+ DDLogMessageOptions _options;
815
+ NSDate *_timestamp;
816
+ NSString *_threadID;
817
+ NSString *_threadName;
818
+ NSString *_queueLabel;
819
+ }
820
+
821
+ /**
822
+ * Default `init` is not available
823
+ */
824
+ - (instancetype)init NS_UNAVAILABLE;
825
+
826
+ /**
827
+ * Standard init method for a log message object.
828
+ * Used by the logging primitives. (And the macros use the logging primitives.)
829
+ *
830
+ * If you find need to manually create logMessage objects, there is one thing you should be aware of:
831
+ *
832
+ * If no flags are passed, the method expects the file and function parameters to be string literals.
833
+ * That is, it expects the given strings to exist for the duration of the object's lifetime,
834
+ * and it expects the given strings to be immutable.
835
+ * In other words, it does not copy these strings, it simply points to them.
836
+ * This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters,
837
+ * so it makes sense to optimize and skip the unnecessary allocations.
838
+ * However, if you need them to be copied you may use the options parameter to specify this.
839
+ *
840
+ * @param message the message
841
+ * @param level the log level
842
+ * @param flag the log flag
843
+ * @param context the context (if any is defined)
844
+ * @param file the current file
845
+ * @param function the current function
846
+ * @param line the current code line
847
+ * @param tag potential tag
848
+ * @param options a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
849
+ * @param timestamp the log timestamp
850
+ *
851
+ * @return a new instance of a log message model object
852
+ */
853
+ - (instancetype)initWithMessage:(NSString *)message
854
+ level:(DDLogLevel)level
855
+ flag:(DDLogFlag)flag
856
+ context:(NSInteger)context
857
+ file:(NSString *)file
858
+ function:(NSString *)function
859
+ line:(NSUInteger)line
860
+ tag:(id)tag
861
+ options:(DDLogMessageOptions)options
862
+ timestamp:(NSDate *)timestamp NS_DESIGNATED_INITIALIZER;
863
+
864
+ /**
865
+ * Read-only properties
866
+ **/
867
+
868
+ /**
869
+ * The log message
870
+ */
871
+ @property (readonly, nonatomic) NSString *message;
872
+ @property (readonly, nonatomic) DDLogLevel level;
873
+ @property (readonly, nonatomic) DDLogFlag flag;
874
+ @property (readonly, nonatomic) NSInteger context;
875
+ @property (readonly, nonatomic) NSString *file;
876
+ @property (readonly, nonatomic) NSString *fileName;
877
+ @property (readonly, nonatomic) NSString *function;
878
+ @property (readonly, nonatomic) NSUInteger line;
879
+ @property (readonly, nonatomic) id tag;
880
+ @property (readonly, nonatomic) DDLogMessageOptions options;
881
+ @property (readonly, nonatomic) NSDate *timestamp;
882
+ @property (readonly, nonatomic) NSString *threadID; // ID as it appears in NSLog calculated from the machThreadID
883
+ @property (readonly, nonatomic) NSString *threadName;
884
+ @property (readonly, nonatomic) NSString *queueLabel;
885
+
886
+ @end
887
+
888
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
889
+ #pragma mark -
890
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
891
+
892
+ /**
893
+ * The `DDLogger` protocol specifies that an optional formatter can be added to a logger.
894
+ * Most (but not all) loggers will want to support formatters.
895
+ *
896
+ * However, writting getters and setters in a thread safe manner,
897
+ * while still maintaining maximum speed for the logging process, is a difficult task.
898
+ *
899
+ * To do it right, the implementation of the getter/setter has strict requiremenets:
900
+ * - Must NOT require the `logMessage:` method to acquire a lock.
901
+ * - Must NOT require the `logMessage:` method to access an atomic property (also a lock of sorts).
902
+ *
903
+ * To simplify things, an abstract logger is provided that implements the getter and setter.
904
+ *
905
+ * Logger implementations may simply extend this class,
906
+ * and they can ACCESS THE FORMATTER VARIABLE DIRECTLY from within their `logMessage:` method!
907
+ **/
908
+ @interface DDAbstractLogger : NSObject <DDLogger>
909
+ {
910
+ // Direct accessors to be used only for performance
911
+ @public
912
+ id <DDLogFormatter> _logFormatter;
913
+ dispatch_queue_t _loggerQueue;
914
+ }
915
+
916
+ @property (nonatomic, strong) id <DDLogFormatter> logFormatter;
917
+ @property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE) dispatch_queue_t loggerQueue;
918
+
919
+ // For thread-safety assertions
920
+
921
+ /**
922
+ * Return YES if the current logger uses a global queue for logging
923
+ */
924
+ @property (nonatomic, readonly, getter=isOnGlobalLoggingQueue) BOOL onGlobalLoggingQueue;
925
+
926
+ /**
927
+ * Return YES if the current logger uses the internal designated queue for logging
928
+ */
929
+ @property (nonatomic, readonly, getter=isOnInternalLoggerQueue) BOOL onInternalLoggerQueue;
930
+
931
+ @end
932
+
933
+ // Software License Agreement (BSD License)
934
+ //
935
+ // Copyright (c) 2010-2016, Deusty, LLC
936
+ // All rights reserved.
937
+ //
938
+ // Redistribution and use of this software in source and binary forms,
939
+ // with or without modification, are permitted provided that the following conditions are met:
940
+ //
941
+ // * Redistributions of source code must retain the above copyright notice,
942
+ // this list of conditions and the following disclaimer.
943
+ //
944
+ // * Neither the name of Deusty nor the names of its contributors may be used
945
+ // to endorse or promote products derived from this software without specific
946
+ // prior written permission of Deusty, LLC.
947
+
948
+ // Disable legacy macros
949
+ #ifndef DD_LEGACY_MACROS
950
+ #define DD_LEGACY_MACROS 0
951
+ #endif
952
+
953
+ /**
954
+ * The constant/variable/method responsible for controlling the current log level.
955
+ **/
956
+ #ifndef LOG_LEVEL_DEF
957
+ #define LOG_LEVEL_DEF ddLogLevel
958
+ #endif
959
+
960
+ /**
961
+ * Whether async should be used by log messages, excluding error messages that are always sent sync.
962
+ **/
963
+ #ifndef LOG_ASYNC_ENABLED
964
+ #define LOG_ASYNC_ENABLED YES
965
+ #endif
966
+
967
+ /**
968
+ * These are the two macros that all other macros below compile into.
969
+ * These big multiline macros makes all the other macros easier to read.
970
+ **/
971
+ #define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
972
+ [DDLog log : isAsynchronous \
973
+ level : lvl \
974
+ flag : flg \
975
+ context : ctx \
976
+ file : __FILE__ \
977
+ function : fnct \
978
+ line : __LINE__ \
979
+ tag : atag \
980
+ format : (frmt), ## __VA_ARGS__]
981
+
982
+ #define LOG_MACRO_TO_DDLOG(ddlog, isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
983
+ [ddlog log : isAsynchronous \
984
+ level : lvl \
985
+ flag : flg \
986
+ context : ctx \
987
+ file : __FILE__ \
988
+ function : fnct \
989
+ line : __LINE__ \
990
+ tag : atag \
991
+ format : (frmt), ## __VA_ARGS__]
992
+
993
+ /**
994
+ * Define version of the macro that only execute if the log level is above the threshold.
995
+ * The compiled versions essentially look like this:
996
+ *
997
+ * if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
998
+ *
999
+ * When LOG_LEVEL_DEF is defined as ddLogLevel.
1000
+ *
1001
+ * As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
1002
+ * This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
1003
+ *
1004
+ * Note that when compiler optimizations are enabled (as they are for your release builds),
1005
+ * the log messages above your logging threshold will automatically be compiled out.
1006
+ *
1007
+ * (If the compiler sees LOG_LEVEL_DEF/ddLogLevel declared as a constant, the compiler simply checks to see
1008
+ * if the 'if' statement would execute, and if not it strips it from the binary.)
1009
+ *
1010
+ * We also define shorthand versions for asynchronous and synchronous logging.
1011
+ **/
1012
+ #define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
1013
+ do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
1014
+
1015
+ #define LOG_MAYBE_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ...) \
1016
+ do { if(lvl & flg) LOG_MACRO_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
1017
+
1018
+ /**
1019
+ * Ready to use log macros with no context or tag.
1020
+ **/
1021
+ #define DDLogError(frmt, ...) LOG_MAYBE(NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1022
+ #define DDLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1023
+ #define DDLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1024
+ #define DDLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1025
+ #define DDLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1026
+
1027
+ #define DDLogErrorToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1028
+ #define DDLogWarnToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1029
+ #define DDLogInfoToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1030
+ #define DDLogDebugToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1031
+ #define DDLogVerboseToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
1032
+ // Software License Agreement (BSD License)
1033
+ //
1034
+ // Copyright (c) 2010-2016, Deusty, LLC
1035
+ // All rights reserved.
1036
+ //
1037
+ // Redistribution and use of this software in source and binary forms,
1038
+ // with or without modification, are permitted provided that the following conditions are met:
1039
+ //
1040
+ // * Redistributions of source code must retain the above copyright notice,
1041
+ // this list of conditions and the following disclaimer.
1042
+ //
1043
+ // * Neither the name of Deusty nor the names of its contributors may be used
1044
+ // to endorse or promote products derived from this software without specific
1045
+ // prior written permission of Deusty, LLC.
1046
+
1047
+ /**
1048
+ * NSAsset replacement that will output a log message even when assertions are disabled.
1049
+ **/
1050
+ #define DDAssert(condition, frmt, ...) \
1051
+ if (!(condition)) { \
1052
+ NSString *description = [NSString stringWithFormat:frmt, ## __VA_ARGS__]; \
1053
+ DDLogError(@"%@", description); \
1054
+ NSAssert(NO, description); \
1055
+ }
1056
+ #define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition)
1057
+
1058
+ // Software License Agreement (BSD License)
1059
+ //
1060
+ // Copyright (c) 2010-2016, Deusty, LLC
1061
+ // All rights reserved.
1062
+ //
1063
+ // Redistribution and use of this software in source and binary forms,
1064
+ // with or without modification, are permitted provided that the following conditions are met:
1065
+ //
1066
+ // * Redistributions of source code must retain the above copyright notice,
1067
+ // this list of conditions and the following disclaimer.
1068
+ //
1069
+ // * Neither the name of Deusty nor the names of its contributors may be used
1070
+ // to endorse or promote products derived from this software without specific
1071
+ // prior written permission of Deusty, LLC.
1072
+
1073
+
1074
+ @protocol DDLogger;
1075
+
1076
+ /**
1077
+ * This class provides the ability to capture the ASL (Apple System Logs)
1078
+ */
1079
+ @interface DDASLLogCapture : NSObject
1080
+
1081
+ /**
1082
+ * Start capturing logs
1083
+ */
1084
+ + (void)start;
1085
+
1086
+ /**
1087
+ * Stop capturing logs
1088
+ */
1089
+ + (void)stop;
1090
+
1091
+ /**
1092
+ * Returns the current capture level.
1093
+ * @note Default log level: DDLogLevelVerbose (i.e. capture all ASL messages).
1094
+ */
1095
+ + (DDLogLevel)captureLevel;
1096
+
1097
+ /**
1098
+ * Set the capture level
1099
+ *
1100
+ * @param level new level
1101
+ */
1102
+ + (void)setCaptureLevel:(DDLogLevel)level;
1103
+
1104
+ @end
1105
+ // Software License Agreement (BSD License)
1106
+ //
1107
+ // Copyright (c) 2010-2016, Deusty, LLC
1108
+ // All rights reserved.
1109
+ //
1110
+ // Redistribution and use of this software in source and binary forms,
1111
+ // with or without modification, are permitted provided that the following conditions are met:
1112
+ //
1113
+ // * Redistributions of source code must retain the above copyright notice,
1114
+ // this list of conditions and the following disclaimer.
1115
+ //
1116
+ // * Neither the name of Deusty nor the names of its contributors may be used
1117
+ // to endorse or promote products derived from this software without specific
1118
+ // prior written permission of Deusty, LLC.
1119
+
1120
+ // Disable legacy macros
1121
+ #ifndef DD_LEGACY_MACROS
1122
+ #define DD_LEGACY_MACROS 0
1123
+ #endif
1124
+
1125
+ #define LOG_CONTEXT_ALL INT_MAX
1126
+
1127
+ #pragma clang diagnostic push
1128
+ #pragma clang diagnostic ignored "-Wunused-function"
1129
+ #if TARGET_OS_IPHONE
1130
+ // iOS
1131
+ #import <UIKit/UIColor.h>
1132
+ typedef UIColor DDColor;
1133
+ static inline DDColor* DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
1134
+ #elif defined(DD_CLI) || !__has_include(<AppKit/NSColor.h>)
1135
+ // OS X CLI
1136
+ #import "CLIColor.h"
1137
+ typedef CLIColor DDColor;
1138
+ static inline DDColor* DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
1139
+ #else
1140
+ // OS X with AppKit
1141
+ #import <AppKit/NSColor.h>
1142
+ typedef NSColor DDColor;
1143
+ static inline DDColor* DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
1144
+ #endif
1145
+ #pragma clang diagnostic pop
1146
+
1147
+
1148
+ /**
1149
+ * This class provides a logger for Terminal output or Xcode console output,
1150
+ * depending on where you are running your code.
1151
+ *
1152
+ * As described in the "Getting Started" page,
1153
+ * the traditional NSLog() function directs it's output to two places:
1154
+ *
1155
+ * - Apple System Log (so it shows up in Console.app)
1156
+ * - StdErr (if stderr is a TTY, so log statements show up in Xcode console)
1157
+ *
1158
+ * To duplicate NSLog() functionality you can simply add this logger and an asl logger.
1159
+ * However, if you instead choose to use file logging (for faster performance),
1160
+ * you may choose to use only a file logger and a tty logger.
1161
+ **/
1162
+ @interface DDTTYLogger : DDAbstractLogger <DDLogger>
1163
+
1164
+ /**
1165
+ * Singleton method
1166
+ */
1167
+ + (instancetype)sharedInstance;
1168
+
1169
+ /* Inherited from the DDLogger protocol:
1170
+ *
1171
+ * Formatters may optionally be added to any logger.
1172
+ *
1173
+ * If no formatter is set, the logger simply logs the message as it is given in logMessage,
1174
+ * or it may use its own built in formatting style.
1175
+ *
1176
+ * More information about formatters can be found here:
1177
+ * Documentation/CustomFormatters.md
1178
+ *
1179
+ * The actual implementation of these methods is inherited from DDAbstractLogger.
1180
+
1181
+ - (id <DDLogFormatter>)logFormatter;
1182
+ - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
1183
+
1184
+ */
1185
+
1186
+ /**
1187
+ * Want to use different colors for different log levels?
1188
+ * Enable this property.
1189
+ *
1190
+ * If you run the application via the Terminal (not Xcode),
1191
+ * the logger will map colors to xterm-256color or xterm-color (if available).
1192
+ *
1193
+ * Xcode does NOT natively support colors in the Xcode debugging console.
1194
+ * You'll need to install the XcodeColors plugin to see colors in the Xcode console.
1195
+ * https://github.com/robbiehanson/XcodeColors
1196
+ *
1197
+ * The default value is NO.
1198
+ **/
1199
+ @property (readwrite, assign) BOOL colorsEnabled;
1200
+
1201
+ /**
1202
+ * When using a custom formatter you can set the `logMessage` method not to append
1203
+ * `\n` character after each output. This allows for some greater flexibility with
1204
+ * custom formatters. Default value is YES.
1205
+ **/
1206
+ @property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
1207
+
1208
+ /**
1209
+ * The default color set (foregroundColor, backgroundColor) is:
1210
+ *
1211
+ * - DDLogFlagError = (red, nil)
1212
+ * - DDLogFlagWarning = (orange, nil)
1213
+ *
1214
+ * You can customize the colors however you see fit.
1215
+ * Please note that you are passing a flag, NOT a level.
1216
+ *
1217
+ * GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:DDLogFlagInfo]; // <- Good :)
1218
+ * BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:DDLogLevelInfo]; // <- BAD! :(
1219
+ *
1220
+ * DDLogFlagInfo = 0...00100
1221
+ * DDLogLevelInfo = 0...00111 <- Would match DDLogFlagInfo and DDLogFlagWarning and DDLogFlagError
1222
+ *
1223
+ * If you run the application within Xcode, then the XcodeColors plugin is required.
1224
+ *
1225
+ * If you run the application from a shell, then DDTTYLogger will automatically map the given color to
1226
+ * the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
1227
+ *
1228
+ * This method invokes setForegroundColor:backgroundColor:forFlag:context: and applies it to `LOG_CONTEXT_ALL`.
1229
+ **/
1230
+ - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask;
1231
+
1232
+ /**
1233
+ * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
1234
+ *
1235
+ * A logging context is often used to identify log messages coming from a 3rd party framework,
1236
+ * although logging context's can be used for many different functions.
1237
+ *
1238
+ * Use LOG_CONTEXT_ALL to set the deafult color for all contexts that have no specific color set defined.
1239
+ *
1240
+ * Logging context's are explained in further detail here:
1241
+ * Documentation/CustomContext.md
1242
+ **/
1243
+ - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask context:(NSInteger)ctxt;
1244
+
1245
+ /**
1246
+ * Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
1247
+ * For example, you could do something like this:
1248
+ *
1249
+ * static NSString *const PurpleTag = @"PurpleTag";
1250
+ *
1251
+ * #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
1252
+ *
1253
+ * And then where you configure CocoaLumberjack:
1254
+ *
1255
+ * purple = DDMakeColor((64/255.0), (0/255.0), (128/255.0));
1256
+ *
1257
+ * or any UIColor/NSColor constructor.
1258
+ *
1259
+ * Note: For CLI OS X projects that don't link with AppKit use CLIColor objects instead
1260
+ *
1261
+ * [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
1262
+ * [DDLog addLogger:[DDTTYLogger sharedInstance]];
1263
+ *
1264
+ * This would essentially give you a straight NSLog replacement that prints in purple:
1265
+ *
1266
+ * DDLogPurple(@"I'm a purple log message!");
1267
+ **/
1268
+ - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forTag:(id <NSCopying>)tag;
1269
+
1270
+ /**
1271
+ * Clearing color profiles.
1272
+ **/
1273
+ - (void)clearColorsForFlag:(DDLogFlag)mask;
1274
+ - (void)clearColorsForFlag:(DDLogFlag)mask context:(NSInteger)context;
1275
+ - (void)clearColorsForTag:(id <NSCopying>)tag;
1276
+ - (void)clearColorsForAllFlags;
1277
+ - (void)clearColorsForAllTags;
1278
+ - (void)clearAllColors;
1279
+
1280
+ @end
1281
+ // Software License Agreement (BSD License)
1282
+ //
1283
+ // Copyright (c) 2010-2016, Deusty, LLC
1284
+ // All rights reserved.
1285
+ //
1286
+ // Redistribution and use of this software in source and binary forms,
1287
+ // with or without modification, are permitted provided that the following conditions are met:
1288
+ //
1289
+ // * Redistributions of source code must retain the above copyright notice,
1290
+ // this list of conditions and the following disclaimer.
1291
+ //
1292
+ // * Neither the name of Deusty nor the names of its contributors may be used
1293
+ // to endorse or promote products derived from this software without specific
1294
+ // prior written permission of Deusty, LLC.
1295
+
1296
+ #import <Foundation/Foundation.h>
1297
+
1298
+ // Disable legacy macros
1299
+ #ifndef DD_LEGACY_MACROS
1300
+ #define DD_LEGACY_MACROS 0
1301
+ #endif
1302
+
1303
+ // Custom key set on messages sent to ASL
1304
+ extern const char* const kDDASLKeyDDLog;
1305
+
1306
+ // Value set for kDDASLKeyDDLog
1307
+ extern const char* const kDDASLDDLogValue;
1308
+
1309
+ /**
1310
+ * This class provides a logger for the Apple System Log facility.
1311
+ *
1312
+ * As described in the "Getting Started" page,
1313
+ * the traditional NSLog() function directs its output to two places:
1314
+ *
1315
+ * - Apple System Log
1316
+ * - StdErr (if stderr is a TTY) so log statements show up in Xcode console
1317
+ *
1318
+ * To duplicate NSLog() functionality you can simply add this logger and a tty logger.
1319
+ * However, if you instead choose to use file logging (for faster performance),
1320
+ * you may choose to use a file logger and a tty logger.
1321
+ **/
1322
+ @interface DDASLLogger : DDAbstractLogger <DDLogger>
1323
+
1324
+ /**
1325
+ * Singleton method
1326
+ *
1327
+ * @return the shared instance
1328
+ */
1329
+ + (instancetype)sharedInstance;
1330
+
1331
+ // Inherited from DDAbstractLogger
1332
+
1333
+ // - (id <DDLogFormatter>)logFormatter;
1334
+ // - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
1335
+
1336
+ @end
1337
+ // Software License Agreement (BSD License)
1338
+ //
1339
+ // Copyright (c) 2010-2016, Deusty, LLC
1340
+ // All rights reserved.
1341
+ //
1342
+ // Redistribution and use of this software in source and binary forms,
1343
+ // with or without modification, are permitted provided that the following conditions are met:
1344
+ //
1345
+ // * Redistributions of source code must retain the above copyright notice,
1346
+ // this list of conditions and the following disclaimer.
1347
+ //
1348
+ // * Neither the name of Deusty nor the names of its contributors may be used
1349
+ // to endorse or promote products derived from this software without specific
1350
+ // prior written permission of Deusty, LLC.
1351
+
1352
+ // Disable legacy macros
1353
+ #ifndef DD_LEGACY_MACROS
1354
+ #define DD_LEGACY_MACROS 0
1355
+ #endif
1356
+
1357
+ @class DDLogFileInfo;
1358
+
1359
+ /**
1360
+ * This class provides a logger to write log statements to a file.
1361
+ **/
1362
+
1363
+
1364
+ // Default configuration and safety/sanity values.
1365
+ //
1366
+ // maximumFileSize -> kDDDefaultLogMaxFileSize
1367
+ // rollingFrequency -> kDDDefaultLogRollingFrequency
1368
+ // maximumNumberOfLogFiles -> kDDDefaultLogMaxNumLogFiles
1369
+ // logFilesDiskQuota -> kDDDefaultLogFilesDiskQuota
1370
+ //
1371
+ // You should carefully consider the proper configuration values for your application.
1372
+
1373
+ extern unsigned long long const kDDDefaultLogMaxFileSize;
1374
+ extern NSTimeInterval const kDDDefaultLogRollingFrequency;
1375
+ extern NSUInteger const kDDDefaultLogMaxNumLogFiles;
1376
+ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
1377
+
1378
+
1379
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1380
+ #pragma mark -
1381
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1382
+
1383
+ /**
1384
+ * The LogFileManager protocol is designed to allow you to control all aspects of your log files.
1385
+ *
1386
+ * The primary purpose of this is to allow you to do something with the log files after they have been rolled.
1387
+ * Perhaps you want to compress them to save disk space.
1388
+ * Perhaps you want to upload them to an FTP server.
1389
+ * Perhaps you want to run some analytics on the file.
1390
+ *
1391
+ * A default LogFileManager is, of course, provided.
1392
+ * The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property.
1393
+ *
1394
+ * This protocol provides various methods to fetch the list of log files.
1395
+ *
1396
+ * There are two variants: sorted and unsorted.
1397
+ * If sorting is not necessary, the unsorted variant is obviously faster.
1398
+ * The sorted variant will return an array sorted by when the log files were created,
1399
+ * with the most recently created log file at index 0, and the oldest log file at the end of the array.
1400
+ *
1401
+ * You can fetch only the log file paths (full path including name), log file names (name only),
1402
+ * or an array of `DDLogFileInfo` objects.
1403
+ * The `DDLogFileInfo` class is documented below, and provides a handy wrapper that
1404
+ * gives you easy access to various file attributes such as the creation date or the file size.
1405
+ */
1406
+ @protocol DDLogFileManager <NSObject>
1407
+ @required
1408
+
1409
+ // Public properties
1410
+
1411
+ /**
1412
+ * The maximum number of archived log files to keep on disk.
1413
+ * For example, if this property is set to 3,
1414
+ * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk.
1415
+ * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted.
1416
+ *
1417
+ * You may optionally disable this option by setting it to zero.
1418
+ **/
1419
+ @property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
1420
+
1421
+ /**
1422
+ * The maximum space that logs can take. On rolling logfile all old logfiles that exceed logFilesDiskQuota will
1423
+ * be deleted.
1424
+ *
1425
+ * You may optionally disable this option by setting it to zero.
1426
+ **/
1427
+ @property (readwrite, assign, atomic) unsigned long long logFilesDiskQuota;
1428
+
1429
+ // Public methods
1430
+
1431
+ /**
1432
+ * Returns the logs directory (path)
1433
+ */
1434
+ - (NSString *)logsDirectory;
1435
+
1436
+ /**
1437
+ * Returns an array of `NSString` objects,
1438
+ * each of which is the filePath to an existing log file on disk.
1439
+ **/
1440
+ - (NSArray *)unsortedLogFilePaths;
1441
+
1442
+ /**
1443
+ * Returns an array of `NSString` objects,
1444
+ * each of which is the fileName of an existing log file on disk.
1445
+ **/
1446
+ - (NSArray *)unsortedLogFileNames;
1447
+
1448
+ /**
1449
+ * Returns an array of `DDLogFileInfo` objects,
1450
+ * each representing an existing log file on disk,
1451
+ * and containing important information about the log file such as it's modification date and size.
1452
+ **/
1453
+ - (NSArray *)unsortedLogFileInfos;
1454
+
1455
+ /**
1456
+ * Just like the `unsortedLogFilePaths` method, but sorts the array.
1457
+ * The items in the array are sorted by creation date.
1458
+ * The first item in the array will be the most recently created log file.
1459
+ **/
1460
+ - (NSArray *)sortedLogFilePaths;
1461
+
1462
+ /**
1463
+ * Just like the `unsortedLogFileNames` method, but sorts the array.
1464
+ * The items in the array are sorted by creation date.
1465
+ * The first item in the array will be the most recently created log file.
1466
+ **/
1467
+ - (NSArray *)sortedLogFileNames;
1468
+
1469
+ /**
1470
+ * Just like the `unsortedLogFileInfos` method, but sorts the array.
1471
+ * The items in the array are sorted by creation date.
1472
+ * The first item in the array will be the most recently created log file.
1473
+ **/
1474
+ - (NSArray *)sortedLogFileInfos;
1475
+
1476
+ // Private methods (only to be used by DDFileLogger)
1477
+
1478
+ /**
1479
+ * Generates a new unique log file path, and creates the corresponding log file.
1480
+ **/
1481
+ - (NSString *)createNewLogFile;
1482
+
1483
+ @optional
1484
+
1485
+ // Notifications from DDFileLogger
1486
+
1487
+ /**
1488
+ * Called when a log file was archieved
1489
+ */
1490
+ - (void)didArchiveLogFile:(NSString *)logFilePath;
1491
+
1492
+ /**
1493
+ * Called when the roll action was executed and the log was archieved
1494
+ */
1495
+ - (void)didRollAndArchiveLogFile:(NSString *)logFilePath;
1496
+
1497
+ @end
1498
+
1499
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1500
+ #pragma mark -
1501
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1502
+
1503
+ /**
1504
+ * Default log file manager.
1505
+ *
1506
+ * All log files are placed inside the logsDirectory.
1507
+ * If a specific logsDirectory isn't specified, the default directory is used.
1508
+ * On Mac, this is in `~/Library/Logs/<Application Name>`.
1509
+ * On iPhone, this is in `~/Library/Caches/Logs`.
1510
+ *
1511
+ * Log files are named `"<bundle identifier> <date> <time>.log"`
1512
+ * Example: `com.organization.myapp 2013-12-03 17-14.log`
1513
+ *
1514
+ * Archived log files are automatically deleted according to the `maximumNumberOfLogFiles` property.
1515
+ **/
1516
+ @interface DDLogFileManagerDefault : NSObject <DDLogFileManager>
1517
+
1518
+ /**
1519
+ * Default initializer
1520
+ */
1521
+ - (instancetype)init;
1522
+
1523
+ /**
1524
+ * Designated initialized, requires the logs directory
1525
+ */
1526
+ - (instancetype)initWithLogsDirectory:(NSString *)logsDirectory NS_DESIGNATED_INITIALIZER;
1527
+
1528
+ #if TARGET_OS_IPHONE
1529
+ /*
1530
+ * Calling this constructor you can override the default "automagically" chosen NSFileProtection level.
1531
+ * Useful if you are writing a command line utility / CydiaSubstrate addon for iOS that has no NSBundle
1532
+ * or like SpringBoard no BackgroundModes key in the NSBundle:
1533
+ * iPhone:~ root# cycript -p SpringBoard
1534
+ * cy# [NSBundle mainBundle]
1535
+ * #"NSBundle </System/Library/CoreServices/SpringBoard.app> (loaded)"
1536
+ * cy# [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
1537
+ * null
1538
+ * cy#
1539
+ **/
1540
+ - (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString *)fileProtectionLevel;
1541
+ #endif
1542
+
1543
+ /*
1544
+ * Methods to override.
1545
+ *
1546
+ * Log files are named `"<bundle identifier> <date> <time>.log"`
1547
+ * Example: `com.organization.myapp 2013-12-03 17-14.log`
1548
+ *
1549
+ * If you wish to change default filename, you can override following two methods.
1550
+ * - `newLogFileName` method would be called on new logfile creation.
1551
+ * - `isLogFile:` method would be called to filter logfiles from all other files in logsDirectory.
1552
+ * You have to parse given filename and return YES if it is logFile.
1553
+ *
1554
+ * **NOTE**
1555
+ * `newLogFileName` returns filename. If appropriate file already exists, number would be added
1556
+ * to filename before extension. You have to handle this case in isLogFile: method.
1557
+ *
1558
+ * Example:
1559
+ * - newLogFileName returns `"com.organization.myapp 2013-12-03.log"`,
1560
+ * file `"com.organization.myapp 2013-12-03.log"` would be created.
1561
+ * - after some time `"com.organization.myapp 2013-12-03.log"` is archived
1562
+ * - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`,
1563
+ * file `"com.organization.myapp 2013-12-03 2.log"` would be created.
1564
+ * - after some time `"com.organization.myapp 2013-12-03 1.log"` is archived
1565
+ * - newLogFileName again returns `"com.organization.myapp 2013-12-03.log"`,
1566
+ * file `"com.organization.myapp 2013-12-03 3.log"` would be created.
1567
+ **/
1568
+
1569
+ /**
1570
+ * Generates log file name with default format `"<bundle identifier> <date> <time>.log"`
1571
+ * Example: `MobileSafari 2013-12-03 17-14.log`
1572
+ *
1573
+ * You can change it by overriding `newLogFileName` and `isLogFile:` methods.
1574
+ **/
1575
+ @property (readonly, copy) NSString *newLogFileName;
1576
+
1577
+ /**
1578
+ * Default log file name is `"<bundle identifier> <date> <time>.log"`.
1579
+ * Example: `MobileSafari 2013-12-03 17-14.log`
1580
+ *
1581
+ * You can change it by overriding `newLogFileName` and `isLogFile:` methods.
1582
+ **/
1583
+ - (BOOL)isLogFile:(NSString *)fileName;
1584
+
1585
+ /* Inherited from DDLogFileManager protocol:
1586
+
1587
+ @property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
1588
+ @property (readwrite, assign, atomic) NSUInteger logFilesDiskQuota;
1589
+
1590
+ - (NSString *)logsDirectory;
1591
+
1592
+ - (NSArray *)unsortedLogFilePaths;
1593
+ - (NSArray *)unsortedLogFileNames;
1594
+ - (NSArray *)unsortedLogFileInfos;
1595
+
1596
+ - (NSArray *)sortedLogFilePaths;
1597
+ - (NSArray *)sortedLogFileNames;
1598
+ - (NSArray *)sortedLogFileInfos;
1599
+
1600
+ */
1601
+
1602
+ @end
1603
+
1604
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1605
+ #pragma mark -
1606
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1607
+
1608
+ /**
1609
+ * Most users will want file log messages to be prepended with the date and time.
1610
+ * Rather than forcing the majority of users to write their own formatter,
1611
+ * we will supply a logical default formatter.
1612
+ * Users can easily replace this formatter with their own by invoking the `setLogFormatter:` method.
1613
+ * It can also be removed by calling `setLogFormatter:`, and passing a nil parameter.
1614
+ *
1615
+ * In addition to the convenience of having a logical default formatter,
1616
+ * it will also provide a template that makes it easy for developers to copy and change.
1617
+ **/
1618
+ @interface DDLogFileFormatterDefault : NSObject <DDLogFormatter>
1619
+
1620
+ /**
1621
+ * Default initializer
1622
+ */
1623
+ - (instancetype)init;
1624
+
1625
+ /**
1626
+ * Designated initializer, requires a date formatter
1627
+ */
1628
+ - (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter NS_DESIGNATED_INITIALIZER;
1629
+
1630
+ @end
1631
+
1632
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1633
+ #pragma mark -
1634
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1635
+
1636
+ /**
1637
+ * The standard implementation for a file logger
1638
+ */
1639
+ @interface DDFileLogger : DDAbstractLogger <DDLogger>
1640
+
1641
+ /**
1642
+ * Default initializer
1643
+ */
1644
+ - (instancetype)init;
1645
+
1646
+ /**
1647
+ * Designated initializer, requires a `DDLogFileManager` instance
1648
+ */
1649
+ - (instancetype)initWithLogFileManager:(id <DDLogFileManager>)logFileManager NS_DESIGNATED_INITIALIZER;
1650
+
1651
+ /**
1652
+ * Log File Rolling:
1653
+ *
1654
+ * `maximumFileSize`:
1655
+ * The approximate maximum size (in bytes) to allow log files to grow.
1656
+ * If a log file is larger than this value after a log statement is appended,
1657
+ * then the log file is rolled.
1658
+ *
1659
+ * `rollingFrequency`
1660
+ * How often to roll the log file.
1661
+ * The frequency is given as an `NSTimeInterval`, which is a double that specifies the interval in seconds.
1662
+ * Once the log file gets to be this old, it is rolled.
1663
+ *
1664
+ * `doNotReuseLogFiles`
1665
+ * When set, will always create a new log file at application launch.
1666
+ *
1667
+ * Both the `maximumFileSize` and the `rollingFrequency` are used to manage rolling.
1668
+ * Whichever occurs first will cause the log file to be rolled.
1669
+ *
1670
+ * For example:
1671
+ * The `rollingFrequency` is 24 hours,
1672
+ * but the log file surpasses the `maximumFileSize` after only 20 hours.
1673
+ * The log file will be rolled at that 20 hour mark.
1674
+ * A new log file will be created, and the 24 hour timer will be restarted.
1675
+ *
1676
+ * You may optionally disable rolling due to filesize by setting `maximumFileSize` to zero.
1677
+ * If you do so, rolling is based solely on `rollingFrequency`.
1678
+ *
1679
+ * You may optionally disable rolling due to time by setting `rollingFrequency` to zero (or any non-positive number).
1680
+ * If you do so, rolling is based solely on `maximumFileSize`.
1681
+ *
1682
+ * If you disable both `maximumFileSize` and `rollingFrequency`, then the log file won't ever be rolled.
1683
+ * This is strongly discouraged.
1684
+ **/
1685
+ @property (readwrite, assign) unsigned long long maximumFileSize;
1686
+
1687
+ /**
1688
+ * See description for `maximumFileSize`
1689
+ */
1690
+ @property (readwrite, assign) NSTimeInterval rollingFrequency;
1691
+
1692
+ /**
1693
+ * See description for `maximumFileSize`
1694
+ */
1695
+ @property (readwrite, assign, atomic) BOOL doNotReuseLogFiles;
1696
+
1697
+ /**
1698
+ * The DDLogFileManager instance can be used to retrieve the list of log files,
1699
+ * and configure the maximum number of archived log files to keep.
1700
+ *
1701
+ * @see DDLogFileManager.maximumNumberOfLogFiles
1702
+ **/
1703
+ @property (strong, nonatomic, readonly) id <DDLogFileManager> logFileManager;
1704
+
1705
+ /**
1706
+ * When using a custom formatter you can set the `logMessage` method not to append
1707
+ * `\n` character after each output. This allows for some greater flexibility with
1708
+ * custom formatters. Default value is YES.
1709
+ **/
1710
+ @property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
1711
+
1712
+ /**
1713
+ * You can optionally force the current log file to be rolled with this method.
1714
+ * CompletionBlock will be called on main queue.
1715
+ */
1716
+ - (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock;
1717
+
1718
+ /**
1719
+ * Method is deprecated.
1720
+ * @deprecated Use `rollLogFileWithCompletionBlock:` method instead.
1721
+ */
1722
+ - (void)rollLogFile __attribute((deprecated));
1723
+
1724
+ // Inherited from DDAbstractLogger
1725
+
1726
+ // - (id <DDLogFormatter>)logFormatter;
1727
+ // - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
1728
+
1729
+ /**
1730
+ * Returns the log file that should be used.
1731
+ * If there is an existing log file that is suitable,
1732
+ * within the constraints of `maximumFileSize` and `rollingFrequency`, then it is returned.
1733
+ *
1734
+ * Otherwise a new file is created and returned.
1735
+ **/
1736
+ - (DDLogFileInfo *)currentLogFileInfo;
1737
+
1738
+ @end
1739
+
1740
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1741
+ #pragma mark -
1742
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1743
+
1744
+ /**
1745
+ * `DDLogFileInfo` is a simple class that provides access to various file attributes.
1746
+ * It provides good performance as it only fetches the information if requested,
1747
+ * and it caches the information to prevent duplicate fetches.
1748
+ *
1749
+ * It was designed to provide quick snapshots of the current state of log files,
1750
+ * and to help sort log files in an array.
1751
+ *
1752
+ * This class does not monitor the files, or update it's cached attribute values if the file changes on disk.
1753
+ * This is not what the class was designed for.
1754
+ *
1755
+ * If you absolutely must get updated values,
1756
+ * you can invoke the reset method which will clear the cache.
1757
+ **/
1758
+ @interface DDLogFileInfo : NSObject
1759
+
1760
+ @property (strong, nonatomic, readonly) NSString *filePath;
1761
+ @property (strong, nonatomic, readonly) NSString *fileName;
1762
+
1763
+ @property (strong, nonatomic, readonly) NSDictionary *fileAttributes;
1764
+
1765
+ @property (strong, nonatomic, readonly) NSDate *creationDate;
1766
+ @property (strong, nonatomic, readonly) NSDate *modificationDate;
1767
+
1768
+ @property (nonatomic, readonly) unsigned long long fileSize;
1769
+
1770
+ @property (nonatomic, readonly) NSTimeInterval age;
1771
+
1772
+ @property (nonatomic, readwrite) BOOL isArchived;
1773
+
1774
+ + (instancetype)logFileWithPath:(NSString *)filePath;
1775
+
1776
+ - (instancetype)init NS_UNAVAILABLE;
1777
+ - (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER;
1778
+
1779
+ - (void)reset;
1780
+ - (void)renameFile:(NSString *)newFileName;
1781
+
1782
+ #if TARGET_IPHONE_SIMULATOR
1783
+
1784
+ // So here's the situation.
1785
+ // Extended attributes are perfect for what we're trying to do here (marking files as archived).
1786
+ // This is exactly what extended attributes were designed for.
1787
+ //
1788
+ // But Apple screws us over on the simulator.
1789
+ // Everytime you build-and-go, they copy the application into a new folder on the hard drive,
1790
+ // and as part of the process they strip extended attributes from our log files.
1791
+ // Normally, a copy of a file preserves extended attributes.
1792
+ // So obviously Apple has gone to great lengths to piss us off.
1793
+ //
1794
+ // Thus we use a slightly different tactic for marking log files as archived in the simulator.
1795
+ // That way it "just works" and there's no confusion when testing.
1796
+ //
1797
+ // The difference in method names is indicative of the difference in functionality.
1798
+ // On the simulator we add an attribute by appending a filename extension.
1799
+ //
1800
+ // For example:
1801
+ // "mylog.txt" -> "mylog.archived.txt"
1802
+ // "mylog" -> "mylog.archived"
1803
+
1804
+ - (BOOL)hasExtensionAttributeWithName:(NSString *)attrName;
1805
+
1806
+ - (void)addExtensionAttributeWithName:(NSString *)attrName;
1807
+ - (void)removeExtensionAttributeWithName:(NSString *)attrName;
1808
+
1809
+ #else /* if TARGET_IPHONE_SIMULATOR */
1810
+
1811
+ // Normal use of extended attributes used everywhere else,
1812
+ // such as on Macs and on iPhone devices.
1813
+
1814
+ - (BOOL)hasExtendedAttributeWithName:(NSString *)attrName;
1815
+
1816
+ - (void)addExtendedAttributeWithName:(NSString *)attrName;
1817
+ - (void)removeExtendedAttributeWithName:(NSString *)attrName;
1818
+
1819
+ #endif /* if TARGET_IPHONE_SIMULATOR */
1820
+
1821
+ - (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another;
1822
+ - (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another;
1823
+
1824
+ @end
1825
+ // Software License Agreement (BSD License)
1826
+ //
1827
+ // Copyright (c) 2010-2016, Deusty, LLC
1828
+ // All rights reserved.
1829
+ //
1830
+ // Redistribution and use of this software in source and binary forms,
1831
+ // with or without modification, are permitted provided that the following conditions are met:
1832
+ //
1833
+ // * Redistributions of source code must retain the above copyright notice,
1834
+ // this list of conditions and the following disclaimer.
1835
+ //
1836
+ // * Neither the name of Deusty nor the names of its contributors may be used
1837
+ // to endorse or promote products derived from this software without specific
1838
+ // prior written permission of Deusty, LLC.
1839
+
1840
+ // Disable legacy macros
1841
+ #ifndef DD_LEGACY_MACROS
1842
+ #define DD_LEGACY_MACROS 0
1843
+ #endif
1844
+
1845
+ /**
1846
+ * This class provides an abstract implementation of a database logger.
1847
+ *
1848
+ * That is, it provides the base implementation for a database logger to build atop of.
1849
+ * All that is needed for a concrete database logger is to extend this class
1850
+ * and override the methods in the implementation file that are prefixed with "db_".
1851
+ **/
1852
+ @interface DDAbstractDatabaseLogger : DDAbstractLogger {
1853
+
1854
+ @protected
1855
+ NSUInteger _saveThreshold;
1856
+ NSTimeInterval _saveInterval;
1857
+ NSTimeInterval _maxAge;
1858
+ NSTimeInterval _deleteInterval;
1859
+ BOOL _deleteOnEverySave;
1860
+
1861
+ BOOL _saveTimerSuspended;
1862
+ NSUInteger _unsavedCount;
1863
+ dispatch_time_t _unsavedTime;
1864
+ dispatch_source_t _saveTimer;
1865
+ dispatch_time_t _lastDeleteTime;
1866
+ dispatch_source_t _deleteTimer;
1867
+ }
1868
+
1869
+ /**
1870
+ * Specifies how often to save the data to disk.
1871
+ * Since saving is an expensive operation (disk io) it is not done after every log statement.
1872
+ * These properties allow you to configure how/when the logger saves to disk.
1873
+ *
1874
+ * A save is done when either (whichever happens first):
1875
+ *
1876
+ * - The number of unsaved log entries reaches saveThreshold
1877
+ * - The amount of time since the oldest unsaved log entry was created reaches saveInterval
1878
+ *
1879
+ * You can optionally disable the saveThreshold by setting it to zero.
1880
+ * If you disable the saveThreshold you are entirely dependent on the saveInterval.
1881
+ *
1882
+ * You can optionally disable the saveInterval by setting it to zero (or a negative value).
1883
+ * If you disable the saveInterval you are entirely dependent on the saveThreshold.
1884
+ *
1885
+ * It's not wise to disable both saveThreshold and saveInterval.
1886
+ *
1887
+ * The default saveThreshold is 500.
1888
+ * The default saveInterval is 60 seconds.
1889
+ **/
1890
+ @property (assign, readwrite) NSUInteger saveThreshold;
1891
+
1892
+ /**
1893
+ * See the description for the `saveThreshold` property
1894
+ */
1895
+ @property (assign, readwrite) NSTimeInterval saveInterval;
1896
+
1897
+ /**
1898
+ * It is likely you don't want the log entries to persist forever.
1899
+ * Doing so would allow the database to grow infinitely large over time.
1900
+ *
1901
+ * The maxAge property provides a way to specify how old a log statement can get
1902
+ * before it should get deleted from the database.
1903
+ *
1904
+ * The deleteInterval specifies how often to sweep for old log entries.
1905
+ * Since deleting is an expensive operation (disk io) is is done on a fixed interval.
1906
+ *
1907
+ * An alternative to the deleteInterval is the deleteOnEverySave option.
1908
+ * This specifies that old log entries should be deleted during every save operation.
1909
+ *
1910
+ * You can optionally disable the maxAge by setting it to zero (or a negative value).
1911
+ * If you disable the maxAge then old log statements are not deleted.
1912
+ *
1913
+ * You can optionally disable the deleteInterval by setting it to zero (or a negative value).
1914
+ *
1915
+ * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted.
1916
+ *
1917
+ * It's not wise to enable both deleteInterval and deleteOnEverySave.
1918
+ *
1919
+ * The default maxAge is 7 days.
1920
+ * The default deleteInterval is 5 minutes.
1921
+ * The default deleteOnEverySave is NO.
1922
+ **/
1923
+ @property (assign, readwrite) NSTimeInterval maxAge;
1924
+
1925
+ /**
1926
+ * See the description for the `maxAge` property
1927
+ */
1928
+ @property (assign, readwrite) NSTimeInterval deleteInterval;
1929
+
1930
+ /**
1931
+ * See the description for the `maxAge` property
1932
+ */
1933
+ @property (assign, readwrite) BOOL deleteOnEverySave;
1934
+
1935
+ /**
1936
+ * Forces a save of any pending log entries (flushes log entries to disk).
1937
+ **/
1938
+ - (void)savePendingLogEntries;
1939
+
1940
+ /**
1941
+ * Removes any log entries that are older than maxAge.
1942
+ **/
1943
+ - (void)deleteOldLogEntries;
1944
+
1945
+ @end