mirror of
https://github.com/samsonjs/samhuri.net-ios.git
synced 2026-03-25 09:25:47 +00:00
cocoapods
This commit is contained in:
parent
55c65c79c5
commit
7f5df3a077
563 changed files with 89446 additions and 0 deletions
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
30089596C2F733D451A454E8 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1613DC56A86AFA7E50460A37 /* libPods.a */; };
|
||||
7B5C4BDF19F2606900667D48 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5C4BDE19F2606900667D48 /* main.m */; };
|
||||
7B5C4BE219F2606900667D48 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5C4BE119F2606900667D48 /* AppDelegate.m */; };
|
||||
7B5C4BE519F2606900667D48 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5C4BE419F2606900667D48 /* MasterViewController.m */; };
|
||||
|
|
@ -15,6 +16,7 @@
|
|||
7B5C4BED19F2606900667D48 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7B5C4BEC19F2606900667D48 /* Images.xcassets */; };
|
||||
7B5C4BF019F2606900667D48 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7B5C4BEE19F2606900667D48 /* LaunchScreen.xib */; };
|
||||
7B5C4BFC19F2606900667D48 /* BlogTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5C4BFB19F2606900667D48 /* BlogTests.m */; };
|
||||
B8B8958B2AA40812EFE04FEF /* libPods-BlogTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C36BC848680D4F831E4DE23 /* libPods-BlogTests.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
|
@ -28,6 +30,7 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1613DC56A86AFA7E50460A37 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7B5C4BD919F2606900667D48 /* Blog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Blog.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7B5C4BDD19F2606900667D48 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
7B5C4BDE19F2606900667D48 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
|
|
@ -43,6 +46,11 @@
|
|||
7B5C4BF519F2606900667D48 /* BlogTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BlogTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
7B5C4BFA19F2606900667D48 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
7B5C4BFB19F2606900667D48 /* BlogTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BlogTests.m; sourceTree = "<group>"; };
|
||||
9C36BC848680D4F831E4DE23 /* libPods-BlogTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-BlogTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A2EB178BEF4356711B2710AE /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
|
||||
AB1234AC662F1A1B7BD87AB0 /* Pods-BlogTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BlogTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-BlogTests/Pods-BlogTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
D1F0F9D6D1DB6188AF81A066 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
DAA4009DDF4B3F5BEEF9CC4C /* Pods-BlogTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BlogTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-BlogTests/Pods-BlogTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -50,6 +58,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
30089596C2F733D451A454E8 /* libPods.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -57,18 +66,32 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B8B8958B2AA40812EFE04FEF /* libPods-BlogTests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
1A8ACE7C3A5634C63D5770EA /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1F0F9D6D1DB6188AF81A066 /* Pods.debug.xcconfig */,
|
||||
A2EB178BEF4356711B2710AE /* Pods.release.xcconfig */,
|
||||
DAA4009DDF4B3F5BEEF9CC4C /* Pods-BlogTests.debug.xcconfig */,
|
||||
AB1234AC662F1A1B7BD87AB0 /* Pods-BlogTests.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7B5C4BD019F2606900667D48 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7B5C4BDB19F2606900667D48 /* Blog */,
|
||||
7B5C4BF819F2606900667D48 /* BlogTests */,
|
||||
7B5C4BDA19F2606900667D48 /* Products */,
|
||||
1A8ACE7C3A5634C63D5770EA /* Pods */,
|
||||
F9CC479BA9A49F1EDD27B0AB /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
|
@ -124,6 +147,15 @@
|
|||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F9CC479BA9A49F1EDD27B0AB /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1613DC56A86AFA7E50460A37 /* libPods.a */,
|
||||
9C36BC848680D4F831E4DE23 /* libPods-BlogTests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
|
@ -131,9 +163,11 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 7B5C4BFF19F2606900667D48 /* Build configuration list for PBXNativeTarget "Blog" */;
|
||||
buildPhases = (
|
||||
8A51BD8ED157654D8B96256C /* Check Pods Manifest.lock */,
|
||||
7B5C4BD519F2606900667D48 /* Sources */,
|
||||
7B5C4BD619F2606900667D48 /* Frameworks */,
|
||||
7B5C4BD719F2606900667D48 /* Resources */,
|
||||
F9882194979CEEC00C6695C2 /* Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -148,9 +182,11 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 7B5C4C0219F2606900667D48 /* Build configuration list for PBXNativeTarget "BlogTests" */;
|
||||
buildPhases = (
|
||||
5869AA845D966F9B4CDB0BB9 /* Check Pods Manifest.lock */,
|
||||
7B5C4BF119F2606900667D48 /* Sources */,
|
||||
7B5C4BF219F2606900667D48 /* Frameworks */,
|
||||
7B5C4BF319F2606900667D48 /* Resources */,
|
||||
F6692F90CD27F7908A2BD4C6 /* Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -220,6 +256,69 @@
|
|||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
5869AA845D966F9B4CDB0BB9 /* Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
8A51BD8ED157654D8B96256C /* Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
F6692F90CD27F7908A2BD4C6 /* Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-BlogTests/Pods-BlogTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
F9882194979CEEC00C6695C2 /* Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
7B5C4BD519F2606900667D48 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
|
|
@ -350,6 +449,7 @@
|
|||
};
|
||||
7B5C4C0019F2606900667D48 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D1F0F9D6D1DB6188AF81A066 /* Pods.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
|
|
@ -361,6 +461,7 @@
|
|||
};
|
||||
7B5C4C0119F2606900667D48 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = A2EB178BEF4356711B2710AE /* Pods.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
|
|
@ -372,6 +473,7 @@
|
|||
};
|
||||
7B5C4C0319F2606900667D48 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = DAA4009DDF4B3F5BEEF9CC4C /* Pods-BlogTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
|
|
@ -391,6 +493,7 @@
|
|||
};
|
||||
7B5C4C0419F2606900667D48 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = AB1234AC662F1A1B7BD87AB0 /* Pods-BlogTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
|
|
@ -423,6 +526,7 @@
|
|||
7B5C4C0119F2606900667D48 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
7B5C4C0219F2606900667D48 /* Build configuration list for PBXNativeTarget "BlogTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
|
|
@ -431,6 +535,7 @@
|
|||
7B5C4C0419F2606900667D48 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
|
|
|||
10
Blog.xcworkspace/contents.xcworkspacedata
generated
Normal file
10
Blog.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Blog.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
41
Blog.xcworkspace/xcshareddata/Blog.xccheckout
Normal file
41
Blog.xcworkspace/xcshareddata/Blog.xccheckout
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>4DE41D0A-0A5B-4767-8937-4D8B9B787CB1</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>Blog</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>9FE6E9BED9551FE3A3237EE95ECA063A7B5AA7F9</key>
|
||||
<string>github.com:samsonjs/samhuri.net-ios.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>Blog.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>9FE6E9BED9551FE3A3237EE95ECA063A7B5AA7F9</key>
|
||||
<string>..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>github.com:samsonjs/samhuri.net-ios.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>111</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>9FE6E9BED9551FE3A3237EE95ECA063A7B5AA7F9</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>9FE6E9BED9551FE3A3237EE95ECA063A7B5AA7F9</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>Blog</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
16
Podfile
Normal file
16
Podfile
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '6.0'
|
||||
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
|
||||
pod 'Mantle'
|
||||
pod 'PromiseKit'
|
||||
pod 'YapDatabase'
|
||||
pod 'libextobjc'
|
||||
|
||||
# target 'Blog' do
|
||||
# end
|
||||
|
||||
target 'BlogTests' do
|
||||
pod 'OHHTTPStubs'
|
||||
end
|
||||
115
Podfile.lock
Normal file
115
Podfile.lock
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
PODS:
|
||||
- CocoaLumberjack (1.9.2):
|
||||
- CocoaLumberjack/Extensions
|
||||
- CocoaLumberjack/Core (1.9.2)
|
||||
- CocoaLumberjack/Extensions (1.9.2):
|
||||
- CocoaLumberjack/Core
|
||||
- libextobjc (0.4):
|
||||
- libextobjc/EXTADT
|
||||
- libextobjc/EXTConcreteProtocol
|
||||
- libextobjc/EXTKeyPathCoding
|
||||
- libextobjc/EXTNil
|
||||
- libextobjc/EXTSafeCategory
|
||||
- libextobjc/EXTScope
|
||||
- libextobjc/EXTSelectorChecking
|
||||
- libextobjc/EXTSynthesize
|
||||
- libextobjc/NSInvocation+EXT
|
||||
- libextobjc/NSMethodSignature+EXT
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/UmbrellaHeader
|
||||
- libextobjc/EXTADT (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/EXTConcreteProtocol (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/EXTKeyPathCoding (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/EXTNil (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/EXTSafeCategory (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/EXTScope (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/EXTSelectorChecking (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/EXTSynthesize (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/NSInvocation+EXT (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/NSMethodSignature+EXT (0.4):
|
||||
- libextobjc/RuntimeExtensions
|
||||
- libextobjc/RuntimeExtensions (0.4)
|
||||
- libextobjc/UmbrellaHeader (0.4)
|
||||
- Mantle (1.5.1):
|
||||
- Mantle/extobjc
|
||||
- Mantle/extobjc (1.5.1)
|
||||
- OHHTTPStubs (3.1.6):
|
||||
- OHHTTPStubs/Core
|
||||
- OHHTTPStubs/Core (3.1.6)
|
||||
- OMGHTTPURLRQ (2.1):
|
||||
- OMGHTTPURLRQ/FormURLEncode
|
||||
- OMGHTTPURLRQ/RQ
|
||||
- OMGHTTPURLRQ/UserAgent
|
||||
- OMGHTTPURLRQ/FormURLEncode (2.1):
|
||||
- OMGHTTPURLRQ/FormURLEncode
|
||||
- OMGHTTPURLRQ/UserAgent
|
||||
- OMGHTTPURLRQ/RQ (2.1):
|
||||
- OMGHTTPURLRQ/FormURLEncode
|
||||
- OMGHTTPURLRQ/UserAgent
|
||||
- OMGHTTPURLRQ/UserAgent (2.1):
|
||||
- OMGHTTPURLRQ/FormURLEncode
|
||||
- OMGHTTPURLRQ/UserAgent
|
||||
- PromiseKit (1.0):
|
||||
- PromiseKit/NSNotificationCenter
|
||||
- PromiseKit/NSURLConnection
|
||||
- PromiseKit/Pause
|
||||
- PromiseKit/UIActionSheet
|
||||
- PromiseKit/UIAlertView
|
||||
- PromiseKit/UIView
|
||||
- PromiseKit/UIViewController
|
||||
- PromiseKit/Until
|
||||
- PromiseKit/When
|
||||
- PromiseKit/NSNotificationCenter (1.0):
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/NSURLConnection (1.0):
|
||||
- OMGHTTPURLRQ
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/Pause (1.0):
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/Promise (1.0)
|
||||
- PromiseKit/UIActionSheet (1.0):
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/UIAlertView (1.0):
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/UIView (1.0):
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/UIViewController (1.0):
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/Until (1.0):
|
||||
- PromiseKit/Promise
|
||||
- PromiseKit/When
|
||||
- PromiseKit/When (1.0):
|
||||
- PromiseKit/Promise
|
||||
- YapDatabase (2.5.2):
|
||||
- YapDatabase/standard
|
||||
- YapDatabase/common (2.5.2):
|
||||
- CocoaLumberjack (~> 1)
|
||||
- YapDatabase/standard (2.5.2):
|
||||
- YapDatabase/common
|
||||
|
||||
DEPENDENCIES:
|
||||
- libextobjc
|
||||
- Mantle
|
||||
- OHHTTPStubs
|
||||
- PromiseKit
|
||||
- YapDatabase
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
CocoaLumberjack: 205769c032b5fef85b92472046bcc8b7e7c8a817
|
||||
libextobjc: ba42e4111f433273a886cd54f0ddaddb7f62f82f
|
||||
Mantle: d7c5ac734579ec751c58fecbf56189853056c58c
|
||||
OHHTTPStubs: 6781373b69e0a67b27239799f11764d0fbefac55
|
||||
OMGHTTPURLRQ: 16564bcee86d8dfa298b65cdf60015c3065f67df
|
||||
PromiseKit: 3a8eb40bb66c8f74ebd629f03ad8b0d5581a744c
|
||||
YapDatabase: 50f763e49374c38025e8255b4c468d26d81b1048
|
||||
|
||||
COCOAPODS: 0.34.2
|
||||
18
Pods/CocoaLumberjack/LICENSE.txt
generated
Normal file
18
Pods/CocoaLumberjack/LICENSE.txt
generated
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2010, Deusty, LLC
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Neither the name of Deusty nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of Deusty, LLC.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
23
Pods/CocoaLumberjack/Lumberjack/DDASLLogCapture.h
generated
Normal file
23
Pods/CocoaLumberjack/Lumberjack/DDASLLogCapture.h
generated
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// DDASLLogCapture.h
|
||||
// Lumberjack
|
||||
//
|
||||
// Created by Dario Ahdoot on 3/17/14.
|
||||
//
|
||||
//
|
||||
|
||||
#import "DDASLLogger.h"
|
||||
|
||||
@protocol DDLogger;
|
||||
|
||||
@interface DDASLLogCapture : NSObject
|
||||
|
||||
+ (void)start;
|
||||
+ (void)stop;
|
||||
|
||||
// Default log level: LOG_LEVEL_VERBOSE (i.e. capture all ASL messages).
|
||||
+ (int)captureLogLevel;
|
||||
+ (void)setCaptureLogLevel:(int)LOG_LEVEL_XXX;
|
||||
|
||||
@end
|
||||
|
||||
188
Pods/CocoaLumberjack/Lumberjack/DDASLLogCapture.m
generated
Normal file
188
Pods/CocoaLumberjack/Lumberjack/DDASLLogCapture.m
generated
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
//
|
||||
// DDASLLogCapture.m
|
||||
// Lumberjack
|
||||
//
|
||||
// Created by Dario Ahdoot on 3/17/14.
|
||||
//
|
||||
//
|
||||
|
||||
#import "DDASLLogCapture.h"
|
||||
#import "DDLog.h"
|
||||
|
||||
#include <asl.h>
|
||||
#include <notify.h>
|
||||
#include <notify_keys.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static BOOL _cancel = YES;
|
||||
static int _captureLogLevel = LOG_LEVEL_VERBOSE;
|
||||
|
||||
@implementation DDASLLogCapture
|
||||
|
||||
+ (void)start
|
||||
{
|
||||
// Ignore subsequent calls
|
||||
if (!_cancel)
|
||||
return;
|
||||
|
||||
_cancel = NO;
|
||||
|
||||
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
|
||||
{
|
||||
[DDASLLogCapture captureAslLogs];
|
||||
});
|
||||
}
|
||||
|
||||
+ (void)stop
|
||||
{
|
||||
_cancel = YES;
|
||||
}
|
||||
|
||||
+ (int)captureLogLevel
|
||||
{
|
||||
return _captureLogLevel;
|
||||
}
|
||||
|
||||
+ (void)setCaptureLogLevel:(int)LOG_LEVEL_XXX
|
||||
{
|
||||
_captureLogLevel = LOG_LEVEL_XXX;
|
||||
}
|
||||
|
||||
# pragma mark - Private methods
|
||||
|
||||
+ (void)configureAslQuery:(aslmsg)query
|
||||
{
|
||||
const char param[] = "7"; // ASL_LEVEL_DEBUG, which is everything. We'll rely on regular DDlog log level to filter
|
||||
asl_set_query(query, ASL_KEY_LEVEL, param, ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC);
|
||||
|
||||
#if !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
|
||||
int processId = [[NSProcessInfo processInfo] processIdentifier];
|
||||
char pid[16];
|
||||
sprintf(pid, "%d", processId);
|
||||
asl_set_query(query, ASL_KEY_PID, pid, ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_NUMERIC);
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (void)aslMessageRecieved:(aslmsg)msg
|
||||
{
|
||||
// NSString * sender = [NSString stringWithCString:asl_get(msg, ASL_KEY_SENDER) encoding:NSUTF8StringEncoding];
|
||||
NSString * message = [NSString stringWithCString:asl_get(msg, ASL_KEY_MSG) encoding:NSUTF8StringEncoding];
|
||||
NSString * level = [NSString stringWithCString:asl_get(msg, ASL_KEY_LEVEL) encoding:NSUTF8StringEncoding];
|
||||
NSString * secondsStr = [NSString stringWithCString:asl_get(msg, ASL_KEY_TIME) encoding:NSUTF8StringEncoding];
|
||||
NSString * nanoStr = [NSString stringWithCString:asl_get(msg, ASL_KEY_TIME_NSEC) encoding:NSUTF8StringEncoding];
|
||||
|
||||
NSTimeInterval seconds = [secondsStr doubleValue];
|
||||
NSTimeInterval nanoSeconds = [nanoStr doubleValue];
|
||||
NSTimeInterval totalSeconds = seconds + (nanoSeconds / 1e9);
|
||||
|
||||
NSDate * timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds];
|
||||
|
||||
int flag;
|
||||
BOOL async;
|
||||
switch([level intValue])
|
||||
{
|
||||
// By default all NSLog's with a ASL_LEVEL_WARNING level
|
||||
case ASL_LEVEL_EMERG :
|
||||
case ASL_LEVEL_ALERT :
|
||||
case ASL_LEVEL_CRIT : flag = LOG_FLAG_ERROR; async = LOG_ASYNC_ERROR; break;
|
||||
case ASL_LEVEL_ERR : flag = LOG_FLAG_WARN; async = LOG_ASYNC_WARN; break;
|
||||
case ASL_LEVEL_WARNING : flag = LOG_FLAG_INFO; async = LOG_ASYNC_INFO; break;
|
||||
case ASL_LEVEL_NOTICE : flag = LOG_FLAG_DEBUG; async = LOG_ASYNC_DEBUG; break;
|
||||
case ASL_LEVEL_INFO :
|
||||
case ASL_LEVEL_DEBUG :
|
||||
default : flag = LOG_FLAG_VERBOSE; async = LOG_ASYNC_VERBOSE; break;
|
||||
}
|
||||
|
||||
if (!(_captureLogLevel & flag))
|
||||
return;
|
||||
|
||||
DDLogMessage * logMessage = [[DDLogMessage alloc]initWithLogMsg:message
|
||||
level:_captureLogLevel
|
||||
flag:flag
|
||||
context:0
|
||||
file:"DDASLLogCapture"
|
||||
function:0
|
||||
line:0
|
||||
tag:nil
|
||||
options:0
|
||||
timestamp:timeStamp];
|
||||
|
||||
[DDLog log:async message:logMessage];
|
||||
}
|
||||
|
||||
+ (void)captureAslLogs
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
/*
|
||||
We use ASL_KEY_MSG_ID to see each message once, but there's no
|
||||
obvious way to get the "next" ID. To bootstrap the process, we'll
|
||||
search by timestamp until we've seen a message.
|
||||
*/
|
||||
|
||||
struct timeval timeval = { .tv_sec = 0 };
|
||||
gettimeofday(&timeval, NULL);
|
||||
unsigned long long startTime = timeval.tv_sec;
|
||||
__block unsigned long long lastSeenID = 0;
|
||||
|
||||
/*
|
||||
syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message)
|
||||
through the notify API when it saves messages to the ASL database.
|
||||
There is some coalescing - currently it is sent at most twice per
|
||||
second - but there is no documented guarantee about this. In any
|
||||
case, there may be multiple messages per notification.
|
||||
|
||||
Notify notifications don't carry any payload, so we need to search
|
||||
for the messages.
|
||||
*/
|
||||
int notifyToken = 0; // Can be used to unregister with notify_cancel().
|
||||
notify_register_dispatch(kNotifyASLDBUpdate, ¬ifyToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(int token)
|
||||
{
|
||||
// At least one message has been posted; build a search query.
|
||||
@autoreleasepool
|
||||
{
|
||||
aslmsg query = asl_new(ASL_TYPE_QUERY);
|
||||
char stringValue[64];
|
||||
if (lastSeenID > 0)
|
||||
{
|
||||
snprintf(stringValue, sizeof stringValue, "%llu", lastSeenID);
|
||||
asl_set_query(query, ASL_KEY_MSG_ID, stringValue, ASL_QUERY_OP_GREATER | ASL_QUERY_OP_NUMERIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(stringValue, sizeof stringValue, "%llu", startTime);
|
||||
asl_set_query(query, ASL_KEY_TIME, stringValue, ASL_QUERY_OP_GREATER_EQUAL | ASL_QUERY_OP_NUMERIC);
|
||||
}
|
||||
[DDASLLogCapture configureAslQuery:query];
|
||||
|
||||
// Iterate over new messages.
|
||||
aslmsg msg;
|
||||
aslresponse response = asl_search(NULL, query);
|
||||
#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
|
||||
while ((msg = asl_next(response)))
|
||||
#else
|
||||
while ((msg = aslresponse_next(response)))
|
||||
#endif
|
||||
{
|
||||
[DDASLLogCapture aslMessageRecieved:msg];
|
||||
|
||||
// Keep track of which messages we've seen.
|
||||
lastSeenID = atoll(asl_get(msg, ASL_KEY_MSG_ID));
|
||||
}
|
||||
#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
|
||||
asl_release(response);
|
||||
#else
|
||||
aslresponse_free(response);
|
||||
#endif
|
||||
if(_cancel)
|
||||
{
|
||||
notify_cancel(notifyToken);
|
||||
return;
|
||||
}
|
||||
free(query);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
37
Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h
generated
Executable file
37
Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h
generated
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "DDLog.h"
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides a logger for the Apple System Log facility.
|
||||
*
|
||||
* As described in the "Getting Started" page,
|
||||
* the traditional NSLog() function directs it's output to two places:
|
||||
*
|
||||
* - Apple System Log
|
||||
* - StdErr (if stderr is a TTY) so log statements show up in Xcode console
|
||||
*
|
||||
* To duplicate NSLog() functionality you can simply add this logger and a tty logger.
|
||||
* However, if you instead choose to use file logging (for faster performance),
|
||||
* you may choose to use a file logger and a tty logger.
|
||||
**/
|
||||
|
||||
@interface DDASLLogger : DDAbstractLogger <DDLogger>
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
// Inherited from DDAbstractLogger
|
||||
|
||||
// - (id <DDLogFormatter>)logFormatter;
|
||||
// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
@end
|
||||
95
Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m
generated
Executable file
95
Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m
generated
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
#import "DDASLLogger.h"
|
||||
#import <asl.h>
|
||||
#import <libkern/OSAtomic.h>
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
**/
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
static DDASLLogger *sharedInstance;
|
||||
|
||||
@implementation DDASLLogger
|
||||
{
|
||||
aslclient client;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static dispatch_once_t DDASLLoggerOnceToken;
|
||||
dispatch_once(&DDASLLoggerOnceToken, ^{
|
||||
sharedInstance = [[[self class] alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if (sharedInstance != nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ((self = [super init]))
|
||||
{
|
||||
// A default asl client is provided for the main thread,
|
||||
// but background threads need to create their own client.
|
||||
|
||||
client = asl_open(NULL, "com.apple.console", 0);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)logMessage:(DDLogMessage *)logMessage
|
||||
{
|
||||
// Skip captured log messages.
|
||||
if (strcmp(logMessage->file, "DDASLLogCapture") == 0)
|
||||
return;
|
||||
|
||||
NSString *logMsg = logMessage->logMsg;
|
||||
|
||||
if (formatter)
|
||||
{
|
||||
logMsg = [formatter formatLogMessage:logMessage];
|
||||
}
|
||||
|
||||
if (logMsg)
|
||||
{
|
||||
const char *msg = [logMsg UTF8String];
|
||||
|
||||
int aslLogLevel;
|
||||
switch (logMessage->logFlag)
|
||||
{
|
||||
// Note: By default ASL will filter anything above level 5 (Notice).
|
||||
// So our mappings shouldn't go above that level.
|
||||
case LOG_FLAG_ERROR : aslLogLevel = ASL_LEVEL_CRIT; break;
|
||||
case LOG_FLAG_WARN : aslLogLevel = ASL_LEVEL_ERR; break;
|
||||
case LOG_FLAG_INFO : aslLogLevel = ASL_LEVEL_WARNING; break; // Regular NSLog's level
|
||||
case LOG_FLAG_DEBUG :
|
||||
case LOG_FLAG_VERBOSE :
|
||||
default : aslLogLevel = ASL_LEVEL_NOTICE; break;
|
||||
}
|
||||
|
||||
aslmsg m = asl_new(ASL_TYPE_MSG);
|
||||
asl_set(m, ASL_KEY_READ_UID, "501");
|
||||
asl_log(client, m, aslLogLevel, "%s", msg);
|
||||
asl_free(m);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)loggerName
|
||||
{
|
||||
return @"cocoa.lumberjack.aslLogger";
|
||||
}
|
||||
|
||||
@end
|
||||
102
Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h
generated
Normal file
102
Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h
generated
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "DDLog.h"
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides an abstract implementation of a database logger.
|
||||
*
|
||||
* That is, it provides the base implementation for a database logger to build atop of.
|
||||
* All that is needed for a concrete database logger is to extend this class
|
||||
* and override the methods in the implementation file that are prefixed with "db_".
|
||||
**/
|
||||
|
||||
@interface DDAbstractDatabaseLogger : DDAbstractLogger {
|
||||
@protected
|
||||
NSUInteger saveThreshold;
|
||||
NSTimeInterval saveInterval;
|
||||
NSTimeInterval maxAge;
|
||||
NSTimeInterval deleteInterval;
|
||||
BOOL deleteOnEverySave;
|
||||
|
||||
BOOL saveTimerSuspended;
|
||||
NSUInteger unsavedCount;
|
||||
dispatch_time_t unsavedTime;
|
||||
dispatch_source_t saveTimer;
|
||||
dispatch_time_t lastDeleteTime;
|
||||
dispatch_source_t deleteTimer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how often to save the data to disk.
|
||||
* Since saving is an expensive operation (disk io) it is not done after every log statement.
|
||||
* These properties allow you to configure how/when the logger saves to disk.
|
||||
*
|
||||
* A save is done when either (whichever happens first):
|
||||
*
|
||||
* - The number of unsaved log entries reaches saveThreshold
|
||||
* - The amount of time since the oldest unsaved log entry was created reaches saveInterval
|
||||
*
|
||||
* You can optionally disable the saveThreshold by setting it to zero.
|
||||
* If you disable the saveThreshold you are entirely dependent on the saveInterval.
|
||||
*
|
||||
* You can optionally disable the saveInterval by setting it to zero (or a negative value).
|
||||
* If you disable the saveInterval you are entirely dependent on the saveThreshold.
|
||||
*
|
||||
* It's not wise to disable both saveThreshold and saveInterval.
|
||||
*
|
||||
* The default saveThreshold is 500.
|
||||
* The default saveInterval is 60 seconds.
|
||||
**/
|
||||
@property (assign, readwrite) NSUInteger saveThreshold;
|
||||
@property (assign, readwrite) NSTimeInterval saveInterval;
|
||||
|
||||
/**
|
||||
* It is likely you don't want the log entries to persist forever.
|
||||
* Doing so would allow the database to grow infinitely large over time.
|
||||
*
|
||||
* The maxAge property provides a way to specify how old a log statement can get
|
||||
* before it should get deleted from the database.
|
||||
*
|
||||
* The deleteInterval specifies how often to sweep for old log entries.
|
||||
* Since deleting is an expensive operation (disk io) is is done on a fixed interval.
|
||||
*
|
||||
* An alternative to the deleteInterval is the deleteOnEverySave option.
|
||||
* This specifies that old log entries should be deleted during every save operation.
|
||||
*
|
||||
* You can optionally disable the maxAge by setting it to zero (or a negative value).
|
||||
* If you disable the maxAge then old log statements are not deleted.
|
||||
*
|
||||
* You can optionally disable the deleteInterval by setting it to zero (or a negative value).
|
||||
*
|
||||
* If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted.
|
||||
*
|
||||
* It's not wise to enable both deleteInterval and deleteOnEverySave.
|
||||
*
|
||||
* The default maxAge is 7 days.
|
||||
* The default deleteInterval is 5 minutes.
|
||||
* The default deleteOnEverySave is NO.
|
||||
**/
|
||||
@property (assign, readwrite) NSTimeInterval maxAge;
|
||||
@property (assign, readwrite) NSTimeInterval deleteInterval;
|
||||
@property (assign, readwrite) BOOL deleteOnEverySave;
|
||||
|
||||
/**
|
||||
* Forces a save of any pending log entries (flushes log entries to disk).
|
||||
**/
|
||||
- (void)savePendingLogEntries;
|
||||
|
||||
/**
|
||||
* Removes any log entries that are older than maxAge.
|
||||
**/
|
||||
- (void)deleteOldLogEntries;
|
||||
|
||||
@end
|
||||
727
Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m
generated
Normal file
727
Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m
generated
Normal file
|
|
@ -0,0 +1,727 @@
|
|||
#import "DDAbstractDatabaseLogger.h"
|
||||
#import <math.h>
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
**/
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
@interface DDAbstractDatabaseLogger ()
|
||||
- (void)destroySaveTimer;
|
||||
- (void)destroyDeleteTimer;
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation DDAbstractDatabaseLogger
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
saveThreshold = 500;
|
||||
saveInterval = 60; // 60 seconds
|
||||
maxAge = (60 * 60 * 24 * 7); // 7 days
|
||||
deleteInterval = (60 * 5); // 5 minutes
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self destroySaveTimer];
|
||||
[self destroyDeleteTimer];
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Override Me
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (BOOL)db_log:(DDLogMessage *)logMessage
|
||||
{
|
||||
// Override me and add your implementation.
|
||||
//
|
||||
// Return YES if an item was added to the buffer.
|
||||
// Return NO if the logMessage was ignored.
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)db_save
|
||||
{
|
||||
// Override me and add your implementation.
|
||||
}
|
||||
|
||||
- (void)db_delete
|
||||
{
|
||||
// Override me and add your implementation.
|
||||
}
|
||||
|
||||
- (void)db_saveAndDelete
|
||||
{
|
||||
// Override me and add your implementation.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Private API
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)performSaveAndSuspendSaveTimer
|
||||
{
|
||||
if (unsavedCount > 0)
|
||||
{
|
||||
if (deleteOnEverySave)
|
||||
[self db_saveAndDelete];
|
||||
else
|
||||
[self db_save];
|
||||
}
|
||||
|
||||
unsavedCount = 0;
|
||||
unsavedTime = 0;
|
||||
|
||||
if (saveTimer && !saveTimerSuspended)
|
||||
{
|
||||
dispatch_suspend(saveTimer);
|
||||
saveTimerSuspended = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)performDelete
|
||||
{
|
||||
if (maxAge > 0.0)
|
||||
{
|
||||
[self db_delete];
|
||||
|
||||
lastDeleteTime = dispatch_time(DISPATCH_TIME_NOW, 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Timers
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)destroySaveTimer
|
||||
{
|
||||
if (saveTimer)
|
||||
{
|
||||
dispatch_source_cancel(saveTimer);
|
||||
if (saveTimerSuspended)
|
||||
{
|
||||
// Must resume a timer before releasing it (or it will crash)
|
||||
dispatch_resume(saveTimer);
|
||||
saveTimerSuspended = NO;
|
||||
}
|
||||
#if !OS_OBJECT_USE_OBJC
|
||||
dispatch_release(saveTimer);
|
||||
#endif
|
||||
saveTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateAndResumeSaveTimer
|
||||
{
|
||||
if ((saveTimer != NULL) && (saveInterval > 0.0) && (unsavedTime > 0.0))
|
||||
{
|
||||
uint64_t interval = (uint64_t)(saveInterval * NSEC_PER_SEC);
|
||||
dispatch_time_t startTime = dispatch_time(unsavedTime, interval);
|
||||
|
||||
dispatch_source_set_timer(saveTimer, startTime, interval, 1.0);
|
||||
|
||||
if (saveTimerSuspended)
|
||||
{
|
||||
dispatch_resume(saveTimer);
|
||||
saveTimerSuspended = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)createSuspendedSaveTimer
|
||||
{
|
||||
if ((saveTimer == NULL) && (saveInterval > 0.0))
|
||||
{
|
||||
saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, loggerQueue);
|
||||
|
||||
dispatch_source_set_event_handler(saveTimer, ^{ @autoreleasepool {
|
||||
|
||||
[self performSaveAndSuspendSaveTimer];
|
||||
|
||||
}});
|
||||
|
||||
saveTimerSuspended = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)destroyDeleteTimer
|
||||
{
|
||||
if (deleteTimer)
|
||||
{
|
||||
dispatch_source_cancel(deleteTimer);
|
||||
#if !OS_OBJECT_USE_OBJC
|
||||
dispatch_release(deleteTimer);
|
||||
#endif
|
||||
deleteTimer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateDeleteTimer
|
||||
{
|
||||
if ((deleteTimer != NULL) && (deleteInterval > 0.0) && (maxAge > 0.0))
|
||||
{
|
||||
uint64_t interval = (uint64_t)(deleteInterval * NSEC_PER_SEC);
|
||||
dispatch_time_t startTime;
|
||||
|
||||
if (lastDeleteTime > 0)
|
||||
startTime = dispatch_time(lastDeleteTime, interval);
|
||||
else
|
||||
startTime = dispatch_time(DISPATCH_TIME_NOW, interval);
|
||||
|
||||
dispatch_source_set_timer(deleteTimer, startTime, interval, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)createAndStartDeleteTimer
|
||||
{
|
||||
if ((deleteTimer == NULL) && (deleteInterval > 0.0) && (maxAge > 0.0))
|
||||
{
|
||||
deleteTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, loggerQueue);
|
||||
|
||||
if (deleteTimer != NULL) {
|
||||
dispatch_source_set_event_handler(deleteTimer, ^{ @autoreleasepool {
|
||||
|
||||
[self performDelete];
|
||||
|
||||
}});
|
||||
|
||||
[self updateDeleteTimer];
|
||||
|
||||
if (deleteTimer != NULL) dispatch_resume(deleteTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Configuration
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (NSUInteger)saveThreshold
|
||||
{
|
||||
// The design of this method is taken from the DDAbstractLogger implementation.
|
||||
// For extensive documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
// Note: The internal implementation MUST access the colorsEnabled variable directly,
|
||||
// This method is designed explicitly for external access.
|
||||
//
|
||||
// Using "self." syntax to go through this method will cause immediate deadlock.
|
||||
// This is the intended result. Fix it by accessing the ivar directly.
|
||||
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
|
||||
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
|
||||
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
|
||||
__block NSUInteger result;
|
||||
|
||||
dispatch_sync(globalLoggingQueue, ^{
|
||||
dispatch_sync(loggerQueue, ^{
|
||||
result = saveThreshold;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setSaveThreshold:(NSUInteger)threshold
|
||||
{
|
||||
dispatch_block_t block = ^{ @autoreleasepool {
|
||||
|
||||
if (saveThreshold != threshold)
|
||||
{
|
||||
saveThreshold = threshold;
|
||||
|
||||
// Since the saveThreshold has changed,
|
||||
// we check to see if the current unsavedCount has surpassed the new threshold.
|
||||
//
|
||||
// If it has, we immediately save the log.
|
||||
|
||||
if ((unsavedCount >= saveThreshold) && (saveThreshold > 0))
|
||||
{
|
||||
[self performSaveAndSuspendSaveTimer];
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
// The design of the setter logic below is taken from the DDAbstractLogger implementation.
|
||||
// For documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
if ([self isOnInternalLoggerQueue])
|
||||
{
|
||||
block();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
|
||||
dispatch_async(globalLoggingQueue, ^{
|
||||
dispatch_async(loggerQueue, block);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (NSTimeInterval)saveInterval
|
||||
{
|
||||
// The design of this method is taken from the DDAbstractLogger implementation.
|
||||
// For extensive documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
// Note: The internal implementation MUST access the colorsEnabled variable directly,
|
||||
// This method is designed explicitly for external access.
|
||||
//
|
||||
// Using "self." syntax to go through this method will cause immediate deadlock.
|
||||
// This is the intended result. Fix it by accessing the ivar directly.
|
||||
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
|
||||
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
|
||||
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
|
||||
__block NSTimeInterval result;
|
||||
|
||||
dispatch_sync(globalLoggingQueue, ^{
|
||||
dispatch_sync(loggerQueue, ^{
|
||||
result = saveInterval;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setSaveInterval:(NSTimeInterval)interval
|
||||
{
|
||||
dispatch_block_t block = ^{ @autoreleasepool {
|
||||
|
||||
// C99 recommended floating point comparison macro
|
||||
// Read: isLessThanOrGreaterThan(floatA, floatB)
|
||||
|
||||
if (/* saveInterval != interval */ islessgreater(saveInterval, interval))
|
||||
{
|
||||
saveInterval = interval;
|
||||
|
||||
// There are several cases we need to handle here.
|
||||
//
|
||||
// 1. If the saveInterval was previously enabled and it just got disabled,
|
||||
// then we need to stop the saveTimer. (And we might as well release it.)
|
||||
//
|
||||
// 2. If the saveInterval was previously disabled and it just got enabled,
|
||||
// then we need to setup the saveTimer. (Plus we might need to do an immediate save.)
|
||||
//
|
||||
// 3. If the saveInterval increased, then we need to reset the timer so that it fires at the later date.
|
||||
//
|
||||
// 4. If the saveInterval decreased, then we need to reset the timer so that it fires at an earlier date.
|
||||
// (Plus we might need to do an immediate save.)
|
||||
|
||||
if (saveInterval > 0.0)
|
||||
{
|
||||
if (saveTimer == NULL)
|
||||
{
|
||||
// Handles #2
|
||||
//
|
||||
// Since the saveTimer uses the unsavedTime to calculate it's first fireDate,
|
||||
// if a save is needed the timer will fire immediately.
|
||||
|
||||
[self createSuspendedSaveTimer];
|
||||
[self updateAndResumeSaveTimer];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handles #3
|
||||
// Handles #4
|
||||
//
|
||||
// Since the saveTimer uses the unsavedTime to calculate it's first fireDate,
|
||||
// if a save is needed the timer will fire immediately.
|
||||
|
||||
[self updateAndResumeSaveTimer];
|
||||
}
|
||||
}
|
||||
else if (saveTimer)
|
||||
{
|
||||
// Handles #1
|
||||
|
||||
[self destroySaveTimer];
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
// The design of the setter logic below is taken from the DDAbstractLogger implementation.
|
||||
// For documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
if ([self isOnInternalLoggerQueue])
|
||||
{
|
||||
block();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
|
||||
dispatch_async(globalLoggingQueue, ^{
|
||||
dispatch_async(loggerQueue, block);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (NSTimeInterval)maxAge
|
||||
{
|
||||
// The design of this method is taken from the DDAbstractLogger implementation.
|
||||
// For extensive documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
// Note: The internal implementation MUST access the colorsEnabled variable directly,
|
||||
// This method is designed explicitly for external access.
|
||||
//
|
||||
// Using "self." syntax to go through this method will cause immediate deadlock.
|
||||
// This is the intended result. Fix it by accessing the ivar directly.
|
||||
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
|
||||
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
|
||||
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
|
||||
__block NSTimeInterval result;
|
||||
|
||||
dispatch_sync(globalLoggingQueue, ^{
|
||||
dispatch_sync(loggerQueue, ^{
|
||||
result = maxAge;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setMaxAge:(NSTimeInterval)interval
|
||||
{
|
||||
dispatch_block_t block = ^{ @autoreleasepool {
|
||||
|
||||
// C99 recommended floating point comparison macro
|
||||
// Read: isLessThanOrGreaterThan(floatA, floatB)
|
||||
|
||||
if (/* maxAge != interval */ islessgreater(maxAge, interval))
|
||||
{
|
||||
NSTimeInterval oldMaxAge = maxAge;
|
||||
NSTimeInterval newMaxAge = interval;
|
||||
|
||||
maxAge = interval;
|
||||
|
||||
// There are several cases we need to handle here.
|
||||
//
|
||||
// 1. If the maxAge was previously enabled and it just got disabled,
|
||||
// then we need to stop the deleteTimer. (And we might as well release it.)
|
||||
//
|
||||
// 2. If the maxAge was previously disabled and it just got enabled,
|
||||
// then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.)
|
||||
//
|
||||
// 3. If the maxAge was increased,
|
||||
// then we don't need to do anything.
|
||||
//
|
||||
// 4. If the maxAge was decreased,
|
||||
// then we should do an immediate delete.
|
||||
|
||||
BOOL shouldDeleteNow = NO;
|
||||
|
||||
if (oldMaxAge > 0.0)
|
||||
{
|
||||
if (newMaxAge <= 0.0)
|
||||
{
|
||||
// Handles #1
|
||||
|
||||
[self destroyDeleteTimer];
|
||||
}
|
||||
else if (oldMaxAge > newMaxAge)
|
||||
{
|
||||
// Handles #4
|
||||
shouldDeleteNow = YES;
|
||||
}
|
||||
}
|
||||
else if (newMaxAge > 0.0)
|
||||
{
|
||||
// Handles #2
|
||||
shouldDeleteNow = YES;
|
||||
}
|
||||
|
||||
if (shouldDeleteNow)
|
||||
{
|
||||
[self performDelete];
|
||||
|
||||
if (deleteTimer)
|
||||
[self updateDeleteTimer];
|
||||
else
|
||||
[self createAndStartDeleteTimer];
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
// The design of the setter logic below is taken from the DDAbstractLogger implementation.
|
||||
// For documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
if ([self isOnInternalLoggerQueue])
|
||||
{
|
||||
block();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
|
||||
dispatch_async(globalLoggingQueue, ^{
|
||||
dispatch_async(loggerQueue, block);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (NSTimeInterval)deleteInterval
|
||||
{
|
||||
// The design of this method is taken from the DDAbstractLogger implementation.
|
||||
// For extensive documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
// Note: The internal implementation MUST access the colorsEnabled variable directly,
|
||||
// This method is designed explicitly for external access.
|
||||
//
|
||||
// Using "self." syntax to go through this method will cause immediate deadlock.
|
||||
// This is the intended result. Fix it by accessing the ivar directly.
|
||||
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
|
||||
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
|
||||
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
|
||||
__block NSTimeInterval result;
|
||||
|
||||
dispatch_sync(globalLoggingQueue, ^{
|
||||
dispatch_sync(loggerQueue, ^{
|
||||
result = deleteInterval;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setDeleteInterval:(NSTimeInterval)interval
|
||||
{
|
||||
dispatch_block_t block = ^{ @autoreleasepool {
|
||||
|
||||
// C99 recommended floating point comparison macro
|
||||
// Read: isLessThanOrGreaterThan(floatA, floatB)
|
||||
|
||||
if (/* deleteInterval != interval */ islessgreater(deleteInterval, interval))
|
||||
{
|
||||
deleteInterval = interval;
|
||||
|
||||
// There are several cases we need to handle here.
|
||||
//
|
||||
// 1. If the deleteInterval was previously enabled and it just got disabled,
|
||||
// then we need to stop the deleteTimer. (And we might as well release it.)
|
||||
//
|
||||
// 2. If the deleteInterval was previously disabled and it just got enabled,
|
||||
// then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.)
|
||||
//
|
||||
// 3. If the deleteInterval increased, then we need to reset the timer so that it fires at the later date.
|
||||
//
|
||||
// 4. If the deleteInterval decreased, then we need to reset the timer so that it fires at an earlier date.
|
||||
// (Plus we might need to do an immediate delete.)
|
||||
|
||||
if (deleteInterval > 0.0)
|
||||
{
|
||||
if (deleteTimer == NULL)
|
||||
{
|
||||
// Handles #2
|
||||
//
|
||||
// Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate,
|
||||
// if a delete is needed the timer will fire immediately.
|
||||
|
||||
[self createAndStartDeleteTimer];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handles #3
|
||||
// Handles #4
|
||||
//
|
||||
// Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate,
|
||||
// if a save is needed the timer will fire immediately.
|
||||
|
||||
[self updateDeleteTimer];
|
||||
}
|
||||
}
|
||||
else if (deleteTimer)
|
||||
{
|
||||
// Handles #1
|
||||
|
||||
[self destroyDeleteTimer];
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
||||
// The design of the setter logic below is taken from the DDAbstractLogger implementation.
|
||||
// For documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
if ([self isOnInternalLoggerQueue])
|
||||
{
|
||||
block();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
|
||||
dispatch_async(globalLoggingQueue, ^{
|
||||
dispatch_async(loggerQueue, block);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)deleteOnEverySave
|
||||
{
|
||||
// The design of this method is taken from the DDAbstractLogger implementation.
|
||||
// For extensive documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
// Note: The internal implementation MUST access the colorsEnabled variable directly,
|
||||
// This method is designed explicitly for external access.
|
||||
//
|
||||
// Using "self." syntax to go through this method will cause immediate deadlock.
|
||||
// This is the intended result. Fix it by accessing the ivar directly.
|
||||
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
|
||||
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
|
||||
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
|
||||
__block BOOL result;
|
||||
|
||||
dispatch_sync(globalLoggingQueue, ^{
|
||||
dispatch_sync(loggerQueue, ^{
|
||||
result = deleteOnEverySave;
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setDeleteOnEverySave:(BOOL)flag
|
||||
{
|
||||
dispatch_block_t block = ^{
|
||||
|
||||
deleteOnEverySave = flag;
|
||||
};
|
||||
|
||||
// The design of the setter logic below is taken from the DDAbstractLogger implementation.
|
||||
// For documentation please refer to the DDAbstractLogger implementation.
|
||||
|
||||
if ([self isOnInternalLoggerQueue])
|
||||
{
|
||||
block();
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
|
||||
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
|
||||
|
||||
dispatch_async(globalLoggingQueue, ^{
|
||||
dispatch_async(loggerQueue, block);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Public API
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)savePendingLogEntries
|
||||
{
|
||||
dispatch_block_t block = ^{ @autoreleasepool {
|
||||
|
||||
[self performSaveAndSuspendSaveTimer];
|
||||
}};
|
||||
|
||||
if ([self isOnInternalLoggerQueue])
|
||||
block();
|
||||
else
|
||||
dispatch_async(loggerQueue, block);
|
||||
}
|
||||
|
||||
- (void)deleteOldLogEntries
|
||||
{
|
||||
dispatch_block_t block = ^{ @autoreleasepool {
|
||||
|
||||
[self performDelete];
|
||||
}};
|
||||
|
||||
if ([self isOnInternalLoggerQueue])
|
||||
block();
|
||||
else
|
||||
dispatch_async(loggerQueue, block);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark DDLogger
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (void)didAddLogger
|
||||
{
|
||||
// If you override me be sure to invoke [super didAddLogger];
|
||||
|
||||
[self createSuspendedSaveTimer];
|
||||
|
||||
[self createAndStartDeleteTimer];
|
||||
}
|
||||
|
||||
- (void)willRemoveLogger
|
||||
{
|
||||
// If you override me be sure to invoke [super willRemoveLogger];
|
||||
|
||||
[self performSaveAndSuspendSaveTimer];
|
||||
|
||||
[self destroySaveTimer];
|
||||
[self destroyDeleteTimer];
|
||||
}
|
||||
|
||||
- (void)logMessage:(DDLogMessage *)logMessage
|
||||
{
|
||||
if ([self db_log:logMessage])
|
||||
{
|
||||
BOOL firstUnsavedEntry = (++unsavedCount == 1);
|
||||
|
||||
if ((unsavedCount >= saveThreshold) && (saveThreshold > 0))
|
||||
{
|
||||
[self performSaveAndSuspendSaveTimer];
|
||||
}
|
||||
else if (firstUnsavedEntry)
|
||||
{
|
||||
unsavedTime = dispatch_time(DISPATCH_TIME_NOW, 0);
|
||||
[self updateAndResumeSaveTimer];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)flush
|
||||
{
|
||||
// This method is invoked by DDLog's flushLog method.
|
||||
//
|
||||
// It is called automatically when the application quits,
|
||||
// or if the developer invokes DDLog's flushLog method prior to crashing or something.
|
||||
|
||||
[self performSaveAndSuspendSaveTimer];
|
||||
}
|
||||
|
||||
@end
|
||||
16
Pods/CocoaLumberjack/Lumberjack/DDAssert.h
generated
Normal file
16
Pods/CocoaLumberjack/Lumberjack/DDAssert.h
generated
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// DDAssert.h
|
||||
// CocoaLumberjack
|
||||
//
|
||||
// Created by Ernesto Rivera on 2014/07/07.
|
||||
//
|
||||
//
|
||||
|
||||
#import "DDLog.h"
|
||||
|
||||
#define DDAssert(condition, frmt, ...) if (!(condition)) { \
|
||||
NSString * description = [NSString stringWithFormat:frmt, ##__VA_ARGS__]; \
|
||||
DDLogError(@"%@", description); \
|
||||
NSAssert(NO, description); }
|
||||
#define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition)
|
||||
|
||||
406
Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h
generated
Normal file
406
Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h
generated
Normal file
|
|
@ -0,0 +1,406 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "DDLog.h"
|
||||
|
||||
@class DDLogFileInfo;
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides a logger to write log statements to a file.
|
||||
**/
|
||||
|
||||
|
||||
// Default configuration and safety/sanity values.
|
||||
//
|
||||
// maximumFileSize -> DEFAULT_LOG_MAX_FILE_SIZE
|
||||
// rollingFrequency -> DEFAULT_LOG_ROLLING_FREQUENCY
|
||||
// maximumNumberOfLogFiles -> DEFAULT_LOG_MAX_NUM_LOG_FILES
|
||||
// logFilesDiskQuota -> DEFAULT_LOG_FILES_DISK_QUOTA
|
||||
//
|
||||
// You should carefully consider the proper configuration values for your application.
|
||||
|
||||
#define DEFAULT_LOG_MAX_FILE_SIZE (1024 * 1024) // 1 MB
|
||||
#define DEFAULT_LOG_ROLLING_FREQUENCY (60 * 60 * 24) // 24 Hours
|
||||
#define DEFAULT_LOG_MAX_NUM_LOG_FILES (5) // 5 Files
|
||||
#define DEFAULT_LOG_FILES_DISK_QUOTA (20 * 1024 * 1024) // 20 MB
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The LogFileManager protocol is designed to allow you to control all aspects of your log files.
|
||||
//
|
||||
// The primary purpose of this is to allow you to do something with the log files after they have been rolled.
|
||||
// Perhaps you want to compress them to save disk space.
|
||||
// Perhaps you want to upload them to an FTP server.
|
||||
// Perhaps you want to run some analytics on the file.
|
||||
//
|
||||
// A default LogFileManager is, of course, provided.
|
||||
// The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property.
|
||||
//
|
||||
// This protocol provides various methods to fetch the list of log files.
|
||||
//
|
||||
// There are two variants: sorted and unsorted.
|
||||
// If sorting is not necessary, the unsorted variant is obviously faster.
|
||||
// The sorted variant will return an array sorted by when the log files were created,
|
||||
// with the most recently created log file at index 0, and the oldest log file at the end of the array.
|
||||
//
|
||||
// You can fetch only the log file paths (full path including name), log file names (name only),
|
||||
// or an array of DDLogFileInfo objects.
|
||||
// The DDLogFileInfo class is documented below, and provides a handy wrapper that
|
||||
// gives you easy access to various file attributes such as the creation date or the file size.
|
||||
|
||||
@protocol DDLogFileManager <NSObject>
|
||||
@required
|
||||
|
||||
// Public properties
|
||||
|
||||
/**
|
||||
* The maximum number of archived log files to keep on disk.
|
||||
* For example, if this property is set to 3,
|
||||
* then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk.
|
||||
* Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted.
|
||||
*
|
||||
* You may optionally disable this option by setting it to zero.
|
||||
**/
|
||||
@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
|
||||
|
||||
/**
|
||||
* The maximum space that logs can take. On rolling logfile all old logfiles that exceed logFilesDiskQuota will
|
||||
* be deleted.
|
||||
*
|
||||
* You may optionally disable this option by setting it to zero.
|
||||
**/
|
||||
@property (readwrite, assign, atomic) unsigned long long logFilesDiskQuota;
|
||||
|
||||
// Public methods
|
||||
|
||||
- (NSString *)logsDirectory;
|
||||
|
||||
- (NSArray *)unsortedLogFilePaths;
|
||||
- (NSArray *)unsortedLogFileNames;
|
||||
- (NSArray *)unsortedLogFileInfos;
|
||||
|
||||
- (NSArray *)sortedLogFilePaths;
|
||||
- (NSArray *)sortedLogFileNames;
|
||||
- (NSArray *)sortedLogFileInfos;
|
||||
|
||||
// Private methods (only to be used by DDFileLogger)
|
||||
|
||||
- (NSString *)createNewLogFile;
|
||||
|
||||
@optional
|
||||
|
||||
// Notifications from DDFileLogger
|
||||
|
||||
- (void)didArchiveLogFile:(NSString *)logFilePath;
|
||||
- (void)didRollAndArchiveLogFile:(NSString *)logFilePath;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Default log file manager.
|
||||
*
|
||||
* All log files are placed inside the logsDirectory.
|
||||
* If a specific logsDirectory isn't specified, the default directory is used.
|
||||
* On Mac, this is in ~/Library/Logs/<Application Name>.
|
||||
* On iPhone, this is in ~/Library/Caches/Logs.
|
||||
*
|
||||
* Log files are named "<bundle identifier> <date> <time>.log"
|
||||
* Example: com.organization.myapp 2013-12-03 17-14.log
|
||||
*
|
||||
* Archived log files are automatically deleted according to the maximumNumberOfLogFiles property.
|
||||
**/
|
||||
@interface DDLogFileManagerDefault : NSObject <DDLogFileManager>
|
||||
{
|
||||
NSUInteger maximumNumberOfLogFiles;
|
||||
unsigned long long logFilesDiskQuota;
|
||||
NSString *_logsDirectory;
|
||||
#if TARGET_OS_IPHONE
|
||||
NSString* _defaultFileProtectionLevel;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (id)init;
|
||||
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory;
|
||||
#if TARGET_OS_IPHONE
|
||||
/*
|
||||
* Calling this constructor you can override the default "automagically" chosen NSFileProtection level.
|
||||
* Useful if you are writing a command line utility / CydiaSubstrate addon for iOS that has no NSBundle
|
||||
* or like SpringBoard no BackgroundModes key in the NSBundle:
|
||||
* iPhone:~ root# cycript -p SpringBoard
|
||||
* cy# [NSBundle mainBundle]
|
||||
* #"NSBundle </System/Library/CoreServices/SpringBoard.app> (loaded)"
|
||||
* cy# [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
|
||||
* null
|
||||
* cy#
|
||||
**/
|
||||
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString*)fileProtectionLevel;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Methods to override.
|
||||
*
|
||||
* Log files are named "<bundle identifier> <date> <time>.log"
|
||||
* Example: com.organization.myapp 2013-12-03 17-14.log
|
||||
*
|
||||
* If you wish to change default filename, you can override following two methods.
|
||||
* - newLogFileName method would be called on new logfile creation.
|
||||
* - isLogFile: method would be called to filter logfiles from all other files in logsDirectory.
|
||||
* You have to parse given filename and return YES if it is logFile.
|
||||
*
|
||||
* **NOTE**
|
||||
* newLogFileName returns filename. If appropriate file already exists, number would be added
|
||||
* to filename before extension. You have to handle this case in isLogFile: method.
|
||||
*
|
||||
* Example:
|
||||
* - newLogFileName returns "com.organization.myapp 2013-12-03.log",
|
||||
* file "com.organization.myapp 2013-12-03.log" would be created.
|
||||
* - after some time "com.organization.myapp 2013-12-03.log" is archived
|
||||
* - newLogFileName again returns "com.organization.myapp 2013-12-03.log",
|
||||
* file "com.organization.myapp 2013-12-03 2.log" would be created.
|
||||
* - after some time "com.organization.myapp 2013-12-03 1.log" is archived
|
||||
* - newLogFileName again returns "com.organization.myapp 2013-12-03.log",
|
||||
* file "com.organization.myapp 2013-12-03 3.log" would be created.
|
||||
**/
|
||||
- (NSString *)newLogFileName;
|
||||
- (BOOL)isLogFile:(NSString *)fileName;
|
||||
|
||||
/* Inherited from DDLogFileManager protocol:
|
||||
|
||||
@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
|
||||
@property (readwrite, assign, atomic) NSUInteger logFilesDiskQuota;
|
||||
|
||||
- (NSString *)logsDirectory;
|
||||
|
||||
- (NSArray *)unsortedLogFilePaths;
|
||||
- (NSArray *)unsortedLogFileNames;
|
||||
- (NSArray *)unsortedLogFileInfos;
|
||||
|
||||
- (NSArray *)sortedLogFilePaths;
|
||||
- (NSArray *)sortedLogFileNames;
|
||||
- (NSArray *)sortedLogFileInfos;
|
||||
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Most users will want file log messages to be prepended with the date and time.
|
||||
* Rather than forcing the majority of users to write their own formatter,
|
||||
* we will supply a logical default formatter.
|
||||
* Users can easily replace this formatter with their own by invoking the setLogFormatter method.
|
||||
* It can also be removed by calling setLogFormatter, and passing a nil parameter.
|
||||
*
|
||||
* In addition to the convenience of having a logical default formatter,
|
||||
* it will also provide a template that makes it easy for developers to copy and change.
|
||||
**/
|
||||
@interface DDLogFileFormatterDefault : NSObject <DDLogFormatter>
|
||||
{
|
||||
NSDateFormatter *dateFormatter;
|
||||
}
|
||||
|
||||
- (id)init;
|
||||
- (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDFileLogger : DDAbstractLogger <DDLogger>
|
||||
{
|
||||
__strong id <DDLogFileManager> logFileManager;
|
||||
|
||||
DDLogFileInfo *currentLogFileInfo;
|
||||
NSFileHandle *currentLogFileHandle;
|
||||
|
||||
dispatch_source_t currentLogFileVnode;
|
||||
dispatch_source_t rollingTimer;
|
||||
|
||||
unsigned long long maximumFileSize;
|
||||
NSTimeInterval rollingFrequency;
|
||||
}
|
||||
|
||||
- (id)init;
|
||||
- (instancetype)initWithLogFileManager:(id <DDLogFileManager>)logFileManager;
|
||||
|
||||
/**
|
||||
* Log File Rolling:
|
||||
*
|
||||
* maximumFileSize:
|
||||
* The approximate maximum size to allow log files to grow.
|
||||
* If a log file is larger than this value after a log statement is appended,
|
||||
* then the log file is rolled.
|
||||
*
|
||||
* rollingFrequency
|
||||
* How often to roll the log file.
|
||||
* The frequency is given as an NSTimeInterval, which is a double that specifies the interval in seconds.
|
||||
* Once the log file gets to be this old, it is rolled.
|
||||
*
|
||||
* Both the maximumFileSize and the rollingFrequency are used to manage rolling.
|
||||
* Whichever occurs first will cause the log file to be rolled.
|
||||
*
|
||||
* For example:
|
||||
* The rollingFrequency is 24 hours,
|
||||
* but the log file surpasses the maximumFileSize after only 20 hours.
|
||||
* The log file will be rolled at that 20 hour mark.
|
||||
* A new log file will be created, and the 24 hour timer will be restarted.
|
||||
*
|
||||
* You may optionally disable rolling due to filesize by setting maximumFileSize to zero.
|
||||
* If you do so, rolling is based solely on rollingFrequency.
|
||||
*
|
||||
* You may optionally disable rolling due to time by setting rollingFrequency to zero (or any non-positive number).
|
||||
* If you do so, rolling is based solely on maximumFileSize.
|
||||
*
|
||||
* If you disable both maximumFileSize and rollingFrequency, then the log file won't ever be rolled.
|
||||
* This is strongly discouraged.
|
||||
**/
|
||||
@property (readwrite, assign) unsigned long long maximumFileSize;
|
||||
@property (readwrite, assign) NSTimeInterval rollingFrequency;
|
||||
@property (readwrite, assign, atomic) BOOL doNotReuseLogFiles;
|
||||
|
||||
/**
|
||||
* The DDLogFileManager instance can be used to retrieve the list of log files,
|
||||
* and configure the maximum number of archived log files to keep.
|
||||
*
|
||||
* @see DDLogFileManager.maximumNumberOfLogFiles
|
||||
**/
|
||||
@property (strong, nonatomic, readonly) id <DDLogFileManager> logFileManager;
|
||||
|
||||
/**
|
||||
* When using a custom formatter you can set the logMessage method not to append
|
||||
* '\n' character after each output. This allows for some greater flexibility with
|
||||
* custom formatters. Default value is YES.
|
||||
**/
|
||||
|
||||
@property (readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
|
||||
|
||||
// You can optionally force the current log file to be rolled with this method.
|
||||
// CompletionBlock will be called on main queue.
|
||||
|
||||
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock;
|
||||
|
||||
// Method is deprecated. Use rollLogFileWithCompletionBlock: method instead.
|
||||
|
||||
- (void)rollLogFile __attribute((deprecated));
|
||||
|
||||
// Inherited from DDAbstractLogger
|
||||
|
||||
// - (id <DDLogFormatter>)logFormatter;
|
||||
// - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* DDLogFileInfo is a simple class that provides access to various file attributes.
|
||||
* It provides good performance as it only fetches the information if requested,
|
||||
* and it caches the information to prevent duplicate fetches.
|
||||
*
|
||||
* It was designed to provide quick snapshots of the current state of log files,
|
||||
* and to help sort log files in an array.
|
||||
*
|
||||
* This class does not monitor the files, or update it's cached attribute values if the file changes on disk.
|
||||
* This is not what the class was designed for.
|
||||
*
|
||||
* If you absolutely must get updated values,
|
||||
* you can invoke the reset method which will clear the cache.
|
||||
**/
|
||||
@interface DDLogFileInfo : NSObject
|
||||
{
|
||||
__strong NSString *filePath;
|
||||
__strong NSString *fileName;
|
||||
|
||||
__strong NSDictionary *fileAttributes;
|
||||
|
||||
__strong NSDate *creationDate;
|
||||
__strong NSDate *modificationDate;
|
||||
|
||||
unsigned long long fileSize;
|
||||
}
|
||||
|
||||
@property (strong, nonatomic, readonly) NSString *filePath;
|
||||
@property (strong, nonatomic, readonly) NSString *fileName;
|
||||
|
||||
@property (strong, nonatomic, readonly) NSDictionary *fileAttributes;
|
||||
|
||||
@property (strong, nonatomic, readonly) NSDate *creationDate;
|
||||
@property (strong, nonatomic, readonly) NSDate *modificationDate;
|
||||
|
||||
@property (nonatomic, readonly) unsigned long long fileSize;
|
||||
|
||||
@property (nonatomic, readonly) NSTimeInterval age;
|
||||
|
||||
@property (nonatomic, readwrite) BOOL isArchived;
|
||||
|
||||
+ (instancetype)logFileWithPath:(NSString *)filePath;
|
||||
|
||||
- (instancetype)initWithFilePath:(NSString *)filePath;
|
||||
|
||||
- (void)reset;
|
||||
- (void)renameFile:(NSString *)newFileName;
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
|
||||
// So here's the situation.
|
||||
// Extended attributes are perfect for what we're trying to do here (marking files as archived).
|
||||
// This is exactly what extended attributes were designed for.
|
||||
//
|
||||
// But Apple screws us over on the simulator.
|
||||
// Everytime you build-and-go, they copy the application into a new folder on the hard drive,
|
||||
// and as part of the process they strip extended attributes from our log files.
|
||||
// Normally, a copy of a file preserves extended attributes.
|
||||
// So obviously Apple has gone to great lengths to piss us off.
|
||||
//
|
||||
// Thus we use a slightly different tactic for marking log files as archived in the simulator.
|
||||
// That way it "just works" and there's no confusion when testing.
|
||||
//
|
||||
// The difference in method names is indicative of the difference in functionality.
|
||||
// On the simulator we add an attribute by appending a filename extension.
|
||||
//
|
||||
// For example:
|
||||
// "mylog.txt" -> "mylog.archived.txt"
|
||||
// "mylog" -> "mylog.archived"
|
||||
|
||||
- (BOOL)hasExtensionAttributeWithName:(NSString *)attrName;
|
||||
|
||||
- (void)addExtensionAttributeWithName:(NSString *)attrName;
|
||||
- (void)removeExtensionAttributeWithName:(NSString *)attrName;
|
||||
|
||||
#else
|
||||
|
||||
// Normal use of extended attributes used everywhere else,
|
||||
// such as on Macs and on iPhone devices.
|
||||
|
||||
- (BOOL)hasExtendedAttributeWithName:(NSString *)attrName;
|
||||
|
||||
- (void)addExtendedAttributeWithName:(NSString *)attrName;
|
||||
- (void)removeExtendedAttributeWithName:(NSString *)attrName;
|
||||
|
||||
#endif
|
||||
|
||||
- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another;
|
||||
- (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another;
|
||||
|
||||
@end
|
||||
1589
Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m
generated
Normal file
1589
Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m
generated
Normal file
File diff suppressed because it is too large
Load diff
99
Pods/CocoaLumberjack/Lumberjack/DDLog+LOGV.h
generated
Normal file
99
Pods/CocoaLumberjack/Lumberjack/DDLog+LOGV.h
generated
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
// DDLog+LOGV.h
|
||||
// Lumberjack
|
||||
//
|
||||
// Created by Mike Pontillo on 11/20/12.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef Lumberjack_DDLog_LOGV_h
|
||||
#define Lumberjack_DDLog_LOGV_h
|
||||
|
||||
#import "DDLog.h"
|
||||
|
||||
|
||||
#define LOGV_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, avalist) \
|
||||
[DDLog log:isAsynchronous \
|
||||
level:lvl \
|
||||
flag:flg \
|
||||
context:ctx \
|
||||
file:__FILE__ \
|
||||
function:fnct \
|
||||
line:__LINE__ \
|
||||
tag:atag \
|
||||
format:frmt \
|
||||
args:avalist]
|
||||
|
||||
#define LOGV_OBJC_MACRO(async, lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_MACRO(async, lvl, flg, ctx, nil, sel_getName(_cmd), frmt, avalist)
|
||||
|
||||
#define LOGV_C_MACRO(async, lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_MACRO(async, lvl, flg, ctx, nil, __FUNCTION__, frmt, avalist)
|
||||
|
||||
|
||||
|
||||
#define SYNC_LOGV_OBJC_MACRO(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_OBJC_MACRO( NO, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
#define ASYNC_LOGV_OBJC_MACRO(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_OBJC_MACRO(YES, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
#define SYNC_LOGV_C_MACRO(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_C_MACRO( NO, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
#define ASYNC_LOGV_C_MACRO(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_C_MACRO(YES, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
|
||||
|
||||
#define LOGV_MAYBE(async, lvl, flg, ctx, fnct, frmt, avalist) \
|
||||
do { if(lvl & flg) LOGV_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, avalist); } while(0)
|
||||
|
||||
#define LOGV_OBJC_MAYBE(async, lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_MAYBE(async, lvl, flg, ctx, sel_getName(_cmd), frmt, avalist)
|
||||
|
||||
#define LOGV_C_MAYBE(async, lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_MAYBE(async, lvl, flg, ctx, __FUNCTION__, frmt, avalist)
|
||||
|
||||
#define SYNC_LOGV_OBJC_MAYBE(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_OBJC_MAYBE( NO, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
#define ASYNC_LOGV_OBJC_MAYBE(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_OBJC_MAYBE(YES, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
#define SYNC_LOGV_C_MAYBE(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_C_MAYBE( NO, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
#define ASYNC_LOGV_C_MAYBE(lvl, flg, ctx, frmt, avalist) \
|
||||
LOGV_C_MAYBE(YES, lvl, flg, ctx, frmt, avalist)
|
||||
|
||||
|
||||
|
||||
#define LOGV_OBJC_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, avalist) \
|
||||
LOGV_MACRO(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, avalist)
|
||||
|
||||
#define LOGV_C_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, avalist) \
|
||||
LOGV_MACRO(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, avalist)
|
||||
|
||||
#define LOGV_TAG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, avalist) \
|
||||
do { if(lvl & flg) LOGV_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, avalist); } while(0)
|
||||
|
||||
#define LOGV_OBJC_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, avalist) \
|
||||
LOGV_TAG_MAYBE(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, avalist)
|
||||
|
||||
#define LOGV_C_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, avalist) \
|
||||
LOGV_TAG_MAYBE(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, avalist)
|
||||
|
||||
|
||||
|
||||
#define DDLogvError(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, avalist)
|
||||
#define DDLogvWarn(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, avalist)
|
||||
#define DDLogvInfo(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, avalist)
|
||||
#define DDLogvVerbose(frmt, avalist) LOGV_OBJC_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, avalist)
|
||||
|
||||
#define DDLogvCError(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, avalist)
|
||||
#define DDLogvCWarn(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, avalist)
|
||||
#define DDLogvCInfo(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, avalist)
|
||||
#define DDLogvCVerbose(frmt, avalist) LOGV_C_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, avalist)
|
||||
|
||||
#endif
|
||||
692
Pods/CocoaLumberjack/Lumberjack/DDLog.h
generated
Executable file
692
Pods/CocoaLumberjack/Lumberjack/DDLog.h
generated
Executable file
|
|
@ -0,0 +1,692 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
* Otherwise, here is a quick refresher.
|
||||
* There are three steps to using the macros:
|
||||
*
|
||||
* Step 1:
|
||||
* Import the header in your implementation file:
|
||||
*
|
||||
* #import "DDLog.h"
|
||||
*
|
||||
* Step 2:
|
||||
* Define your logging level in your implementation file:
|
||||
*
|
||||
* // Log levels: off, error, warn, info, verbose
|
||||
* static const int ddLogLevel = LOG_LEVEL_VERBOSE;
|
||||
*
|
||||
* Step 2 [3rd party frameworks]:
|
||||
*
|
||||
* Define your LOG_LEVEL_DEF to a different variable/function than ddLogLevel:
|
||||
*
|
||||
* // #undef LOG_LEVEL_DEF // Undefine first only if needed
|
||||
* #define LOG_LEVEL_DEF myLibLogLevel
|
||||
*
|
||||
* Define your logging level in your implementation file:
|
||||
*
|
||||
* // Log levels: off, error, warn, info, verbose
|
||||
* static const int myLibLogLevel = LOG_LEVEL_VERBOSE;
|
||||
*
|
||||
* Step 3:
|
||||
* Replace your NSLog statements with DDLog statements according to the severity of the message.
|
||||
*
|
||||
* NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!");
|
||||
*
|
||||
* DDLog works exactly the same as NSLog.
|
||||
* This means you can pass it multiple variables just like NSLog.
|
||||
**/
|
||||
|
||||
#ifndef LOG_LEVEL_DEF
|
||||
#define LOG_LEVEL_DEF ddLogLevel
|
||||
#endif
|
||||
|
||||
@class DDLogMessage;
|
||||
|
||||
@protocol DDLogger;
|
||||
@protocol DDLogFormatter;
|
||||
|
||||
/**
|
||||
* This is the single macro that all other macros below compile into.
|
||||
* This big multiline macro makes all the other macros easier to read.
|
||||
**/
|
||||
|
||||
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
|
||||
[DDLog log:isAsynchronous \
|
||||
level:lvl \
|
||||
flag:flg \
|
||||
context:ctx \
|
||||
file:__FILE__ \
|
||||
function:fnct \
|
||||
line:__LINE__ \
|
||||
tag:atag \
|
||||
format:(frmt), ##__VA_ARGS__]
|
||||
|
||||
/**
|
||||
* Define the Objective-C and C versions of the macro.
|
||||
* These automatically inject the proper function name for either an objective-c method or c function.
|
||||
*
|
||||
* We also define shorthand versions for asynchronous and synchronous logging.
|
||||
**/
|
||||
|
||||
#define LOG_OBJC_MACRO(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, nil, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_MACRO(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, nil, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MACRO(NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MACRO(NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Define version of the macro that only execute if the logLevel is above the threshold.
|
||||
* The compiled versions essentially look like this:
|
||||
*
|
||||
* if (logFlagForThisLogMsg & ddLogLevel) { execute log message }
|
||||
*
|
||||
* When LOG_LEVEL_DEF is defined as ddLogLevel.
|
||||
*
|
||||
* As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels.
|
||||
* This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques.
|
||||
*
|
||||
* Note that when compiler optimizations are enabled (as they are for your release builds),
|
||||
* the log messages above your logging threshold will automatically be compiled out.
|
||||
*
|
||||
* (If the compiler sees LOG_LEVEL_DEF/ddLogLevel declared as a constant, the compiler simply checks to see
|
||||
* if the 'if' statement would execute, and if not it strips it from the binary.)
|
||||
*
|
||||
* We also define shorthand versions for asynchronous and synchronous logging.
|
||||
**/
|
||||
|
||||
#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \
|
||||
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
|
||||
|
||||
#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MAYBE(async, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_MAYBE(async, lvl, flg, ctx, frmt, ...) \
|
||||
LOG_MAYBE(async, lvl, flg, ctx, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MAYBE(NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_OBJC_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define SYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MAYBE(NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define ASYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \
|
||||
LOG_C_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Define versions of the macros that also accept tags.
|
||||
*
|
||||
* The DDLogMessage object includes a 'tag' ivar that may be used for a variety of purposes.
|
||||
* It may be used to pass custom information to loggers or formatters.
|
||||
* Or it may be used by 3rd party extensions to the framework.
|
||||
*
|
||||
* Thes macros just make it a little easier to extend logging functionality.
|
||||
**/
|
||||
|
||||
#define LOG_OBJC_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_MACRO(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
|
||||
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
|
||||
|
||||
#define LOG_OBJC_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__)
|
||||
|
||||
#define LOG_C_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \
|
||||
LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Define the standard options.
|
||||
*
|
||||
* We default to only 4 levels because it makes it easier for beginners
|
||||
* to make the transition to a logging framework.
|
||||
*
|
||||
* More advanced users may choose to completely customize the levels (and level names) to suite their needs.
|
||||
* For more information on this see the "Custom Log Levels" page:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomLogLevels
|
||||
*
|
||||
* Advanced users may also notice that we're using a bitmask.
|
||||
* This is to allow for custom fine grained logging:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/FineGrainedLogging
|
||||
*
|
||||
* -- Flags --
|
||||
*
|
||||
* Typically you will use the LOG_LEVELS (see below), but the flags may be used directly in certain situations.
|
||||
* For example, say you have a lot of warning log messages, and you wanted to disable them.
|
||||
* However, you still needed to see your error and info log messages.
|
||||
* You could accomplish that with the following:
|
||||
*
|
||||
* static const int ddLogLevel = LOG_FLAG_ERROR | LOG_FLAG_INFO;
|
||||
*
|
||||
* When LOG_LEVEL_DEF is defined as ddLogLevel.
|
||||
*
|
||||
* Flags may also be consulted when writing custom log formatters,
|
||||
* as the DDLogMessage class captures the individual flag that caused the log message to fire.
|
||||
*
|
||||
* -- Levels --
|
||||
*
|
||||
* Log levels are simply the proper bitmask of the flags.
|
||||
*
|
||||
* -- Booleans --
|
||||
*
|
||||
* The booleans may be used when your logging code involves more than one line.
|
||||
* For example:
|
||||
*
|
||||
* if (LOG_VERBOSE) {
|
||||
* for (id sprocket in sprockets)
|
||||
* DDLogVerbose(@"sprocket: %@", [sprocket description])
|
||||
* }
|
||||
*
|
||||
* -- Async --
|
||||
*
|
||||
* Defines the default asynchronous options.
|
||||
* The default philosophy for asynchronous logging is very simple:
|
||||
*
|
||||
* Log messages with errors should be executed synchronously.
|
||||
* After all, an error just occurred. The application could be unstable.
|
||||
*
|
||||
* All other log messages, such as debug output, are executed asynchronously.
|
||||
* After all, if it wasn't an error, then it was just informational output,
|
||||
* or something the application was easily able to recover from.
|
||||
*
|
||||
* -- Changes --
|
||||
*
|
||||
* You are strongly discouraged from modifying this file.
|
||||
* If you do, you make it more difficult on yourself to merge future bug fixes and improvements from the project.
|
||||
* Instead, create your own MyLogging.h or ApplicationNameLogging.h or CompanyLogging.h
|
||||
*
|
||||
* For an example of customizing your logging experience, see the "Custom Log Levels" page:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomLogLevels
|
||||
**/
|
||||
|
||||
#define LOG_FLAG_ERROR (1 << 0) // 0...00001
|
||||
#define LOG_FLAG_WARN (1 << 1) // 0...00010
|
||||
#define LOG_FLAG_INFO (1 << 2) // 0...00100
|
||||
#define LOG_FLAG_DEBUG (1 << 3) // 0...01000
|
||||
#define LOG_FLAG_VERBOSE (1 << 4) // 0...10000
|
||||
|
||||
#define LOG_LEVEL_OFF 0
|
||||
#define LOG_LEVEL_ERROR (LOG_FLAG_ERROR) // 0...00001
|
||||
#define LOG_LEVEL_WARN (LOG_FLAG_ERROR | LOG_FLAG_WARN) // 0...00011
|
||||
#define LOG_LEVEL_INFO (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO) // 0...00111
|
||||
#define LOG_LEVEL_DEBUG (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO | LOG_FLAG_DEBUG) // 0...01111
|
||||
#define LOG_LEVEL_VERBOSE (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO | LOG_FLAG_DEBUG | LOG_FLAG_VERBOSE) // 0...11111
|
||||
#define LOG_LEVEL_ALL 0xFFFFFFFF // 1111....11111 (LOG_LEVEL_VERBOSE plus any other flags)
|
||||
|
||||
#define LOG_ERROR (LOG_LEVEL_DEF & LOG_FLAG_ERROR)
|
||||
#define LOG_WARN (LOG_LEVEL_DEF & LOG_FLAG_WARN)
|
||||
#define LOG_INFO (LOG_LEVEL_DEF & LOG_FLAG_INFO)
|
||||
#define LOG_DEBUG (LOG_LEVEL_DEF & LOG_FLAG_DEBUG)
|
||||
#define LOG_VERBOSE (LOG_LEVEL_DEF & LOG_FLAG_VERBOSE)
|
||||
|
||||
#define LOG_ASYNC_ENABLED YES
|
||||
|
||||
#define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_DEBUG (YES && LOG_ASYNC_ENABLED)
|
||||
#define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED)
|
||||
|
||||
#define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogDebug(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
|
||||
|
||||
#define DDLogCError(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogCWarn(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogCInfo(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogCDebug(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ##__VA_ARGS__)
|
||||
#define DDLogCVerbose(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* The THIS_FILE macro gives you an NSString of the file name.
|
||||
* For simplicity and clarity, the file name does not include the full path or file extension.
|
||||
*
|
||||
* For example: DDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy"
|
||||
**/
|
||||
|
||||
NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
|
||||
|
||||
#define THIS_FILE (DDExtractFileNameWithoutExtension(__FILE__, NO))
|
||||
|
||||
/**
|
||||
* The THIS_METHOD macro gives you the name of the current objective-c method.
|
||||
*
|
||||
* For example: DDLogWarn(@"%@ - Requires non-nil strings", THIS_METHOD) -> @"setMake:model: requires non-nil strings"
|
||||
*
|
||||
* Note: This does NOT work in straight C functions (non objective-c).
|
||||
* Instead you should use the predefined __FUNCTION__ macro.
|
||||
**/
|
||||
|
||||
#define THIS_METHOD NSStringFromSelector(_cmd)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface DDLog : NSObject
|
||||
|
||||
/**
|
||||
* Provides access to the underlying logging queue.
|
||||
* This may be helpful to Logger classes for things like thread synchronization.
|
||||
**/
|
||||
|
||||
+ (dispatch_queue_t)loggingQueue;
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method is used by the macros above.
|
||||
* It is suggested you stick with the macros as they're easier to use.
|
||||
**/
|
||||
|
||||
+ (void)log:(BOOL)synchronous
|
||||
level:(int)level
|
||||
flag:(int)flag
|
||||
context:(int)context
|
||||
file:(const char *)file
|
||||
function:(const char *)function
|
||||
line:(int)line
|
||||
tag:(id)tag
|
||||
format:(NSString *)format, ... __attribute__ ((format (__NSString__, 9, 10)));
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method can be used if you have a prepared va_list.
|
||||
**/
|
||||
|
||||
+ (void)log:(BOOL)asynchronous
|
||||
level:(int)level
|
||||
flag:(int)flag
|
||||
context:(int)context
|
||||
file:(const char *)file
|
||||
function:(const char *)function
|
||||
line:(int)line
|
||||
tag:(id)tag
|
||||
format:(NSString *)format
|
||||
args:(va_list)argList;
|
||||
|
||||
/**
|
||||
* Logging Primitive.
|
||||
*
|
||||
* This method can be used if you manualy prepared DDLogMessage.
|
||||
**/
|
||||
|
||||
+ (void)log:(BOOL)asynchronous
|
||||
message:(DDLogMessage *)logMessage;
|
||||
|
||||
/**
|
||||
* Since logging can be asynchronous, there may be times when you want to flush the logs.
|
||||
* The framework invokes this automatically when the application quits.
|
||||
**/
|
||||
|
||||
+ (void)flushLog;
|
||||
|
||||
/**
|
||||
* Loggers
|
||||
*
|
||||
* In order for your log statements to go somewhere, you should create and add a logger.
|
||||
*
|
||||
* You can add multiple loggers in order to direct your log statements to multiple places.
|
||||
* And each logger can be configured separately.
|
||||
* So you could have, for example, verbose logging to the console, but a concise log file with only warnings & errors.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Adds the logger to the system.
|
||||
*
|
||||
* This is equivalent to invoking [DDLog addLogger:logger withLogLevel:LOG_LEVEL_ALL].
|
||||
**/
|
||||
+ (void)addLogger:(id <DDLogger>)logger;
|
||||
|
||||
/**
|
||||
* Adds the logger to the system.
|
||||
*
|
||||
* The logLevel that you provide here is a preemptive filter (for performance).
|
||||
* That is, the logLevel specified here will be used to filter out logMessages so that
|
||||
* the logger is never even invoked for the messages.
|
||||
*
|
||||
* More information:
|
||||
* When you issue a log statement, the logging framework iterates over each logger,
|
||||
* and checks to see if it should forward the logMessage to the logger.
|
||||
* This check is done using the logLevel parameter passed to this method.
|
||||
*
|
||||
* For example:
|
||||
* [DDLog addLogger:consoleLogger withLogLevel:LOG_LEVEL_VERBOSE];
|
||||
* [DDLog addLogger:fileLogger withLogLevel:LOG_LEVEL_WARN];
|
||||
*
|
||||
* DDLogError(@"oh no"); => gets forwarded to consoleLogger & fileLogger
|
||||
* DDLogInfo(@"hi"); => gets forwarded to consoleLogger only
|
||||
*
|
||||
* It is important to remember that Lumberjack uses a BITMASK.
|
||||
* Many developers & third party frameworks may define extra log levels & flags.
|
||||
* For example:
|
||||
*
|
||||
* #define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000
|
||||
*
|
||||
* So if you specify LOG_LEVEL_VERBOSE to this method, you won't see the framework's trace messages.
|
||||
*
|
||||
* (SOME_FRAMEWORK_LOG_FLAG_TRACE & LOG_LEVEL_VERBOSE) => (01000000 & 00011111) => NO
|
||||
*
|
||||
* Consider passing LOG_LEVEL_ALL to this method, which has all bits set.
|
||||
* You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
|
||||
* except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
|
||||
*
|
||||
* ((LOG_LEVEL_ALL ^ LOG_LEVEL_VERBOSE) | LOG_LEVEL_INFO)
|
||||
**/
|
||||
+ (void)addLogger:(id <DDLogger>)logger withLogLevel:(int)logLevel;
|
||||
|
||||
+ (void)removeLogger:(id <DDLogger>)logger;
|
||||
+ (void)removeAllLoggers;
|
||||
|
||||
+ (NSArray *)allLoggers;
|
||||
|
||||
/**
|
||||
* Registered Dynamic Logging
|
||||
*
|
||||
* These methods allow you to obtain a list of classes that are using registered dynamic logging,
|
||||
* and also provides methods to get and set their log level during run time.
|
||||
**/
|
||||
|
||||
+ (NSArray *)registeredClasses;
|
||||
+ (NSArray *)registeredClassNames;
|
||||
|
||||
+ (int)logLevelForClass:(Class)aClass;
|
||||
+ (int)logLevelForClassWithName:(NSString *)aClassName;
|
||||
|
||||
+ (void)setLogLevel:(int)logLevel forClass:(Class)aClass;
|
||||
+ (void)setLogLevel:(int)logLevel forClassWithName:(NSString *)aClassName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@protocol DDLogger <NSObject>
|
||||
@required
|
||||
|
||||
- (void)logMessage:(DDLogMessage *)logMessage;
|
||||
|
||||
/**
|
||||
* Formatters may optionally be added to any logger.
|
||||
*
|
||||
* If no formatter is set, the logger simply logs the message as it is given in logMessage,
|
||||
* or it may use its own built in formatting style.
|
||||
**/
|
||||
- (id <DDLogFormatter>)logFormatter;
|
||||
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Since logging is asynchronous, adding and removing loggers is also asynchronous.
|
||||
* In other words, the loggers are added and removed at appropriate times with regards to log messages.
|
||||
*
|
||||
* - Loggers will not receive log messages that were executed prior to when they were added.
|
||||
* - Loggers will not receive log messages that were executed after they were removed.
|
||||
*
|
||||
* These methods are executed in the logging thread/queue.
|
||||
* This is the same thread/queue that will execute every logMessage: invocation.
|
||||
* Loggers may use these methods for thread synchronization or other setup/teardown tasks.
|
||||
**/
|
||||
- (void)didAddLogger;
|
||||
- (void)willRemoveLogger;
|
||||
|
||||
/**
|
||||
* Some loggers may buffer IO for optimization purposes.
|
||||
* For example, a database logger may only save occasionaly as the disk IO is slow.
|
||||
* In such loggers, this method should be implemented to flush any pending IO.
|
||||
*
|
||||
* This allows invocations of DDLog's flushLog method to be propogated to loggers that need it.
|
||||
*
|
||||
* Note that DDLog's flushLog method is invoked automatically when the application quits,
|
||||
* and it may be also invoked manually by the developer prior to application crashes, or other such reasons.
|
||||
**/
|
||||
- (void)flush;
|
||||
|
||||
/**
|
||||
* Each logger is executed concurrently with respect to the other loggers.
|
||||
* Thus, a dedicated dispatch queue is used for each logger.
|
||||
* Logger implementations may optionally choose to provide their own dispatch queue.
|
||||
**/
|
||||
- (dispatch_queue_t)loggerQueue;
|
||||
|
||||
/**
|
||||
* If the logger implementation does not choose to provide its own queue,
|
||||
* one will automatically be created for it.
|
||||
* The created queue will receive its name from this method.
|
||||
* This may be helpful for debugging or profiling reasons.
|
||||
**/
|
||||
- (NSString *)loggerName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@protocol DDLogFormatter <NSObject>
|
||||
@required
|
||||
|
||||
/**
|
||||
* Formatters may optionally be added to any logger.
|
||||
* This allows for increased flexibility in the logging environment.
|
||||
* For example, log messages for log files may be formatted differently than log messages for the console.
|
||||
*
|
||||
* For more information about formatters, see the "Custom Formatters" page:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomFormatters
|
||||
*
|
||||
* The formatter may also optionally filter the log message by returning nil,
|
||||
* in which case the logger will not log the message.
|
||||
**/
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* A single formatter instance can be added to multiple loggers.
|
||||
* These methods provides hooks to notify the formatter of when it's added/removed.
|
||||
*
|
||||
* This is primarily for thread-safety.
|
||||
* If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
|
||||
* Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
|
||||
* it could possibly use these hooks to switch to thread-safe versions of the code.
|
||||
**/
|
||||
- (void)didAddToLogger:(id <DDLogger>)logger;
|
||||
- (void)willRemoveFromLogger:(id <DDLogger>)logger;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@protocol DDRegisteredDynamicLogging
|
||||
|
||||
/**
|
||||
* Implement these methods to allow a file's log level to be managed from a central location.
|
||||
*
|
||||
* This is useful if you'd like to be able to change log levels for various parts
|
||||
* of your code from within the running application.
|
||||
*
|
||||
* Imagine pulling up the settings for your application,
|
||||
* and being able to configure the logging level on a per file basis.
|
||||
*
|
||||
* The implementation can be very straight-forward:
|
||||
*
|
||||
* + (int)ddLogLevel
|
||||
* {
|
||||
* return ddLogLevel;
|
||||
* }
|
||||
*
|
||||
* + (void)ddSetLogLevel:(int)logLevel
|
||||
* {
|
||||
* ddLogLevel = logLevel;
|
||||
* }
|
||||
**/
|
||||
|
||||
+ (int)ddLogLevel;
|
||||
+ (void)ddSetLogLevel:(int)logLevel;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The DDLogMessage class encapsulates information about the log message.
|
||||
* If you write custom loggers or formatters, you will be dealing with objects of this class.
|
||||
**/
|
||||
|
||||
enum {
|
||||
DDLogMessageCopyFile = 1 << 0,
|
||||
DDLogMessageCopyFunction = 1 << 1
|
||||
};
|
||||
typedef int DDLogMessageOptions;
|
||||
|
||||
@interface DDLogMessage : NSObject <NSCopying>
|
||||
{
|
||||
|
||||
// The public variables below can be accessed directly (for speed).
|
||||
// For example: logMessage->logLevel
|
||||
|
||||
@public
|
||||
int logLevel;
|
||||
int logFlag;
|
||||
int logContext;
|
||||
NSString *logMsg;
|
||||
NSDate *timestamp;
|
||||
char *file;
|
||||
char *function;
|
||||
int lineNumber;
|
||||
mach_port_t machThreadID;
|
||||
char *queueLabel;
|
||||
NSString *threadName;
|
||||
|
||||
// For 3rd party extensions to the framework, where flags and contexts aren't enough.
|
||||
id tag;
|
||||
|
||||
// For 3rd party extensions that manually create DDLogMessage instances.
|
||||
DDLogMessageOptions options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard init method for a log message object.
|
||||
* Used by the logging primitives. (And the macros use the logging primitives.)
|
||||
*
|
||||
* If you find need to manually create logMessage objects, there is one thing you should be aware of:
|
||||
*
|
||||
* If no flags are passed, the method expects the file and function parameters to be string literals.
|
||||
* That is, it expects the given strings to exist for the duration of the object's lifetime,
|
||||
* and it expects the given strings to be immutable.
|
||||
* In other words, it does not copy these strings, it simply points to them.
|
||||
* This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters,
|
||||
* so it makes sense to optimize and skip the unnecessary allocations.
|
||||
* However, if you need them to be copied you may use the options parameter to specify this.
|
||||
* Options is a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
|
||||
**/
|
||||
- (instancetype)initWithLogMsg:(NSString *)logMsg
|
||||
level:(int)logLevel
|
||||
flag:(int)logFlag
|
||||
context:(int)logContext
|
||||
file:(const char *)file
|
||||
function:(const char *)function
|
||||
line:(int)line
|
||||
tag:(id)tag
|
||||
options:(DDLogMessageOptions)optionsMask;
|
||||
- (instancetype)initWithLogMsg:(NSString *)logMsg
|
||||
level:(int)logLevel
|
||||
flag:(int)logFlag
|
||||
context:(int)logContext
|
||||
file:(const char *)file
|
||||
function:(const char *)function
|
||||
line:(int)line
|
||||
tag:(id)tag
|
||||
options:(DDLogMessageOptions)optionsMask
|
||||
timestamp:(NSDate *)aTimestamp;
|
||||
|
||||
/**
|
||||
* Returns the threadID as it appears in NSLog.
|
||||
* That is, it is a hexadecimal value which is calculated from the machThreadID.
|
||||
**/
|
||||
- (NSString *)threadID;
|
||||
|
||||
/**
|
||||
* Convenience property to get just the file name, as the file variable is generally the full file path.
|
||||
* This method does not include the file extension, which is generally unwanted for logging purposes.
|
||||
**/
|
||||
- (NSString *)fileName;
|
||||
|
||||
/**
|
||||
* Returns the function variable in NSString form.
|
||||
**/
|
||||
- (NSString *)methodName;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* The DDLogger protocol specifies that an optional formatter can be added to a logger.
|
||||
* Most (but not all) loggers will want to support formatters.
|
||||
*
|
||||
* However, writting getters and setters in a thread safe manner,
|
||||
* while still maintaining maximum speed for the logging process, is a difficult task.
|
||||
*
|
||||
* To do it right, the implementation of the getter/setter has strict requiremenets:
|
||||
* - Must NOT require the logMessage method to acquire a lock.
|
||||
* - Must NOT require the logMessage method to access an atomic property (also a lock of sorts).
|
||||
*
|
||||
* To simplify things, an abstract logger is provided that implements the getter and setter.
|
||||
*
|
||||
* Logger implementations may simply extend this class,
|
||||
* and they can ACCESS THE FORMATTER VARIABLE DIRECTLY from within their logMessage method!
|
||||
**/
|
||||
|
||||
@interface DDAbstractLogger : NSObject <DDLogger>
|
||||
{
|
||||
id <DDLogFormatter> formatter;
|
||||
|
||||
dispatch_queue_t loggerQueue;
|
||||
}
|
||||
|
||||
- (id <DDLogFormatter>)logFormatter;
|
||||
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
// For thread-safety assertions
|
||||
- (BOOL)isOnGlobalLoggingQueue;
|
||||
- (BOOL)isOnInternalLoggerQueue;
|
||||
|
||||
@end
|
||||
1253
Pods/CocoaLumberjack/Lumberjack/DDLog.m
generated
Executable file
1253
Pods/CocoaLumberjack/Lumberjack/DDLog.m
generated
Executable file
File diff suppressed because it is too large
Load diff
188
Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h
generated
Executable file
188
Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h
generated
Executable file
|
|
@ -0,0 +1,188 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIColor.h> // iOS
|
||||
#elif !defined (COCOAPODS_POD_AVAILABLE_CocoaLumberjack_CLI)
|
||||
#import <AppKit/NSColor.h> // OS X with AppKit
|
||||
#else
|
||||
#import "CLIColor.h" // OS X without AppKit
|
||||
#endif
|
||||
|
||||
#import "DDLog.h"
|
||||
|
||||
#define LOG_CONTEXT_ALL INT_MAX
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides a logger for Terminal output or Xcode console output,
|
||||
* depending on where you are running your code.
|
||||
*
|
||||
* As described in the "Getting Started" page,
|
||||
* the traditional NSLog() function directs it's output to two places:
|
||||
*
|
||||
* - Apple System Log (so it shows up in Console.app)
|
||||
* - StdErr (if stderr is a TTY, so log statements show up in Xcode console)
|
||||
*
|
||||
* To duplicate NSLog() functionality you can simply add this logger and an asl logger.
|
||||
* However, if you instead choose to use file logging (for faster performance),
|
||||
* you may choose to use only a file logger and a tty logger.
|
||||
**/
|
||||
|
||||
@interface DDTTYLogger : DDAbstractLogger <DDLogger>
|
||||
{
|
||||
NSUInteger calendarUnitFlags;
|
||||
|
||||
NSString *appName;
|
||||
char *app;
|
||||
size_t appLen;
|
||||
|
||||
NSString *processID;
|
||||
char *pid;
|
||||
size_t pidLen;
|
||||
|
||||
BOOL colorsEnabled;
|
||||
NSMutableArray *colorProfilesArray;
|
||||
NSMutableDictionary *colorProfilesDict;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
/* Inherited from the DDLogger protocol:
|
||||
*
|
||||
* Formatters may optionally be added to any logger.
|
||||
*
|
||||
* If no formatter is set, the logger simply logs the message as it is given in logMessage,
|
||||
* or it may use its own built in formatting style.
|
||||
*
|
||||
* More information about formatters can be found here:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomFormatters
|
||||
*
|
||||
* The actual implementation of these methods is inherited from DDAbstractLogger.
|
||||
|
||||
- (id <DDLogFormatter>)logFormatter;
|
||||
- (void)setLogFormatter:(id <DDLogFormatter>)formatter;
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Want to use different colors for different log levels?
|
||||
* Enable this property.
|
||||
*
|
||||
* If you run the application via the Terminal (not Xcode),
|
||||
* the logger will map colors to xterm-256color or xterm-color (if available).
|
||||
*
|
||||
* Xcode does NOT natively support colors in the Xcode debugging console.
|
||||
* You'll need to install the XcodeColors plugin to see colors in the Xcode console.
|
||||
* https://github.com/robbiehanson/XcodeColors
|
||||
*
|
||||
* The default value is NO.
|
||||
**/
|
||||
@property (readwrite, assign) BOOL colorsEnabled;
|
||||
|
||||
/**
|
||||
* When using a custom formatter you can set the logMessage method not to append
|
||||
* '\n' character after each output. This allows for some greater flexibility with
|
||||
* custom formatters. Default value is YES.
|
||||
**/
|
||||
|
||||
@property (readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
|
||||
|
||||
/**
|
||||
* The default color set (foregroundColor, backgroundColor) is:
|
||||
*
|
||||
* - LOG_FLAG_ERROR = (red, nil)
|
||||
* - LOG_FLAG_WARN = (orange, nil)
|
||||
*
|
||||
* You can customize the colors however you see fit.
|
||||
* Please note that you are passing a flag, NOT a level.
|
||||
*
|
||||
* GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_FLAG_INFO]; // <- Good :)
|
||||
* BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_LEVEL_INFO]; // <- BAD! :(
|
||||
*
|
||||
* LOG_FLAG_INFO = 0...00100
|
||||
* LOG_LEVEL_INFO = 0...00111 <- Would match LOG_FLAG_INFO and LOG_FLAG_WARN and LOG_FLAG_ERROR
|
||||
*
|
||||
* If you run the application within Xcode, then the XcodeColors plugin is required.
|
||||
*
|
||||
* If you run the application from a shell, then DDTTYLogger will automatically map the given color to
|
||||
* the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.)
|
||||
*
|
||||
* This method invokes setForegroundColor:backgroundColor:forFlag:context: and applies it to `LOG_CONTEXT_ALL`.
|
||||
**/
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask;
|
||||
#elif !defined (COCOAPODS_POD_AVAILABLE_CocoaLumberjack_CLI)
|
||||
- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask;
|
||||
#else
|
||||
- (void)setForegroundColor:(CLIColor *)txtColor backgroundColor:(CLIColor *)bgColor forFlag:(int)mask;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
|
||||
*
|
||||
* A logging context is often used to identify log messages coming from a 3rd party framework,
|
||||
* although logging context's can be used for many different functions.
|
||||
*
|
||||
* Use LOG_CONTEXT_ALL to set the deafult color for all contexts that have no specific color set defined.
|
||||
*
|
||||
* Logging context's are explained in further detail here:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomContext
|
||||
**/
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask context:(int)ctxt;
|
||||
#elif !defined (COCOAPODS_POD_AVAILABLE_CocoaLumberjack_CLI)
|
||||
- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask context:(int)ctxt;
|
||||
#else
|
||||
- (void)setForegroundColor:(CLIColor *)txtColor backgroundColor:(CLIColor *)bgColor forFlag:(int)mask context:(int)ctxt;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile.
|
||||
* For example, you could do something like this:
|
||||
*
|
||||
* static NSString *const PurpleTag = @"PurpleTag";
|
||||
*
|
||||
* #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
|
||||
*
|
||||
* And then in your applicationDidFinishLaunching, or wherever you configure Lumberjack:
|
||||
*
|
||||
* #if TARGET_OS_IPHONE
|
||||
* UIColor *purple = [UIColor colorWithRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
|
||||
* #else
|
||||
* NSColor *purple = [NSColor colorWithCalibratedRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0];
|
||||
*
|
||||
* Note: For CLI OS X projects that don't link with AppKit use CLIColor objects instead
|
||||
*
|
||||
* [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
|
||||
* [DDLog addLogger:[DDTTYLogger sharedInstance]];
|
||||
*
|
||||
* This would essentially give you a straight NSLog replacement that prints in purple:
|
||||
*
|
||||
* DDLogPurple(@"I'm a purple log message!");
|
||||
**/
|
||||
#if TARGET_OS_IPHONE
|
||||
- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forTag:(id <NSCopying>)tag;
|
||||
#elif !defined (COCOAPODS_POD_AVAILABLE_CocoaLumberjack_CLI)
|
||||
- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forTag:(id <NSCopying>)tag;
|
||||
#else
|
||||
- (void)setForegroundColor:(CLIColor *)txtColor backgroundColor:(CLIColor *)bgColor forTag:(id <NSCopying>)tag;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Clearing color profiles.
|
||||
**/
|
||||
- (void)clearColorsForFlag:(int)mask;
|
||||
- (void)clearColorsForFlag:(int)mask context:(int)context;
|
||||
- (void)clearColorsForTag:(id <NSCopying>)tag;
|
||||
- (void)clearColorsForAllFlags;
|
||||
- (void)clearColorsForAllTags;
|
||||
- (void)clearAllColors;
|
||||
|
||||
@end
|
||||
1510
Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m
generated
Executable file
1510
Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m
generated
Executable file
File diff suppressed because it is too large
Load diff
63
Pods/CocoaLumberjack/Lumberjack/Extensions/DDContextFilterLogFormatter.h
generated
Normal file
63
Pods/CocoaLumberjack/Lumberjack/Extensions/DDContextFilterLogFormatter.h
generated
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "DDLog.h"
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" page.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides a log formatter that filters log statements from a logging context not on the whitelist.
|
||||
*
|
||||
* A log formatter can be added to any logger to format and/or filter its output.
|
||||
* You can learn more about log formatters here:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomFormatters
|
||||
*
|
||||
* You can learn more about logging context's here:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomContext
|
||||
*
|
||||
* But here's a quick overview / refresher:
|
||||
*
|
||||
* Every log statement has a logging context.
|
||||
* These come from the underlying logging macros defined in DDLog.h.
|
||||
* The default logging context is zero.
|
||||
* You can define multiple logging context's for use in your application.
|
||||
* For example, logically separate parts of your app each have a different logging context.
|
||||
* Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context.
|
||||
**/
|
||||
@interface DDContextWhitelistFilterLogFormatter : NSObject <DDLogFormatter>
|
||||
|
||||
- (id)init;
|
||||
|
||||
- (void)addToWhitelist:(int)loggingContext;
|
||||
- (void)removeFromWhitelist:(int)loggingContext;
|
||||
|
||||
- (NSArray *)whitelist;
|
||||
|
||||
- (BOOL)isOnWhitelist:(int)loggingContext;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* This class provides a log formatter that filters log statements from a logging context on the blacklist.
|
||||
**/
|
||||
@interface DDContextBlacklistFilterLogFormatter : NSObject <DDLogFormatter>
|
||||
|
||||
- (id)init;
|
||||
|
||||
- (void)addToBlacklist:(int)loggingContext;
|
||||
- (void)removeFromBlacklist:(int)loggingContext;
|
||||
|
||||
- (NSArray *)blacklist;
|
||||
|
||||
- (BOOL)isOnBlacklist:(int)loggingContext;
|
||||
|
||||
@end
|
||||
191
Pods/CocoaLumberjack/Lumberjack/Extensions/DDContextFilterLogFormatter.m
generated
Normal file
191
Pods/CocoaLumberjack/Lumberjack/Extensions/DDContextFilterLogFormatter.m
generated
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
#import "DDContextFilterLogFormatter.h"
|
||||
#import <libkern/OSAtomic.h>
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
**/
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
@interface DDLoggingContextSet : NSObject
|
||||
|
||||
- (void)addToSet:(int)loggingContext;
|
||||
- (void)removeFromSet:(int)loggingContext;
|
||||
|
||||
- (NSArray *)currentSet;
|
||||
|
||||
- (BOOL)isInSet:(int)loggingContext;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@implementation DDContextWhitelistFilterLogFormatter
|
||||
{
|
||||
DDLoggingContextSet *contextSet;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
contextSet = [[DDLoggingContextSet alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)addToWhitelist:(int)loggingContext
|
||||
{
|
||||
[contextSet addToSet:loggingContext];
|
||||
}
|
||||
|
||||
- (void)removeFromWhitelist:(int)loggingContext
|
||||
{
|
||||
[contextSet removeFromSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSArray *)whitelist
|
||||
{
|
||||
return [contextSet currentSet];
|
||||
}
|
||||
|
||||
- (BOOL)isOnWhitelist:(int)loggingContext
|
||||
{
|
||||
return [contextSet isInSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage
|
||||
{
|
||||
if ([self isOnWhitelist:logMessage->logContext])
|
||||
return logMessage->logMsg;
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@implementation DDContextBlacklistFilterLogFormatter
|
||||
{
|
||||
DDLoggingContextSet *contextSet;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
contextSet = [[DDLoggingContextSet alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)addToBlacklist:(int)loggingContext
|
||||
{
|
||||
[contextSet addToSet:loggingContext];
|
||||
}
|
||||
|
||||
- (void)removeFromBlacklist:(int)loggingContext
|
||||
{
|
||||
[contextSet removeFromSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSArray *)blacklist
|
||||
{
|
||||
return [contextSet currentSet];
|
||||
}
|
||||
|
||||
- (BOOL)isOnBlacklist:(int)loggingContext
|
||||
{
|
||||
return [contextSet isInSet:loggingContext];
|
||||
}
|
||||
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage
|
||||
{
|
||||
if ([self isOnBlacklist:logMessage->logContext])
|
||||
return nil;
|
||||
else
|
||||
return logMessage->logMsg;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark -
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@implementation DDLoggingContextSet
|
||||
{
|
||||
OSSpinLock lock;
|
||||
NSMutableSet *set;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
set = [[NSMutableSet alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)addToSet:(int)loggingContext
|
||||
{
|
||||
OSSpinLockLock(&lock);
|
||||
{
|
||||
[set addObject:@(loggingContext)];
|
||||
}
|
||||
OSSpinLockUnlock(&lock);
|
||||
}
|
||||
|
||||
- (void)removeFromSet:(int)loggingContext
|
||||
{
|
||||
OSSpinLockLock(&lock);
|
||||
{
|
||||
[set removeObject:@(loggingContext)];
|
||||
}
|
||||
OSSpinLockUnlock(&lock);
|
||||
}
|
||||
|
||||
- (NSArray *)currentSet
|
||||
{
|
||||
NSArray *result = nil;
|
||||
|
||||
OSSpinLockLock(&lock);
|
||||
{
|
||||
result = [set allObjects];
|
||||
}
|
||||
OSSpinLockUnlock(&lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (BOOL)isInSet:(int)loggingContext
|
||||
{
|
||||
BOOL result = NO;
|
||||
|
||||
OSSpinLockLock(&lock);
|
||||
{
|
||||
result = [set containsObject:@(loggingContext)];
|
||||
}
|
||||
OSSpinLockUnlock(&lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
128
Pods/CocoaLumberjack/Lumberjack/Extensions/DDDispatchQueueLogFormatter.h
generated
Normal file
128
Pods/CocoaLumberjack/Lumberjack/Extensions/DDDispatchQueueLogFormatter.h
generated
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <libkern/OSAtomic.h>
|
||||
#import "DDLog.h"
|
||||
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" page.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id.
|
||||
*
|
||||
* A log formatter can be added to any logger to format and/or filter its output.
|
||||
* You can learn more about log formatters here:
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomFormatters
|
||||
*
|
||||
* A typical NSLog (or DDTTYLogger) prints detailed info as [<process_id>:<thread_id>].
|
||||
* For example:
|
||||
*
|
||||
* 2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here
|
||||
*
|
||||
* Where:
|
||||
* - 19928 = process id
|
||||
* - 5207 = thread id (mach_thread_id printed in hex)
|
||||
*
|
||||
* When using grand central dispatch (GCD), this information is less useful.
|
||||
* This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool.
|
||||
* For example:
|
||||
*
|
||||
* 2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue
|
||||
* 2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue
|
||||
* 2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue
|
||||
*
|
||||
* This formatter allows you to replace the standard [box:info] with the dispatch_queue name.
|
||||
* For example:
|
||||
*
|
||||
* 2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue
|
||||
* 2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue
|
||||
* 2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue
|
||||
*
|
||||
* If the dispatch_queue doesn't have a set name, then it falls back to the thread name.
|
||||
* If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal).
|
||||
*
|
||||
* Note: If manually creating your own background threads (via NSThread/alloc/init or NSThread/detachNeThread),
|
||||
* you can use [[NSThread currentThread] setName:(NSString *)].
|
||||
**/
|
||||
@interface DDDispatchQueueLogFormatter : NSObject <DDLogFormatter> {
|
||||
@protected
|
||||
|
||||
NSString *dateFormatString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard init method.
|
||||
* Configure using properties as desired.
|
||||
**/
|
||||
- (id)init;
|
||||
|
||||
/**
|
||||
* The minQueueLength restricts the minimum size of the [detail box].
|
||||
* If the minQueueLength is set to 0, there is no restriction.
|
||||
*
|
||||
* For example, say a dispatch_queue has a label of "diskIO":
|
||||
*
|
||||
* If the minQueueLength is 0: [diskIO]
|
||||
* If the minQueueLength is 4: [diskIO]
|
||||
* If the minQueueLength is 5: [diskIO]
|
||||
* If the minQueueLength is 6: [diskIO]
|
||||
* If the minQueueLength is 7: [diskIO ]
|
||||
* If the minQueueLength is 8: [diskIO ]
|
||||
*
|
||||
* The default minQueueLength is 0 (no minimum, so [detail box] won't be padded).
|
||||
*
|
||||
* If you want every [detail box] to have the exact same width,
|
||||
* set both minQueueLength and maxQueueLength to the same value.
|
||||
**/
|
||||
@property (assign, atomic) NSUInteger minQueueLength;
|
||||
|
||||
/**
|
||||
* The maxQueueLength restricts the number of characters that will be inside the [detail box].
|
||||
* If the maxQueueLength is 0, there is no restriction.
|
||||
*
|
||||
* For example, say a dispatch_queue has a label of "diskIO":
|
||||
*
|
||||
* If the maxQueueLength is 0: [diskIO]
|
||||
* If the maxQueueLength is 4: [disk]
|
||||
* If the maxQueueLength is 5: [diskI]
|
||||
* If the maxQueueLength is 6: [diskIO]
|
||||
* If the maxQueueLength is 7: [diskIO]
|
||||
* If the maxQueueLength is 8: [diskIO]
|
||||
*
|
||||
* The default maxQueueLength is 0 (no maximum, so [detail box] won't be truncated).
|
||||
*
|
||||
* If you want every [detail box] to have the exact same width,
|
||||
* set both minQueueLength and maxQueueLength to the same value.
|
||||
**/
|
||||
@property (assign, atomic) NSUInteger maxQueueLength;
|
||||
|
||||
/**
|
||||
* Sometimes queue labels have long names like "com.apple.main-queue",
|
||||
* but you'd prefer something shorter like simply "main".
|
||||
*
|
||||
* This method allows you to set such preferred replacements.
|
||||
* The above example is set by default.
|
||||
*
|
||||
* To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter.
|
||||
**/
|
||||
- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel;
|
||||
- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* Method declarations that make it easier to extend/modify DDDispatchQueueLogFormatter
|
||||
**/
|
||||
@interface DDDispatchQueueLogFormatter (OverridableMethods)
|
||||
|
||||
- (NSString *)stringFromDate:(NSDate *)date;
|
||||
- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage;
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
|
||||
|
||||
@end
|
||||
|
||||
260
Pods/CocoaLumberjack/Lumberjack/Extensions/DDDispatchQueueLogFormatter.m
generated
Normal file
260
Pods/CocoaLumberjack/Lumberjack/Extensions/DDDispatchQueueLogFormatter.m
generated
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
#import "DDDispatchQueueLogFormatter.h"
|
||||
#import <libkern/OSAtomic.h>
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" wiki.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
**/
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
|
||||
@implementation DDDispatchQueueLogFormatter
|
||||
{
|
||||
int32_t atomicLoggerCount;
|
||||
NSDateFormatter *threadUnsafeDateFormatter; // Use [self stringFromDate]
|
||||
|
||||
OSSpinLock lock;
|
||||
|
||||
NSUInteger _minQueueLength; // _prefix == Only access via atomic property
|
||||
NSUInteger _maxQueueLength; // _prefix == Only access via atomic property
|
||||
NSMutableDictionary *_replacements; // _prefix == Only access from within spinlock
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
dateFormatString = @"yyyy-MM-dd HH:mm:ss:SSS";
|
||||
|
||||
atomicLoggerCount = 0;
|
||||
threadUnsafeDateFormatter = nil;
|
||||
|
||||
_minQueueLength = 0;
|
||||
_maxQueueLength = 0;
|
||||
_replacements = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Set default replacements:
|
||||
|
||||
_replacements[@"com.apple.main-thread"] = @"main";
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark Configuration
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@synthesize minQueueLength = _minQueueLength;
|
||||
@synthesize maxQueueLength = _maxQueueLength;
|
||||
|
||||
- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel
|
||||
{
|
||||
NSString *result = nil;
|
||||
|
||||
OSSpinLockLock(&lock);
|
||||
{
|
||||
result = _replacements[longLabel];
|
||||
}
|
||||
OSSpinLockUnlock(&lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel
|
||||
{
|
||||
OSSpinLockLock(&lock);
|
||||
{
|
||||
if (shortLabel)
|
||||
_replacements[longLabel] = shortLabel;
|
||||
else
|
||||
[_replacements removeObjectForKey:longLabel];
|
||||
}
|
||||
OSSpinLockUnlock(&lock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma mark DDLogFormatter
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (NSString *)stringFromDate:(NSDate *)date
|
||||
{
|
||||
int32_t loggerCount = OSAtomicAdd32(0, &atomicLoggerCount);
|
||||
|
||||
NSString *calendarIdentifier = nil;
|
||||
#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
|
||||
calendarIdentifier = NSCalendarIdentifierGregorian;
|
||||
#else
|
||||
calendarIdentifier = NSGregorianCalendar;
|
||||
#endif
|
||||
|
||||
if (loggerCount <= 1)
|
||||
{
|
||||
// Single-threaded mode.
|
||||
|
||||
if (threadUnsafeDateFormatter == nil)
|
||||
{
|
||||
threadUnsafeDateFormatter = [[NSDateFormatter alloc] init];
|
||||
[threadUnsafeDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
|
||||
[threadUnsafeDateFormatter setDateFormat:dateFormatString];
|
||||
}
|
||||
|
||||
[threadUnsafeDateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier]];
|
||||
return [threadUnsafeDateFormatter stringFromDate:date];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multi-threaded mode.
|
||||
// NSDateFormatter is NOT thread-safe.
|
||||
|
||||
NSString *key = @"DispatchQueueLogFormatter_NSDateFormatter";
|
||||
|
||||
NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
|
||||
NSDateFormatter *dateFormatter = threadDictionary[key];
|
||||
|
||||
if (dateFormatter == nil)
|
||||
{
|
||||
dateFormatter = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
|
||||
[dateFormatter setDateFormat:dateFormatString];
|
||||
|
||||
threadDictionary[key] = dateFormatter;
|
||||
}
|
||||
|
||||
[dateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier]];
|
||||
return [dateFormatter stringFromDate:date];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage
|
||||
{
|
||||
// As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue
|
||||
|
||||
NSUInteger minQueueLength = self.minQueueLength;
|
||||
NSUInteger maxQueueLength = self.maxQueueLength;
|
||||
|
||||
// Get the name of the queue, thread, or machID (whichever we are to use).
|
||||
|
||||
NSString *queueThreadLabel = nil;
|
||||
|
||||
BOOL useQueueLabel = YES;
|
||||
BOOL useThreadName = NO;
|
||||
|
||||
if (logMessage->queueLabel)
|
||||
{
|
||||
// If you manually create a thread, it's dispatch_queue will have one of the thread names below.
|
||||
// Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID.
|
||||
|
||||
char *names[] = { "com.apple.root.low-priority",
|
||||
"com.apple.root.default-priority",
|
||||
"com.apple.root.high-priority",
|
||||
"com.apple.root.low-overcommit-priority",
|
||||
"com.apple.root.default-overcommit-priority",
|
||||
"com.apple.root.high-overcommit-priority" };
|
||||
|
||||
int length = sizeof(names) / sizeof(char *);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (strcmp(logMessage->queueLabel, names[i]) == 0)
|
||||
{
|
||||
useQueueLabel = NO;
|
||||
useThreadName = [logMessage->threadName length] > 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
useQueueLabel = NO;
|
||||
useThreadName = [logMessage->threadName length] > 0;
|
||||
}
|
||||
|
||||
if (useQueueLabel || useThreadName)
|
||||
{
|
||||
NSString *fullLabel;
|
||||
NSString *abrvLabel;
|
||||
|
||||
if (useQueueLabel)
|
||||
fullLabel = @(logMessage->queueLabel);
|
||||
else
|
||||
fullLabel = logMessage->threadName;
|
||||
|
||||
OSSpinLockLock(&lock);
|
||||
{
|
||||
abrvLabel = _replacements[fullLabel];
|
||||
}
|
||||
OSSpinLockUnlock(&lock);
|
||||
|
||||
if (abrvLabel)
|
||||
queueThreadLabel = abrvLabel;
|
||||
else
|
||||
queueThreadLabel = fullLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
queueThreadLabel = [NSString stringWithFormat:@"%x", logMessage->machThreadID];
|
||||
}
|
||||
|
||||
// Now use the thread label in the output
|
||||
|
||||
NSUInteger labelLength = [queueThreadLabel length];
|
||||
|
||||
// labelLength > maxQueueLength : truncate
|
||||
// labelLength < minQueueLength : padding
|
||||
// : exact
|
||||
|
||||
if ((maxQueueLength > 0) && (labelLength > maxQueueLength))
|
||||
{
|
||||
// Truncate
|
||||
|
||||
return [queueThreadLabel substringToIndex:maxQueueLength];
|
||||
}
|
||||
else if (labelLength < minQueueLength)
|
||||
{
|
||||
// Padding
|
||||
|
||||
NSUInteger numSpaces = minQueueLength - labelLength;
|
||||
|
||||
char spaces[numSpaces + 1];
|
||||
memset(spaces, ' ', numSpaces);
|
||||
spaces[numSpaces] = '\0';
|
||||
|
||||
return [NSString stringWithFormat:@"%@%s", queueThreadLabel, spaces];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Exact
|
||||
|
||||
return queueThreadLabel;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage
|
||||
{
|
||||
NSString *timestamp = [self stringFromDate:(logMessage->timestamp)];
|
||||
NSString *queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage];
|
||||
|
||||
return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, queueThreadLabel, logMessage->logMsg];
|
||||
}
|
||||
|
||||
- (void)didAddToLogger:(id <DDLogger>)logger
|
||||
{
|
||||
OSAtomicIncrement32(&atomicLoggerCount);
|
||||
}
|
||||
|
||||
- (void)willRemoveFromLogger:(id <DDLogger>)logger
|
||||
{
|
||||
OSAtomicDecrement32(&atomicLoggerCount);
|
||||
}
|
||||
|
||||
@end
|
||||
30
Pods/CocoaLumberjack/Lumberjack/Extensions/DDMultiFormatter.h
generated
Normal file
30
Pods/CocoaLumberjack/Lumberjack/Extensions/DDMultiFormatter.h
generated
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "DDLog.h"
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" page.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
*
|
||||
*
|
||||
* This formatter can be used to chain different formatters together.
|
||||
* The log message will processed in the order of the formatters added.
|
||||
**/
|
||||
|
||||
@interface DDMultiFormatter : NSObject <DDLogFormatter>
|
||||
|
||||
/**
|
||||
* Array of chained formatters
|
||||
*/
|
||||
@property (readonly) NSArray *formatters;
|
||||
|
||||
- (void)addFormatter:(id<DDLogFormatter>)formatter;
|
||||
- (void)removeFormatter:(id<DDLogFormatter>)formatter;
|
||||
- (void)removeAllFormatters;
|
||||
- (BOOL)isFormattingWithFormatter:(id<DDLogFormatter>)formatter;
|
||||
|
||||
@end
|
||||
132
Pods/CocoaLumberjack/Lumberjack/Extensions/DDMultiFormatter.m
generated
Normal file
132
Pods/CocoaLumberjack/Lumberjack/Extensions/DDMultiFormatter.m
generated
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#import "DDMultiFormatter.h"
|
||||
|
||||
/**
|
||||
* Welcome to Cocoa Lumberjack!
|
||||
*
|
||||
* The project page has a wealth of documentation if you have any questions.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack
|
||||
*
|
||||
* If you're new to the project you may wish to read the "Getting Started" page.
|
||||
* https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
|
||||
**/
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Compiling for iOS
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 // iOS 6.0 or later
|
||||
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
|
||||
#else // iOS 5.X or earlier
|
||||
#define NEEDS_DISPATCH_RETAIN_RELEASE 1
|
||||
#endif
|
||||
#else
|
||||
// Compiling for Mac OS X
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 // Mac OS X 10.8 or later
|
||||
#define NEEDS_DISPATCH_RETAIN_RELEASE 0
|
||||
#else // Mac OS X 10.7 or earlier
|
||||
#define NEEDS_DISPATCH_RETAIN_RELEASE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if ! __has_feature(objc_arc)
|
||||
#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
|
||||
#endif
|
||||
|
||||
|
||||
@interface DDMultiFormatter ()
|
||||
|
||||
- (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation DDMultiFormatter {
|
||||
dispatch_queue_t _queue;
|
||||
NSMutableArray *_formatters;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
||||
_queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", DISPATCH_QUEUE_CONCURRENT);
|
||||
#else
|
||||
_queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", NULL);
|
||||
#endif
|
||||
_formatters = [NSMutableArray new];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#if NEEDS_DISPATCH_RETAIN_RELEASE
|
||||
- (void)dealloc {
|
||||
dispatch_release(_queue);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark Processing
|
||||
|
||||
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
|
||||
__block NSString *line = logMessage->logMsg;
|
||||
|
||||
dispatch_sync(_queue, ^{
|
||||
for (id<DDLogFormatter> formatter in _formatters) {
|
||||
DDLogMessage *message = [self logMessageForLine:line originalMessage:logMessage];
|
||||
line = [formatter formatLogMessage:message];
|
||||
|
||||
if (!line) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
- (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message {
|
||||
DDLogMessage *newMessage = [message copy];
|
||||
newMessage->logMsg = line;
|
||||
return newMessage;
|
||||
}
|
||||
|
||||
#pragma mark Formatters
|
||||
|
||||
- (NSArray *)formatters {
|
||||
__block NSArray *formatters;
|
||||
|
||||
dispatch_sync(_queue, ^{
|
||||
formatters = [_formatters copy];
|
||||
});
|
||||
|
||||
return formatters;
|
||||
}
|
||||
|
||||
- (void)addFormatter:(id<DDLogFormatter>)formatter {
|
||||
dispatch_barrier_async(_queue, ^{
|
||||
[_formatters addObject:formatter];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeFormatter:(id<DDLogFormatter>)formatter {
|
||||
dispatch_barrier_async(_queue, ^{
|
||||
[_formatters removeObject:formatter];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeAllFormatters {
|
||||
dispatch_barrier_async(_queue, ^{
|
||||
[_formatters removeAllObjects];
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isFormattingWithFormatter:(id<DDLogFormatter>)formatter {
|
||||
__block BOOL hasFormatter;
|
||||
|
||||
dispatch_sync(_queue, ^{
|
||||
hasFormatter = [_formatters containsObject:formatter];
|
||||
});
|
||||
|
||||
return hasFormatter;
|
||||
}
|
||||
|
||||
@end
|
||||
7
Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt
generated
Normal file
7
Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
This folder contains some sample formatters that may be helpful.
|
||||
|
||||
Feel free to change them, extend them, or use them as the basis for your own custom formatter(s).
|
||||
|
||||
More information about creating your own custom formatters can be found on the wiki:
|
||||
https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomFormatters
|
||||
|
||||
81
Pods/CocoaLumberjack/README.md
generated
Normal file
81
Pods/CocoaLumberjack/README.md
generated
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<p align="center" >
|
||||
<img src="LumberjackLogo.png" title="Lumberjack logo" float=left>
|
||||
</p>
|
||||
|
||||
CocoaLumberjack
|
||||
===============
|
||||
[](https://travis-ci.org/CocoaLumberjack/CocoaLumberjack)
|
||||
[](http://cocoadocs.org/docsets/CocoaLumberjack/)
|
||||
[](http://cocoadocs.org/docsets/CocoaLumberjack/)
|
||||
[](http://opensource.org/licenses/BSD-3-Clause)
|
||||
[](https://www.versioneye.com/objective-c/cocoalumberjack/references)
|
||||
|
||||
**CocoaLumberjack** is a fast & simple, yet powerful & flexible logging framework for Mac and iOS.
|
||||
|
||||
#### Lumberjack is Fast & Simple, yet Powerful & Flexible.
|
||||
|
||||
It is similar in concept to other popular logging frameworks such as log4j, yet is designed specifically for Objective-C, and takes advantage of features such as multi-threading, grand central dispatch (if available), lockless atomic operations, and the dynamic nature of the Objective-C runtime.
|
||||
|
||||
#### Lumberjack is Fast
|
||||
|
||||
In most cases it is an order of magnitude faster than NSLog.
|
||||
|
||||
#### Lumberjack is Simple
|
||||
|
||||
It takes as little as a single line of code to configure lumberjack when your application launches. Then simply replace your NSLog statements with DDLog statements and that's about it. (And the DDLog macros have the exact same format and syntax as NSLog, so it's super easy.)
|
||||
|
||||
#### Lumberjack is Powerful:
|
||||
|
||||
One log statement can be sent to multiple loggers, meaning you can log to a file and the console simultaneously. Want more? Create your own loggers (it's easy) and send your log statements over the network. Or to a database or distributed file system. The sky is the limit.
|
||||
|
||||
#### Lumberjack is Flexible:
|
||||
|
||||
Configure your logging however you want. Change log levels per file (perfect for debugging). Change log levels per logger (verbose console, but concise log file). Change log levels per xcode configuration (verbose debug, but concise release). Have your log statements compiled out of the release build. Customize the number of log levels for your application. Add your own fine-grained logging. Dynamically change log levels during runtime. Choose how & when you want your log files to be rolled. Upload your log files to a central server. Compress archived log files to save disk space...
|
||||
|
||||
### This framework is for you if:
|
||||
|
||||
- You're looking for a way to track down that impossible-to-reproduce bug that keeps popping up in the field.
|
||||
- You're frustrated with the super short console log on the iPhone.
|
||||
- You're looking to take your application to the next level in terms of support and stability.
|
||||
- You're looking for an enterprise level logging solution for your application (Mac or iPhone).
|
||||
|
||||
### How to get started
|
||||
- install via [CocoaPods](http://cocoapods.org)
|
||||
|
||||
```ruby
|
||||
platform :ios, '6.1'
|
||||
pod 'CocoaLumberjack'
|
||||
```
|
||||
- read the [Getting started](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted) guide, check out the [FAQ](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/FAQ) section or the other [docs](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki)
|
||||
- if you find issues or want to suggest improvements, create an issue or a pull request
|
||||
- for all kinds of questions involving CocoaLumberjack, use the [Google group](http://groups.google.com/group/cocoalumberjack) or StackOverflow (use [#lumberjack](http://stackoverflow.com/questions/tagged/lumberjack)).
|
||||
|
||||
### Documentation
|
||||
- **[Get started using Lumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted)**<br/>
|
||||
- [Different log levels for Debug and Release builds](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/XcodeTricks)<br/>
|
||||
- [Different log levels for each logger](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/PerLoggerLogLevels)<br/>
|
||||
- [Use colors in the Xcode debugging console](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/XcodeColors)<br/>
|
||||
- [Write your own custom formatters](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomFormatters)<br/>
|
||||
- [FAQ](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/FAQ)<br/>
|
||||
- [Analysis of performance with benchmarks](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/Performance)<br/>
|
||||
- [Common issues you may encounter and their solutions](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/ProblemSolution)<br/>
|
||||
- [AppCode support](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/AppCode-support)
|
||||
- **[full Lumberjack wiki](https://github.com/CocoaLumberjack/CocoaLumberjack/wiki)**<br/>
|
||||
|
||||
### Requirements
|
||||
- Xcode 4.4 or later is required
|
||||
- iOS 5 or later
|
||||
- OS X 10.7 or later
|
||||
- for OS X < 10.7 support, use the 1.6.0 version
|
||||
|
||||
### Author
|
||||
- [Robbie Hanson](https://github.com/robbiehanson)
|
||||
- Love the project? Wanna buy me a coffee? (or a beer :D) [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UZRA26JPJB3DA)
|
||||
|
||||
### Collaborators
|
||||
- [Ernesto Rivera](https://github.com/rivera-ernesto)
|
||||
- [Dmitry Vorobyov](https://github.com/dvor)
|
||||
- [Bogdan Poplauschi](https://github.com/bpoplauschi)
|
||||
|
||||
### License
|
||||
- CocoaLumberjack is available under the BSD license. See the [LICENSE file](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/LICENSE.txt).
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDASLLogCapture.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDASLLogCapture.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDASLLogCapture.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDASLLogger.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDASLLogger.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDASLLogger.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDAbstractDatabaseLogger.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDAbstractDatabaseLogger.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDAssert.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDAssert.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDAssert.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDContextFilterLogFormatter.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDContextFilterLogFormatter.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/Extensions/DDContextFilterLogFormatter.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDDispatchQueueLogFormatter.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDDispatchQueueLogFormatter.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/Extensions/DDDispatchQueueLogFormatter.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDFileLogger.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDFileLogger.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDFileLogger.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDLog+LOGV.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDLog+LOGV.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDLog+LOGV.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDLog.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDLog.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDLog.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDMultiFormatter.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDMultiFormatter.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/Extensions/DDMultiFormatter.h
|
||||
1
Pods/Headers/Build/CocoaLumberjack/DDTTYLogger.h
generated
Symbolic link
1
Pods/Headers/Build/CocoaLumberjack/DDTTYLogger.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../CocoaLumberjack/Lumberjack/DDTTYLogger.h
|
||||
1
Pods/Headers/Build/Mantle/EXTKeyPathCoding.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/EXTKeyPathCoding.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/extobjc/EXTKeyPathCoding.h
|
||||
1
Pods/Headers/Build/Mantle/EXTRuntimeExtensions.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/EXTRuntimeExtensions.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/extobjc/EXTRuntimeExtensions.h
|
||||
1
Pods/Headers/Build/Mantle/EXTScope.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/EXTScope.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/extobjc/EXTScope.h
|
||||
1
Pods/Headers/Build/Mantle/MTLJSONAdapter.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/MTLJSONAdapter.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/MTLJSONAdapter.h
|
||||
1
Pods/Headers/Build/Mantle/MTLManagedObjectAdapter.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/MTLManagedObjectAdapter.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/MTLManagedObjectAdapter.h
|
||||
1
Pods/Headers/Build/Mantle/MTLModel+NSCoding.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/MTLModel+NSCoding.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/MTLModel+NSCoding.h
|
||||
1
Pods/Headers/Build/Mantle/MTLModel.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/MTLModel.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/MTLModel.h
|
||||
1
Pods/Headers/Build/Mantle/MTLReflection.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/MTLReflection.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/MTLReflection.h
|
||||
1
Pods/Headers/Build/Mantle/MTLValueTransformer.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/MTLValueTransformer.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/MTLValueTransformer.h
|
||||
1
Pods/Headers/Build/Mantle/Mantle.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/Mantle.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/Mantle.h
|
||||
1
Pods/Headers/Build/Mantle/NSArray+MTLManipulationAdditions.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/NSArray+MTLManipulationAdditions.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/NSArray+MTLManipulationAdditions.h
|
||||
1
Pods/Headers/Build/Mantle/NSDictionary+MTLManipulationAdditions.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/NSDictionary+MTLManipulationAdditions.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h
|
||||
1
Pods/Headers/Build/Mantle/NSError+MTLModelException.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/NSError+MTLModelException.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/NSError+MTLModelException.h
|
||||
1
Pods/Headers/Build/Mantle/NSObject+MTLComparisonAdditions.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/NSObject+MTLComparisonAdditions.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/NSObject+MTLComparisonAdditions.h
|
||||
1
Pods/Headers/Build/Mantle/NSValueTransformer+MTLInversionAdditions.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/NSValueTransformer+MTLInversionAdditions.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h
|
||||
1
Pods/Headers/Build/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h
|
||||
1
Pods/Headers/Build/Mantle/metamacros.h
generated
Symbolic link
1
Pods/Headers/Build/Mantle/metamacros.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../Mantle/Mantle/extobjc/metamacros.h
|
||||
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubs.h
generated
Symbolic link
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubs.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubs.h
|
||||
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubsResponse+HTTPMessage.h
generated
Symbolic link
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubsResponse+HTTPMessage.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubsResponse+HTTPMessage.h
|
||||
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubsResponse+JSON.h
generated
Symbolic link
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubsResponse+JSON.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubsResponse+JSON.h
|
||||
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubsResponse.h
generated
Symbolic link
1
Pods/Headers/Build/OHHTTPStubs/OHHTTPStubsResponse.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubsResponse.h
|
||||
1
Pods/Headers/Build/OMGHTTPURLRQ/OMGFormURLEncode.h
generated
Symbolic link
1
Pods/Headers/Build/OMGHTTPURLRQ/OMGFormURLEncode.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../OMGHTTPURLRQ/OMGFormURLEncode.h
|
||||
1
Pods/Headers/Build/OMGHTTPURLRQ/OMGHTTPURLRQ.h
generated
Symbolic link
1
Pods/Headers/Build/OMGHTTPURLRQ/OMGHTTPURLRQ.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../OMGHTTPURLRQ/OMGHTTPURLRQ.h
|
||||
1
Pods/Headers/Build/OMGHTTPURLRQ/OMGUserAgent.h
generated
Symbolic link
1
Pods/Headers/Build/OMGHTTPURLRQ/OMGUserAgent.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../OMGHTTPURLRQ/OMGUserAgent.h
|
||||
1
Pods/Headers/Build/PromiseKit/NSNotificationCenter+PromiseKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/NSNotificationCenter+PromiseKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/NSNotificationCenter+PromiseKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/NSURLConnection+PromiseKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/NSURLConnection+PromiseKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/NSURLConnection+PromiseKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/Promise+Pause.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/Promise+Pause.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/PromiseKit/Promise+Pause.h
|
||||
1
Pods/Headers/Build/PromiseKit/Promise+Until.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/Promise+Until.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/PromiseKit/Promise+Until.h
|
||||
1
Pods/Headers/Build/PromiseKit/Promise+When.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/Promise+When.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/PromiseKit/Promise+When.h
|
||||
1
Pods/Headers/Build/PromiseKit/Promise.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/Promise.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/PromiseKit/Promise.h
|
||||
1
Pods/Headers/Build/PromiseKit/PromiseKit+Foundation.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/PromiseKit+Foundation.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/deprecated/PromiseKit+Foundation.h
|
||||
1
Pods/Headers/Build/PromiseKit/PromiseKit+UIKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/PromiseKit+UIKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/deprecated/PromiseKit+UIKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/PromiseKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/PromiseKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/PromiseKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/UIActionSheet+PromiseKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/UIActionSheet+PromiseKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/UIActionSheet+PromiseKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/UIAlertView+PromiseKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/UIAlertView+PromiseKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/UIAlertView+PromiseKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/UIView+PromiseKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/UIView+PromiseKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/UIView+PromiseKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/UIViewController+PromiseKit.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/UIViewController+PromiseKit.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/UIViewController+PromiseKit.h
|
||||
1
Pods/Headers/Build/PromiseKit/fwd.h
generated
Symbolic link
1
Pods/Headers/Build/PromiseKit/fwd.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../PromiseKit/objc/PromiseKit/fwd.h
|
||||
1
Pods/Headers/Build/YapDatabase/NSDictionary+YapDatabase.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/NSDictionary+YapDatabase.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Internal/NSDictionary+YapDatabase.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapCache.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapCache.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Internal/YapCache.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapCollectionKey.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapCollectionKey.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Utilities/YapCollectionKey.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabase.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabase.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/YapDatabase.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseConnection.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseConnection.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/YapDatabaseConnection.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseConnectionDefaults.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseConnectionDefaults.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Internal/YapDatabaseConnectionDefaults.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseConnectionState.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseConnectionState.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Internal/YapDatabaseConnectionState.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtension.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtension.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtension.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtensionConnection.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtensionConnection.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionConnection.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtensionPrivate.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtensionPrivate.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/Protocol/Internal/YapDatabaseExtensionPrivate.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtensionTransaction.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseExtensionTransaction.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredView.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredView.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredView.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewConnection.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewConnection.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewConnection.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewPrivate.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewPrivate.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FilteredViews/Internal/YapDatabaseFilteredViewPrivate.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewTransaction.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewTransaction.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTransaction.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewTypes.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFilteredViewTypes.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTypes.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearch.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearch.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearch.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchConnection.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchConnection.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchConnection.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchPrivate.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchPrivate.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FullTextSearch/Internal/YapDatabaseFullTextSearchPrivate.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchSnippetOptions.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchTransaction.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseFullTextSearchTransaction.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchTransaction.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseLogging.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseLogging.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Internal/YapDatabaseLogging.h
|
||||
1
Pods/Headers/Build/YapDatabase/YapDatabaseManager.h
generated
Symbolic link
1
Pods/Headers/Build/YapDatabase/YapDatabaseManager.h
generated
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../YapDatabase/YapDatabase/Internal/YapDatabaseManager.h
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue