├── .gitignore
├── CCLogSystem.podspec
├── CCLogSystem.xcworkspace
└── contents.xcworkspacedata
├── CCLogSystem
├── CCLogSystem.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── CCLogSystem
│ ├── CCFileOutputRedirectionController.h
│ ├── CCLocationMake.h
│ ├── CCLocationMake.m
│ ├── CCLog.h
│ ├── CCLog.m
│ ├── CCLogController+Utility.h
│ ├── CCLogController+Utility.m
│ ├── CCLogController.h
│ ├── CCLogController.m
│ ├── CCLogReviewViewController.h
│ ├── CCLogReviewViewController.m
│ ├── CCLogStringImp.h
│ ├── CCLogStringImp.m
│ ├── CCLogSystem.h
│ ├── CCLogSystem.m
│ ├── CCLogViewController.h
│ ├── CCLogViewController.m
│ ├── CCSimpleFileOutputRedirectionController.h
│ ├── CCSimpleFileOutputRedirectionController.m
│ ├── CCTeeController.h
│ ├── CCTeeController.m
│ ├── NSObject+CCReverseComparison.h
│ └── NSObject+CCReverseComparison.m
└── CCLogSystemTests
│ └── Info.plist
├── CCLogSystemDemo
├── CCLogSystemDemo.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── CCLogSystemDemo
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Base.lproj
│ │ ├── LaunchScreen.xib
│ │ └── Main.storyboard
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── ViewController.h
│ ├── ViewController.m
│ └── main.m
└── CCLogSystemDemoTests
│ ├── CCLogSystemDemoTests.m
│ └── Info.plist
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | .DS_Store
5 | *.pbxuser
6 | !default.pbxuser
7 | *.mode1v3
8 | !default.mode1v3
9 | *.mode2v3
10 | !default.mode2v3
11 | *.perspectivev3
12 | !default.perspectivev3
13 | xcuserdata
14 | *.xccheckout
15 | *.moved-aside
16 | DerivedData
17 | *.hmap
18 | *.ipa
19 | *.xcuserstate
20 |
21 | # CocoaPods
22 | #
23 | # We recommend against adding the Pods directory to your .gitignore. However
24 | # you should judge for yourself, the pros and cons are mentioned at:
25 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
26 | #
27 | # Pods/
28 |
--------------------------------------------------------------------------------
/CCLogSystem.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "CCLogSystem"
3 | s.version = "1.0.1"
4 | s.summary = "A Log system for iOS."
5 | s.description = <<-DESC
6 | This library provide an iOS Log System. We can use it to replace NSLog.
7 | And It also can record the log to the local files.
8 | We can directly review these logs in our app, and email to ourselves.
9 | DESC
10 | s.homepage = "https://github.com/yechunjun/CCLogSystem"
11 | s.license = "MIT"
12 | s.author = { "Chun Ye" => "chunforios@gmail.com" }
13 | s.social_media_url = "http://chun.tips"
14 | s.platform = :ios, "6.0"
15 | s.source = { :git => "https://github.com/yechunjun/CCLogSystem.git", :tag => "1.0.1" }
16 | s.source_files = "CCLogSystem/CCLogSystem/*.{h,m}"
17 | s.frameworks = "Foundation", "UIKit"
18 | s.requires_arc = true
19 | end
20 |
--------------------------------------------------------------------------------
/CCLogSystem.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
9 |
10 |
11 |
14 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 343C428E1A0236A700035411 /* CCLogSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 343C428D1A0236A700035411 /* CCLogSystem.m */; };
11 | 3467CA531A035F9100DA6C84 /* CCLogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA3E1A035F9100DA6C84 /* CCLogViewController.m */; };
12 | 3467CA541A035F9100DA6C84 /* CCLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA3F1A035F9100DA6C84 /* CCLog.m */; };
13 | 3467CA551A035F9100DA6C84 /* CCLogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA401A035F9100DA6C84 /* CCLogController.m */; };
14 | 3467CA561A035F9100DA6C84 /* CCLogController+Utility.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA421A035F9100DA6C84 /* CCLogController+Utility.m */; };
15 | 3467CA571A035F9100DA6C84 /* CCLogReviewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA471A035F9100DA6C84 /* CCLogReviewViewController.m */; };
16 | 3467CA581A035F9100DA6C84 /* CCLogStringImp.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA4A1A035F9100DA6C84 /* CCLogStringImp.m */; };
17 | 3467CA591A035F9100DA6C84 /* CCLocationMake.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA4B1A035F9100DA6C84 /* CCLocationMake.m */; };
18 | 3467CA5A1A035F9100DA6C84 /* CCTeeController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA4D1A035F9100DA6C84 /* CCTeeController.m */; };
19 | 3467CA5B1A035F9100DA6C84 /* CCSimpleFileOutputRedirectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA4E1A035F9100DA6C84 /* CCSimpleFileOutputRedirectionController.m */; };
20 | 3467CA5C1A035F9100DA6C84 /* NSObject+CCReverseComparison.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CA511A035F9100DA6C84 /* NSObject+CCReverseComparison.m */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXCopyFilesBuildPhase section */
24 | 348FAFCD1A02325000AA05C2 /* CopyFiles */ = {
25 | isa = PBXCopyFilesBuildPhase;
26 | buildActionMask = 2147483647;
27 | dstPath = "include/$(PRODUCT_NAME)";
28 | dstSubfolderSpec = 16;
29 | files = (
30 | );
31 | runOnlyForDeploymentPostprocessing = 0;
32 | };
33 | /* End PBXCopyFilesBuildPhase section */
34 |
35 | /* Begin PBXFileReference section */
36 | 343C428C1A0236A700035411 /* CCLogSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogSystem.h; sourceTree = ""; };
37 | 343C428D1A0236A700035411 /* CCLogSystem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogSystem.m; sourceTree = ""; };
38 | 3467CA3E1A035F9100DA6C84 /* CCLogViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogViewController.m; sourceTree = ""; };
39 | 3467CA3F1A035F9100DA6C84 /* CCLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLog.m; sourceTree = ""; };
40 | 3467CA401A035F9100DA6C84 /* CCLogController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogController.m; sourceTree = ""; };
41 | 3467CA411A035F9100DA6C84 /* CCLogController+Utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CCLogController+Utility.h"; sourceTree = ""; };
42 | 3467CA421A035F9100DA6C84 /* CCLogController+Utility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CCLogController+Utility.m"; sourceTree = ""; };
43 | 3467CA431A035F9100DA6C84 /* CCLogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogController.h; sourceTree = ""; };
44 | 3467CA441A035F9100DA6C84 /* CCFileOutputRedirectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCFileOutputRedirectionController.h; sourceTree = ""; };
45 | 3467CA451A035F9100DA6C84 /* CCLogReviewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogReviewViewController.h; sourceTree = ""; };
46 | 3467CA461A035F9100DA6C84 /* CCLogStringImp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogStringImp.h; sourceTree = ""; };
47 | 3467CA471A035F9100DA6C84 /* CCLogReviewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogReviewViewController.m; sourceTree = ""; };
48 | 3467CA481A035F9100DA6C84 /* CCLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLog.h; sourceTree = ""; };
49 | 3467CA491A035F9100DA6C84 /* CCLocationMake.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLocationMake.h; sourceTree = ""; };
50 | 3467CA4A1A035F9100DA6C84 /* CCLogStringImp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogStringImp.m; sourceTree = ""; };
51 | 3467CA4B1A035F9100DA6C84 /* CCLocationMake.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLocationMake.m; sourceTree = ""; };
52 | 3467CA4C1A035F9100DA6C84 /* CCLogViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogViewController.h; sourceTree = ""; };
53 | 3467CA4D1A035F9100DA6C84 /* CCTeeController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCTeeController.m; sourceTree = ""; };
54 | 3467CA4E1A035F9100DA6C84 /* CCSimpleFileOutputRedirectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCSimpleFileOutputRedirectionController.m; sourceTree = ""; };
55 | 3467CA4F1A035F9100DA6C84 /* CCSimpleFileOutputRedirectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSimpleFileOutputRedirectionController.h; sourceTree = ""; };
56 | 3467CA501A035F9100DA6C84 /* CCTeeController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTeeController.h; sourceTree = ""; };
57 | 3467CA511A035F9100DA6C84 /* NSObject+CCReverseComparison.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+CCReverseComparison.m"; sourceTree = ""; };
58 | 3467CA521A035F9100DA6C84 /* NSObject+CCReverseComparison.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+CCReverseComparison.h"; sourceTree = ""; };
59 | 348FAFCF1A02325000AA05C2 /* libCCLogSystem.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCCLogSystem.a; sourceTree = BUILT_PRODUCTS_DIR; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | 348FAFCC1A02325000AA05C2 /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | /* End PBXFrameworksBuildPhase section */
71 |
72 | /* Begin PBXGroup section */
73 | 3467CA5D1A035F9C00DA6C84 /* CCLog */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 3467CA431A035F9100DA6C84 /* CCLogController.h */,
77 | 3467CA401A035F9100DA6C84 /* CCLogController.m */,
78 | 3467CA411A035F9100DA6C84 /* CCLogController+Utility.h */,
79 | 3467CA421A035F9100DA6C84 /* CCLogController+Utility.m */,
80 | 3467CA481A035F9100DA6C84 /* CCLog.h */,
81 | 3467CA3F1A035F9100DA6C84 /* CCLog.m */,
82 | );
83 | name = CCLog;
84 | sourceTree = "";
85 | };
86 | 3467CA5E1A035FB100DA6C84 /* DeveloperUI */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 3467CA451A035F9100DA6C84 /* CCLogReviewViewController.h */,
90 | 3467CA471A035F9100DA6C84 /* CCLogReviewViewController.m */,
91 | 3467CA4C1A035F9100DA6C84 /* CCLogViewController.h */,
92 | 3467CA3E1A035F9100DA6C84 /* CCLogViewController.m */,
93 | );
94 | name = DeveloperUI;
95 | sourceTree = "";
96 | };
97 | 3467CA5F1A035FE100DA6C84 /* Base */ = {
98 | isa = PBXGroup;
99 | children = (
100 | 3467CA491A035F9100DA6C84 /* CCLocationMake.h */,
101 | 3467CA4B1A035F9100DA6C84 /* CCLocationMake.m */,
102 | 3467CA461A035F9100DA6C84 /* CCLogStringImp.h */,
103 | 3467CA4A1A035F9100DA6C84 /* CCLogStringImp.m */,
104 | 3467CA521A035F9100DA6C84 /* NSObject+CCReverseComparison.h */,
105 | 3467CA511A035F9100DA6C84 /* NSObject+CCReverseComparison.m */,
106 | );
107 | name = Base;
108 | sourceTree = "";
109 | };
110 | 3467CA601A03600500DA6C84 /* FileOutput */ = {
111 | isa = PBXGroup;
112 | children = (
113 | 3467CA441A035F9100DA6C84 /* CCFileOutputRedirectionController.h */,
114 | 3467CA501A035F9100DA6C84 /* CCTeeController.h */,
115 | 3467CA4D1A035F9100DA6C84 /* CCTeeController.m */,
116 | 3467CA4F1A035F9100DA6C84 /* CCSimpleFileOutputRedirectionController.h */,
117 | 3467CA4E1A035F9100DA6C84 /* CCSimpleFileOutputRedirectionController.m */,
118 | );
119 | name = FileOutput;
120 | sourceTree = "";
121 | };
122 | 348FAFC61A02325000AA05C2 = {
123 | isa = PBXGroup;
124 | children = (
125 | 348FAFD11A02325000AA05C2 /* CCLogSystem */,
126 | 348FAFD01A02325000AA05C2 /* Products */,
127 | );
128 | sourceTree = "";
129 | };
130 | 348FAFD01A02325000AA05C2 /* Products */ = {
131 | isa = PBXGroup;
132 | children = (
133 | 348FAFCF1A02325000AA05C2 /* libCCLogSystem.a */,
134 | );
135 | name = Products;
136 | sourceTree = "";
137 | };
138 | 348FAFD11A02325000AA05C2 /* CCLogSystem */ = {
139 | isa = PBXGroup;
140 | children = (
141 | 3467CA601A03600500DA6C84 /* FileOutput */,
142 | 3467CA5F1A035FE100DA6C84 /* Base */,
143 | 3467CA5E1A035FB100DA6C84 /* DeveloperUI */,
144 | 3467CA5D1A035F9C00DA6C84 /* CCLog */,
145 | 343C428C1A0236A700035411 /* CCLogSystem.h */,
146 | 343C428D1A0236A700035411 /* CCLogSystem.m */,
147 | );
148 | path = CCLogSystem;
149 | sourceTree = "";
150 | };
151 | /* End PBXGroup section */
152 |
153 | /* Begin PBXNativeTarget section */
154 | 348FAFCE1A02325000AA05C2 /* CCLogSystem */ = {
155 | isa = PBXNativeTarget;
156 | buildConfigurationList = 348FAFE31A02325000AA05C2 /* Build configuration list for PBXNativeTarget "CCLogSystem" */;
157 | buildPhases = (
158 | 348FAFCB1A02325000AA05C2 /* Sources */,
159 | 348FAFCC1A02325000AA05C2 /* Frameworks */,
160 | 348FAFCD1A02325000AA05C2 /* CopyFiles */,
161 | );
162 | buildRules = (
163 | );
164 | dependencies = (
165 | );
166 | name = CCLogSystem;
167 | productName = CCLogSystem;
168 | productReference = 348FAFCF1A02325000AA05C2 /* libCCLogSystem.a */;
169 | productType = "com.apple.product-type.library.static";
170 | };
171 | /* End PBXNativeTarget section */
172 |
173 | /* Begin PBXProject section */
174 | 348FAFC71A02325000AA05C2 /* Project object */ = {
175 | isa = PBXProject;
176 | attributes = {
177 | LastUpgradeCheck = 0610;
178 | ORGANIZATIONNAME = "Chun Tips";
179 | TargetAttributes = {
180 | 348FAFCE1A02325000AA05C2 = {
181 | CreatedOnToolsVersion = 6.1;
182 | };
183 | };
184 | };
185 | buildConfigurationList = 348FAFCA1A02325000AA05C2 /* Build configuration list for PBXProject "CCLogSystem" */;
186 | compatibilityVersion = "Xcode 3.2";
187 | developmentRegion = English;
188 | hasScannedForEncodings = 0;
189 | knownRegions = (
190 | en,
191 | );
192 | mainGroup = 348FAFC61A02325000AA05C2;
193 | productRefGroup = 348FAFD01A02325000AA05C2 /* Products */;
194 | projectDirPath = "";
195 | projectRoot = "";
196 | targets = (
197 | 348FAFCE1A02325000AA05C2 /* CCLogSystem */,
198 | );
199 | };
200 | /* End PBXProject section */
201 |
202 | /* Begin PBXSourcesBuildPhase section */
203 | 348FAFCB1A02325000AA05C2 /* Sources */ = {
204 | isa = PBXSourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | 3467CA591A035F9100DA6C84 /* CCLocationMake.m in Sources */,
208 | 3467CA5C1A035F9100DA6C84 /* NSObject+CCReverseComparison.m in Sources */,
209 | 3467CA551A035F9100DA6C84 /* CCLogController.m in Sources */,
210 | 3467CA541A035F9100DA6C84 /* CCLog.m in Sources */,
211 | 3467CA581A035F9100DA6C84 /* CCLogStringImp.m in Sources */,
212 | 3467CA561A035F9100DA6C84 /* CCLogController+Utility.m in Sources */,
213 | 3467CA5B1A035F9100DA6C84 /* CCSimpleFileOutputRedirectionController.m in Sources */,
214 | 343C428E1A0236A700035411 /* CCLogSystem.m in Sources */,
215 | 3467CA531A035F9100DA6C84 /* CCLogViewController.m in Sources */,
216 | 3467CA571A035F9100DA6C84 /* CCLogReviewViewController.m in Sources */,
217 | 3467CA5A1A035F9100DA6C84 /* CCTeeController.m in Sources */,
218 | );
219 | runOnlyForDeploymentPostprocessing = 0;
220 | };
221 | /* End PBXSourcesBuildPhase section */
222 |
223 | /* Begin XCBuildConfiguration section */
224 | 348FAFE11A02325000AA05C2 /* Debug */ = {
225 | isa = XCBuildConfiguration;
226 | buildSettings = {
227 | ALWAYS_SEARCH_USER_PATHS = NO;
228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
229 | CLANG_CXX_LIBRARY = "libc++";
230 | CLANG_ENABLE_MODULES = YES;
231 | CLANG_ENABLE_OBJC_ARC = YES;
232 | CLANG_WARN_BOOL_CONVERSION = YES;
233 | CLANG_WARN_CONSTANT_CONVERSION = YES;
234 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
235 | CLANG_WARN_EMPTY_BODY = YES;
236 | CLANG_WARN_ENUM_CONVERSION = YES;
237 | CLANG_WARN_INT_CONVERSION = YES;
238 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
239 | CLANG_WARN_UNREACHABLE_CODE = YES;
240 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
241 | COPY_PHASE_STRIP = NO;
242 | ENABLE_STRICT_OBJC_MSGSEND = YES;
243 | GCC_C_LANGUAGE_STANDARD = gnu99;
244 | GCC_DYNAMIC_NO_PIC = NO;
245 | GCC_OPTIMIZATION_LEVEL = 0;
246 | GCC_PREPROCESSOR_DEFINITIONS = (
247 | "DEBUG=1",
248 | "$(inherited)",
249 | );
250 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
251 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
252 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
253 | GCC_WARN_UNDECLARED_SELECTOR = YES;
254 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
255 | GCC_WARN_UNUSED_FUNCTION = YES;
256 | GCC_WARN_UNUSED_VARIABLE = YES;
257 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
258 | MTL_ENABLE_DEBUG_INFO = YES;
259 | ONLY_ACTIVE_ARCH = YES;
260 | SDKROOT = iphoneos;
261 | };
262 | name = Debug;
263 | };
264 | 348FAFE21A02325000AA05C2 /* Release */ = {
265 | isa = XCBuildConfiguration;
266 | buildSettings = {
267 | ALWAYS_SEARCH_USER_PATHS = NO;
268 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
269 | CLANG_CXX_LIBRARY = "libc++";
270 | CLANG_ENABLE_MODULES = YES;
271 | CLANG_ENABLE_OBJC_ARC = YES;
272 | CLANG_WARN_BOOL_CONVERSION = YES;
273 | CLANG_WARN_CONSTANT_CONVERSION = YES;
274 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
275 | CLANG_WARN_EMPTY_BODY = YES;
276 | CLANG_WARN_ENUM_CONVERSION = YES;
277 | CLANG_WARN_INT_CONVERSION = YES;
278 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
279 | CLANG_WARN_UNREACHABLE_CODE = YES;
280 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
281 | COPY_PHASE_STRIP = YES;
282 | ENABLE_NS_ASSERTIONS = NO;
283 | ENABLE_STRICT_OBJC_MSGSEND = YES;
284 | GCC_C_LANGUAGE_STANDARD = gnu99;
285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
287 | GCC_WARN_UNDECLARED_SELECTOR = YES;
288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
289 | GCC_WARN_UNUSED_FUNCTION = YES;
290 | GCC_WARN_UNUSED_VARIABLE = YES;
291 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
292 | MTL_ENABLE_DEBUG_INFO = NO;
293 | SDKROOT = iphoneos;
294 | VALIDATE_PRODUCT = YES;
295 | };
296 | name = Release;
297 | };
298 | 348FAFE41A02325000AA05C2 /* Debug */ = {
299 | isa = XCBuildConfiguration;
300 | buildSettings = {
301 | OTHER_LDFLAGS = "-ObjC";
302 | PRODUCT_NAME = "$(TARGET_NAME)";
303 | SKIP_INSTALL = YES;
304 | };
305 | name = Debug;
306 | };
307 | 348FAFE51A02325000AA05C2 /* Release */ = {
308 | isa = XCBuildConfiguration;
309 | buildSettings = {
310 | OTHER_LDFLAGS = "-ObjC";
311 | PRODUCT_NAME = "$(TARGET_NAME)";
312 | SKIP_INSTALL = YES;
313 | };
314 | name = Release;
315 | };
316 | /* End XCBuildConfiguration section */
317 |
318 | /* Begin XCConfigurationList section */
319 | 348FAFCA1A02325000AA05C2 /* Build configuration list for PBXProject "CCLogSystem" */ = {
320 | isa = XCConfigurationList;
321 | buildConfigurations = (
322 | 348FAFE11A02325000AA05C2 /* Debug */,
323 | 348FAFE21A02325000AA05C2 /* Release */,
324 | );
325 | defaultConfigurationIsVisible = 0;
326 | defaultConfigurationName = Release;
327 | };
328 | 348FAFE31A02325000AA05C2 /* Build configuration list for PBXNativeTarget "CCLogSystem" */ = {
329 | isa = XCConfigurationList;
330 | buildConfigurations = (
331 | 348FAFE41A02325000AA05C2 /* Debug */,
332 | 348FAFE51A02325000AA05C2 /* Release */,
333 | );
334 | defaultConfigurationIsVisible = 0;
335 | defaultConfigurationName = Release;
336 | };
337 | /* End XCConfigurationList section */
338 | };
339 | rootObject = 348FAFC71A02325000AA05C2 /* Project object */;
340 | }
341 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCFileOutputRedirectionController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 |
15 | @protocol CCFileOutputRedirectionController
16 |
17 | @property (nonatomic, strong) NSFileHandle *inputFileHandle;
18 | @property (nonatomic, strong) NSFileHandle *outputFileHandle;
19 |
20 | - (void)startRecordLog;
21 |
22 | - (void)stopRecordLog;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLocationMake.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLog.h"
14 |
15 | typedef NS_ENUM(NSInteger, CCLocationStyle) {
16 | CCLocationStyleShort, // Only point FUNCTION name
17 | CCLocationStyleLong, // Point FILE FUNCTION LINE and Thread
18 | };
19 |
20 | CC_EXTERN CCLocation CCLocationNowhere;
21 |
22 | CC_EXTERN NSString *CCStringFromLocation(CCLocation location);
23 |
24 | CC_EXTERN NSString *CCStringFromLocationWithStyle(CCLocation location, CCLocationStyle locationStyle);
25 |
26 | CC_EXTERN NSString *CCLogPrefixFromLocation (CCLocation location);
27 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLocationMake.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLocationMake.h"
14 |
15 | #pragma mark - Private
16 |
17 | static NSString *CCStringFromSourceFilePath(const char *file)
18 | {
19 | NSString *path = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:file length:strlen(file)];
20 | NSString *string = [path lastPathComponent];
21 | return string;
22 | }
23 |
24 | static NSString *CCStringWithSourceLocationFromLocation(CCLocation location)
25 | {
26 | NSString *string;
27 | if (!memcmp(&location, &CCLocationNowhere, sizeof(location))) {
28 | string = @"";
29 | } else {
30 | string = [NSString stringWithFormat:@"%@ at %d (%s)", CCStringFromSourceFilePath(location.file), location.line, location.func];
31 | }
32 | return string;
33 | }
34 |
35 | #pragma mark - Public
36 |
37 | NSString *CCLogPrefixFromLocation (CCLocation location)
38 | {
39 | NSString *sourceLocationDescription = CCStringWithSourceLocationFromLocation(location);
40 | NSArray *stringArray = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%@", [NSThread currentThread].description], (sourceLocationDescription.length > 0 ? [NSString stringWithFormat:@"%@:", sourceLocationDescription] : [NSNull null]), nil];
41 | NSString *string = [stringArray componentsJoinedByString:@" "];
42 | return string;
43 | }
44 |
45 | NSString *CCStringFromLocationWithStyle(CCLocation location, CCLocationStyle locationStyle)
46 | {
47 | NSString *string;
48 | switch (locationStyle) {
49 | case CCLocationStyleLong:
50 | {
51 | NSString *sourceLocationDescription = CCStringWithSourceLocationFromLocation(location);
52 | NSArray *stringArray = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%@", [NSThread currentThread].description], (sourceLocationDescription.length > 0 ? [NSString stringWithFormat:@"%@", sourceLocationDescription] : [NSNull null]), nil];
53 | string = [stringArray componentsJoinedByString:@" "];
54 | }
55 | break;
56 | case CCLocationStyleShort:
57 | string = [NSString stringWithFormat:@"%s", location.func];
58 | break;
59 | default:
60 | abort();
61 | break;
62 | }
63 | return string;
64 | }
65 |
66 | NSString *CCStringFromLocation(CCLocation location)
67 | {
68 | return CCStringFromLocationWithStyle(location, CCLocationStyleLong);
69 | }
70 |
71 | CCLocation CCLocationNowhere = {
72 | CC_INITIALIZED_FIELD(file, ""),
73 | CC_INITIALIZED_FIELD(line, 0),
74 | CC_INITIALIZED_FIELD(func, "")
75 | };
76 |
77 |
78 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLog.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 |
15 | // Define
16 | #ifdef __cplusplus
17 | #define CC_EXTERN extern "C" __attribute__((visibility ("default")))
18 | #else
19 | #define CC_EXTERN extern __attribute__((visibility ("default")))
20 | #endif
21 |
22 | #ifdef __cplusplus
23 | # if !defined __clang__
24 | # define CC_INITIALIZED_FIELD(name, ...) \
25 | name: __VA_ARGS__
26 | # else
27 | # define CC_INITIALIZED_FIELD(name, ...) \
28 | .name = __VA_ARGS__
29 | # endif
30 | #else
31 | # define CC_INITIALIZED_FIELD(name, ...) \
32 | .name = __VA_ARGS__
33 | #endif
34 |
35 | // Location
36 | typedef struct {
37 | char const *file;
38 | int line;
39 | char const *func;
40 | } CCLocation;
41 |
42 | static inline CCLocation CCLocationMake (char const *file, int line, char const *func)
43 | {
44 | CCLocation location;
45 | location.file = file;
46 | location.line = line;
47 | location.func = func;
48 |
49 | return location;
50 | }
51 |
52 | #define CC_LOCATION() \
53 | CCLocationMake (__FILE__, __LINE__, __func__)
54 |
55 | // Log
56 | CC_EXTERN void CCLog (CCLocation location, NSString *format, ...);
57 |
58 | CC_EXTERN void switchToCCLog (void);
59 |
60 | CC_EXTERN void switchToNSLog (void);
61 |
62 | // Description
63 | CC_EXTERN NSString *CCDescriptionWithObjCTypeAndArgs (char const *objCType, ...);
64 |
65 | #define CC_STRING_FOR_LOG_VALUE(...) \
66 | [NSString stringWithFormat:@"%s: %@", \
67 | #__VA_ARGS__, \
68 | CC_DESCRIPTION_FOR_VALUE(__VA_ARGS__)]
69 |
70 | #define CC_DESCRIPTION_FOR_VALUE(...) \
71 | ({ \
72 | CCDescriptionWithObjCTypeAndArgs ( \
73 | @encode (__typeof__ (__VA_ARGS__)), \
74 | (__VA_ARGS__)); \
75 | })
76 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLog.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLog.h"
14 | #import "CCLogStringImp.h"
15 | #import
16 |
17 | #pragma mark - Log
18 |
19 | enum CCLogImpKind {
20 | CCLogImpKindStdErr,
21 | CCLogImpKindNSLog
22 | };
23 |
24 | enum CCLogImpKind CCLogImpKind = CCLogImpKindStdErr;
25 |
26 | static void CCLogString (CCLocation location, NSString *string)
27 | {
28 | if (CCLogImpKindStdErr == CCLogImpKind) {
29 | CCLogStringToStderr(location, string);
30 | } else {
31 | CCLogStringToNSLog(location, string);
32 | }
33 | }
34 |
35 | void switchToCCLog (void)
36 | {
37 | CCLogImpKind = CCLogImpKindStdErr;
38 | }
39 |
40 | void switchToNSLog (void)
41 | {
42 | CCLogImpKind = CCLogImpKindNSLog;
43 | }
44 |
45 | void CCLog (CCLocation location, NSString *format, ...)
46 | {
47 | NSString *string;
48 | {
49 | va_list argList;
50 | va_start(argList, format);
51 | string = [[NSString alloc] initWithFormat:format arguments:argList];
52 | va_end(argList);
53 | }
54 | CCLogString(location, string);
55 | }
56 |
57 | #pragma mark - Description
58 |
59 | typedef NSString *(*CCDescriptionHandler) (char const *objcType, va_list argList);
60 |
61 | static inline NSString *CCObjectDescription (id object)
62 | {
63 | NSString *description = [object description];
64 | return description;
65 | }
66 |
67 | static NSString *CCBaseDescriptionHandler (char const *objCType, va_list ap)
68 | {
69 | NSString *description;
70 |
71 | NSString *objCTypeString = [[NSString alloc] initWithUTF8String:objCType];
72 |
73 | if ([@"c" isEqualToString: objCTypeString]) {
74 | int x = va_arg(ap, int);
75 | if (isprint (x)) {
76 | description = [NSString stringWithFormat:@"'%c'", x];
77 | } else {
78 | description = [NSString stringWithFormat:@"%d", (int)x];
79 | }
80 | } else if ([@"i" isEqualToString:objCTypeString]) {
81 | int i = va_arg(ap, int);
82 | description = [NSString stringWithFormat:@"%d", i];
83 | } else if ([@"s" isEqualToString:objCTypeString]) {
84 | int s = va_arg(ap, int);
85 | description = [NSString stringWithFormat:@"%d", s];
86 | }else if ([@"l" isEqualToString:objCTypeString]) {
87 | long l = va_arg(ap, long);
88 | description = [NSString stringWithFormat:@"%ld", l];
89 | } else if ([@"q" isEqualToString:objCTypeString]) {
90 | long long q = va_arg(ap, long long);
91 | description = [NSString stringWithFormat:@"%lld", q];
92 | } else if ([@"C" isEqualToString:objCTypeString]) {
93 | int C = va_arg(ap, int);
94 | description = [NSString stringWithFormat:@"%d", C];
95 | } else if ([@"I" isEqualToString:objCTypeString]) {
96 | unsigned int I = va_arg(ap, unsigned int);
97 | description = [NSString stringWithFormat:@"%u", I];
98 | } else if ([@"S" isEqualToString:objCTypeString]) {
99 | int S = va_arg(ap, int);
100 | description = [NSString stringWithFormat:@"%d", S];
101 | } else if ([@"L" isEqualToString:objCTypeString]) {
102 | unsigned long L = va_arg(ap, unsigned long);
103 | description = [NSString stringWithFormat:@"%lu", L];
104 | } else if ([@"Q" isEqualToString:objCTypeString]) {
105 | unsigned long long Q = va_arg(ap, unsigned long long);
106 | description = [NSString stringWithFormat:@"%llu", Q];
107 | } else if ([@"f" isEqualToString:objCTypeString]) {
108 | double f = va_arg(ap, double);
109 | description = [NSString stringWithFormat:@"%f", f];
110 | } else if ([@"d" isEqualToString:objCTypeString]) {
111 | double d = va_arg(ap, double);
112 | description = [NSString stringWithFormat:@"%g", d];
113 | } else if ([@"*" isEqualToString:objCTypeString]) {
114 | char * point = va_arg(ap, char *);
115 | description = [NSString stringWithFormat:@"%s", point];
116 | } else if ([@"r*" isEqualToString:objCTypeString]) {
117 | char const * constPoint = va_arg(ap, char const *);
118 | description = [NSString stringWithFormat:@"%s", constPoint];
119 | } else if ([@"^v" isEqualToString:objCTypeString]) {
120 | void * _void = va_arg(ap, void *);
121 | description = [NSString stringWithFormat:@"%p", _void];
122 | } else if ([@"r^v" isEqualToString:objCTypeString]) {
123 | void const * _constVoid = va_arg(ap, void const *);
124 | description = [NSString stringWithFormat:@"%p", _constVoid];
125 | } else if ([[NSString stringWithUTF8String:"@"] isEqualToString:objCTypeString]) {
126 | id x = va_arg(ap, id);
127 | description = CCObjectDescription(x);
128 | } else if ([[NSString stringWithUTF8String:"@?"] isEqualToString:objCTypeString]) {
129 | id x = va_arg(ap, id);
130 | description = CCObjectDescription(x);
131 | } else if ([[NSString stringWithUTF8String:":"] isEqualToString:objCTypeString]) {
132 | SEL sel = va_arg(ap, SEL);
133 | description = NSStringFromSelector(sel);
134 | } else if ([[NSString stringWithUTF8String:"#"] isEqualToString:objCTypeString]) {
135 | id class = va_arg(ap, id);
136 | description = NSStringFromClass(class);
137 | } else if ([[NSString stringWithUTF8String:@encode (NSRange)] isEqualToString:objCTypeString]) {
138 | NSRange range = va_arg(ap, NSRange);
139 | description = NSStringFromRange(range);
140 | } else if ([objCTypeString hasPrefix: @"^{"]) {
141 | void *p = va_arg(ap, void *);
142 | description = [NSString stringWithFormat:@"<%@>(%p)", objCTypeString, p];
143 | } else {
144 | if ([objCTypeString hasPrefix:@"{CGRect"]) {
145 | CGRect rect = va_arg(ap, CGRect);
146 | description = NSStringFromCGRect(rect);
147 | } else if ([objCTypeString hasPrefix:@"{CGVector"]) {
148 | CGVector vector = va_arg(ap, CGVector);
149 | description = NSStringFromCGVector(vector);
150 | } else if ([objCTypeString hasPrefix:@"{CGSize"]) {
151 | CGSize size = va_arg(ap, CGSize);
152 | description = NSStringFromCGSize(size);
153 | } else if ([objCTypeString hasPrefix:@"{CGAffineTransform"]) {
154 | CGAffineTransform transform = va_arg(ap, CGAffineTransform);
155 | description = NSStringFromCGAffineTransform(transform);
156 | } else if ([objCTypeString hasPrefix:@"{UIEdgeInsets"]) {
157 | UIEdgeInsets insets = va_arg(ap, UIEdgeInsets);
158 | description = NSStringFromUIEdgeInsets(insets);
159 | } else if ([objCTypeString hasPrefix:@"{UIOffset"]) {
160 | UIOffset offset = va_arg(ap, UIOffset);
161 | description = NSStringFromUIOffset(offset);
162 | } else {
163 | description = [NSString stringWithFormat:@"<%@>(?)", objCTypeString];
164 | }
165 | }
166 | return description;
167 | }
168 |
169 | static CCDescriptionHandler CCCurrentDescriptionHandler;
170 |
171 | CCDescriptionHandler CCGetCurrentDescriptionHandler (void)
172 | {
173 | CCDescriptionHandler currentDescriptionHandler;
174 | if (!CCCurrentDescriptionHandler) {
175 | CCCurrentDescriptionHandler = CCBaseDescriptionHandler;
176 | }
177 | currentDescriptionHandler = CCCurrentDescriptionHandler;
178 | return currentDescriptionHandler;
179 | }
180 |
181 | void CCSetCurrentDescriptionHandler (CCDescriptionHandler handler)
182 | {
183 | CCCurrentDescriptionHandler = handler;
184 | }
185 |
186 | NSString *CCDescriptionWithObjCTypeAndArgs (char const *objCType, ...)
187 | {
188 | NSString *description;
189 |
190 | va_list ap;
191 | va_start(ap, objCType);
192 |
193 | description = CCGetCurrentDescriptionHandler() (objCType, ap);
194 |
195 | va_end(ap);
196 |
197 | return description;
198 | }
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogController+Utility.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLogController.h"
14 |
15 | @interface CCLogController (Utility)
16 |
17 | - (NSString *)pathForbasename:(NSString *)basename;
18 |
19 | + (NSDateFormatter *)dateFormatter;
20 |
21 | + (NSString *)basenamePrefix;
22 |
23 | + (NSString *)pathExtension;
24 |
25 | + (BOOL)forceConsoleLog;
26 |
27 | + (NSString *)basenameForDate:(NSDate *)date;
28 |
29 | + (NSString *)basenameForBasename:(NSString *)origBasename date2:(NSDate *)date2 date2Type:(NSString *)date2Type;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogController+Utility.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLogController+Utility.h"
14 |
15 | @implementation CCLogController (Utility)
16 |
17 | - (NSString *)pathForbasename:(NSString *)basename
18 | {
19 | NSString *fileName = [basename stringByAppendingPathExtension:[CCLogController pathExtension]];
20 | return [self.logsDirectory stringByAppendingPathComponent:fileName];
21 | }
22 |
23 | + (NSString *)basenameForDate:(NSDate *)date
24 | {
25 | NSDateFormatter *dateFormatter = [CCLogController dateFormatter];
26 | NSString *dateString = [dateFormatter stringFromDate:date];
27 | NSString *basenamePrefix = [CCLogController basenamePrefix];
28 | NSString *basename = [basenamePrefix stringByAppendingString:dateString];
29 | return basename;
30 | }
31 |
32 | + (NSString *)basenameForBasename:(NSString *)origBasename date2:(NSDate *)date2 date2Type:(NSString *)date2Type
33 | {
34 | NSDateFormatter *dateFormatter = [CCLogController dateFormatter];
35 | NSString *date2String = [dateFormatter stringFromDate:date2];
36 | NSString *separator = [CCLogController separator];
37 | NSString *basename = [@[origBasename, date2String, date2Type] componentsJoinedByString:separator];
38 | return basename;
39 | }
40 |
41 | + (BOOL)forceConsoleLog
42 | {
43 | return [[[NSProcessInfo processInfo].environment objectForKey:@"NSUnbufferedIO"] boolValue];
44 | }
45 |
46 | + (NSDateFormatter *)dateFormatter
47 | {
48 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
49 | dateFormatter.locale = [NSLocale currentLocale];
50 | dateFormatter.dateFormat = @"yyyy-MM-dd-HHmmss";
51 | return dateFormatter;
52 | }
53 |
54 | + (NSString *)basenamePrefix
55 | {
56 | NSString *processName = [NSProcessInfo processInfo].processName;
57 | NSString *basenamePrefix = [NSString stringWithFormat:@"%@_", processName];
58 | return basenamePrefix;
59 | }
60 |
61 | + (NSString *)pathExtension
62 | {
63 | return @"log";
64 | }
65 |
66 | + (NSString *)separator;
67 | {
68 | return @"_";
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 | #import "CCFileOutputRedirectionController.h"
15 | #import "CCLogSystem.h"
16 |
17 | @interface CCLogController : NSObject
18 |
19 | @property (nonatomic, weak) id fileOutputRedirectionController;
20 |
21 | @property (nonatomic, copy, readonly) NSString *logsDirectory;
22 |
23 | @property (nonatomic, copy, readonly) NSArray *availableLogs;
24 |
25 | - (void)startCapturingLogsWithRedirectionController: (id )fileOutputRedirectionController logType:(CCLogType)logType;
26 |
27 | - (void)stopCapturingLogs;
28 |
29 | - (void)removeOldLogsExceedingTotalSize: (unsigned long long)maximumTotalSize savingAtLeast: (NSUInteger)minimumCount;
30 |
31 | @end
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLogController.h"
14 | #import "CCLogController+Utility.h"
15 | #import
16 |
17 | #import
18 | #import
19 | #import
20 |
21 | #import "CCLog.h"
22 | #import "NSObject+CCReverseComparison.h"
23 |
24 | static NSPointerArray *_logContollerContainer;
25 |
26 | @interface CCLogController ()
27 |
28 | @property (nonatomic, copy) NSString *logsDirectory;
29 |
30 | @property (nonatomic, copy) NSArray *availableLogs;
31 |
32 | @property (nonatomic, copy) NSString *outputBasename;
33 |
34 | // Crash
35 | @property (nonatomic) int stdOutDup;
36 |
37 | @property (nonatomic) BOOL stdOutToStdErrRedirectEnabledImp;
38 |
39 | @end
40 |
41 | @implementation CCLogController
42 |
43 | #pragma mark - Init
44 |
45 | + (void)load
46 | {
47 | _logContollerContainer = [[NSPointerArray alloc] initWithOptions:NSPointerFunctionsWeakMemory];
48 | }
49 |
50 | - (id)init
51 | {
52 | self = [super init];
53 | if (self) {
54 | NSString *fullNamespace = @"tips.chun.CCLogSystem";
55 |
56 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
57 | self.logsDirectory = [paths[0] stringByAppendingPathComponent:fullNamespace];
58 | }
59 |
60 | [_logContollerContainer addPointer:(__bridge void *)(self)];
61 |
62 | return self;
63 | }
64 |
65 | #pragma mark - Set && Get
66 |
67 | - (NSArray *)availableLogs
68 | {
69 | NSArray *availableLogs;
70 |
71 | NSFileManager *fileManager = [NSFileManager defaultManager];
72 |
73 | NSError *error;
74 |
75 | NSArray *contents = [fileManager contentsOfDirectoryAtPath:self.logsDirectory error:&error];
76 | if (!contents) {
77 | availableLogs = nil;
78 | } else {
79 | NSString *dotAndPathExtension = [[@"a" stringByAppendingString:[CCLogController pathExtension]] substringFromIndex:1];
80 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(self endswith %@) and (self beginswith %@)", dotAndPathExtension, [CCLogController basenamePrefix]];
81 | NSArray *filteredContents = [contents filteredArrayUsingPredicate:predicate];
82 | NSMutableArray *filteredPaths = [NSMutableArray array];
83 |
84 | for (NSString *filename in filteredContents) {
85 | NSString *path = [self.logsDirectory stringByAppendingPathComponent:filename];
86 | [filteredPaths addObject:path];
87 | }
88 |
89 | availableLogs = [filteredPaths sortedArrayUsingSelector:@selector(reverseCompare:)];
90 | }
91 |
92 | return availableLogs;
93 | }
94 |
95 | #pragma mark - Public
96 |
97 | - (void)startCapturingLogsWithRedirectionController: (id )fileOutputRedirectionController logType:(CCLogType)logType
98 | {
99 | if (logType == CCLogTypeCCLOG) {
100 | switchToCCLog();
101 | } else {
102 | switchToNSLog();
103 | }
104 |
105 | NSFileManager *fileManager = [NSFileManager defaultManager];
106 | NSString *outputBasename = [CCLogController basenameForDate:[NSDate date]];
107 | NSString *outputFilePath = [self pathForbasename:outputBasename];
108 |
109 | if (![fileManager fileExistsAtPath:self.logsDirectory]) {
110 | NSError *error;
111 | [fileManager createDirectoryAtPath:self.logsDirectory withIntermediateDirectories:YES attributes:nil error:&error];
112 | }
113 |
114 | BOOL fileAlreadyExists = [fileManager fileExistsAtPath:outputFilePath];
115 |
116 | if (!fileAlreadyExists) {
117 | NSData *data = [NSData data];
118 | [fileManager createFileAtPath:outputFilePath contents:data attributes:nil];
119 | }
120 |
121 | CC_LOG_VALUE(outputFilePath);
122 |
123 | NSFileHandle *outputFileHandle = [NSFileHandle fileHandleForWritingAtPath:outputFilePath];
124 | [outputFileHandle seekToEndOfFile];
125 |
126 | NSFileHandle *inputFileHandle = [NSFileHandle fileHandleWithStandardError];
127 |
128 | fileOutputRedirectionController.outputFileHandle = outputFileHandle;
129 | fileOutputRedirectionController.inputFileHandle = inputFileHandle;
130 | self.fileOutputRedirectionController = fileOutputRedirectionController;
131 |
132 | self.outputBasename = [[outputFilePath lastPathComponent] stringByDeletingPathExtension];
133 |
134 | [self startCapturingCrashLog];
135 | }
136 |
137 | - (void)stopCapturingLogs
138 | {
139 | [self flush];
140 | self.fileOutputRedirectionController = nil;
141 | }
142 |
143 | - (void)removeOldLogsExceedingTotalSize: (unsigned long long)maximumTotalSize savingAtLeast: (NSUInteger)minimumCount
144 | {
145 | NSArray *availableLogs = [self availableLogs];
146 |
147 | if (availableLogs && availableLogs.count > 0) {
148 | NSFileManager *fileManager = [NSFileManager defaultManager];
149 |
150 | unsigned long long totalSize = 0ULL;
151 |
152 | NSUInteger index;
153 |
154 | for (index = 0; index < availableLogs.count; index ++) {
155 | NSString *path = [availableLogs objectAtIndex:index];
156 | NSError *error;
157 | NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:&error];
158 | if (attributes) {
159 | unsigned long long fileSize = [[attributes valueForKey:@"NSFileSize"] longLongValue];
160 | unsigned long long updatedTotalSize = fileSize + totalSize;
161 | if (updatedTotalSize > maximumTotalSize) {
162 | if (index < minimumCount) {
163 | index = MIN(minimumCount, availableLogs.count);
164 | }
165 | break;
166 | } else {
167 | totalSize = updatedTotalSize;
168 | }
169 | }
170 | }
171 |
172 | NSArray *logsForRemoval = [availableLogs subarrayWithRange:NSMakeRange(index, availableLogs.count - index)];
173 |
174 | for (NSString *pathForRemoval in logsForRemoval) {
175 | NSError *error;
176 | [fileManager removeItemAtPath:pathForRemoval error:&error];
177 | }
178 | }
179 | }
180 |
181 | #pragma mark - Private && Log
182 |
183 | - (void)flush
184 | {
185 | fflush (stderr);
186 | fflush (stdout);
187 |
188 | [self.fileOutputRedirectionController stopRecordLog];
189 | }
190 |
191 | - (void)relocateLogToType:(NSString *)type
192 | {
193 | NSFileManager *fileManager = [NSFileManager defaultManager];
194 | NSString *basename = [CCLogController basenameForBasename:self.outputBasename date2:[NSDate date] date2Type:type];
195 | NSString *outputFilePath = [self pathForbasename:self.outputBasename];
196 | NSString *updatedPath = [self pathForbasename:basename];
197 |
198 | [fileManager linkItemAtPath:outputFilePath toPath:updatedPath error:NULL];
199 |
200 | [fileManager removeItemAtPath:outputFilePath error:NULL];
201 |
202 | self.outputBasename = basename;
203 | }
204 |
205 | #pragma mark - Private && Crash
206 |
207 | static NSUncaughtExceptionHandler *originUncaughtExceptionHandler;
208 |
209 | - (void)formulateCrashLog
210 | {
211 | [self relocateLogToType:@"crashed"];
212 |
213 | [self setStdOutToStdErrRedirectEnabled:NO];
214 |
215 | [self stopCapturingLogs];
216 |
217 | asl_add_log_file (NULL, STDERR_FILENO);
218 | }
219 |
220 | static void logAwareUncaughtExceptionHandler (NSException *exception)
221 | {
222 | CC_LOG_VALUE(exception.name);
223 | CC_LOG_VALUE(exception);
224 | CC_LOG_VALUE(exception.userInfo);
225 | CC_LOG_VALUE(exception.callStackSymbols);
226 |
227 | if (originUncaughtExceptionHandler) {
228 | originUncaughtExceptionHandler(exception);
229 | }
230 |
231 | [_logContollerContainer.allObjects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
232 | [obj formulateCrashLog];
233 | }];
234 | }
235 |
236 | - (void)startCapturingCrashLog
237 | {
238 | [self setStdOutToStdErrRedirectEnabled:YES];
239 |
240 | originUncaughtExceptionHandler = NSGetUncaughtExceptionHandler();
241 |
242 | NSSetUncaughtExceptionHandler(logAwareUncaughtExceptionHandler);
243 | }
244 |
245 | - (void)stopCapturingCrashLog
246 | {
247 | NSSetUncaughtExceptionHandler (originUncaughtExceptionHandler);
248 |
249 | [self setStdOutToStdErrRedirectEnabled:NO];
250 |
251 | [self stopCapturingLogs];
252 | }
253 |
254 | - (void)setStdOutToStdErrRedirectEnabled:(BOOL)redirectEnabled
255 | {
256 | if (redirectEnabled) {
257 | int stdOutDup = dup(STDOUT_FILENO);
258 | dup2(STDERR_FILENO, STDOUT_FILENO);
259 | self.stdOutDup = stdOutDup;
260 | } else {
261 | dup2(self.stdOutDup, STDOUT_FILENO);
262 | close(self.stdOutDup);
263 | }
264 |
265 | self.stdOutToStdErrRedirectEnabledImp = redirectEnabled;
266 | }
267 |
268 | - (BOOL)stdOutToStdErrRedirectEnabled
269 | {
270 | return self.stdOutToStdErrRedirectEnabledImp;
271 | }
272 |
273 | @end
274 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogReviewViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 |
15 | @interface CCLogReviewViewController : UIViewController
16 |
17 | - (id)initWithLogPathURL:(NSURL *)logPathURL;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogReviewViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLogReviewViewController.h"
14 | #import "CCLogSystem.h"
15 |
16 | @import MessageUI;
17 |
18 | @interface CCLogReviewViewController ()
19 |
20 | @property (nonatomic, strong) NSURL *currentLogPathURL;
21 |
22 | @property (nonatomic, strong) UIWebView *webView;
23 |
24 | @end
25 |
26 | @implementation CCLogReviewViewController
27 |
28 | - (id)initWithLogPathURL:(NSURL *)logPathURL;
29 | {
30 | self = [super init];
31 | if (self) {
32 | self.currentLogPathURL = logPathURL;
33 |
34 | self.title = [self.currentLogPathURL lastPathComponent];
35 | }
36 | return self;
37 | }
38 |
39 | - (void)viewDidLoad
40 | {
41 | [super viewDidLoad];
42 |
43 | self.webView = [[UIWebView alloc] initWithFrame:CGRectZero];
44 | self.webView.backgroundColor = [UIColor whiteColor];
45 | self.webView.translatesAutoresizingMaskIntoConstraints = NO;
46 | self.webView.delegate = self;
47 | [self.view addSubview:self.webView];
48 |
49 | NSDictionary *views = NSDictionaryOfVariableBindings(_webView);
50 | NSMutableArray *constraits = [NSMutableArray array];
51 | [constraits addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_webView]|" options:0 metrics:nil views:views]];
52 | [constraits addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_webView]|" options:0 metrics:nil views:views]];
53 | [self.view addConstraints:constraits];
54 |
55 | [self loadLogData];
56 |
57 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Email" style:UIBarButtonItemStylePlain target:self action:@selector(handleEmailBarButtonItem)];
58 | }
59 |
60 | #pragma mark - Private
61 |
62 | - (void)handleEmailBarButtonItem
63 | {
64 | if ([MFMailComposeViewController canSendMail]) {
65 | MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
66 | NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
67 | NSString *appVersion = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
68 | NSString *appBuild = [infoDictionary objectForKey:@"CFBundleVersion"];
69 | NSString *processName = [NSProcessInfo processInfo].processName;
70 | [mailController setSubject:[NSString stringWithFormat:@"%@ Log Report ", processName, appVersion, appBuild]];
71 | [mailController setMailComposeDelegate:self];
72 |
73 | NSData *logData = [[NSData alloc] initWithContentsOfURL:self.currentLogPathURL];
74 | [mailController addAttachmentData:logData mimeType:@"com.apple.log" fileName:self.currentLogPathURL.lastPathComponent];
75 |
76 | [self presentViewController:mailController animated:YES completion:NULL];
77 | } else {
78 | [[[UIAlertView alloc] initWithTitle:@"" message:@"Configure your email account in iOS Settings." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
79 | }
80 | }
81 |
82 | - (void)loadLogData
83 | {
84 | [self.webView loadRequest:[NSURLRequest requestWithURL:self.currentLogPathURL]];
85 | }
86 |
87 | #pragma mark - MFMailComposeViewControllerDelegate
88 |
89 | - (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
90 | {
91 | [controller dismissViewControllerAnimated:YES completion:NULL];
92 | }
93 |
94 | #pragma mark - UIWebViewDelegate
95 |
96 | - (void)webViewDidFinishLoad:(UIWebView *)webView
97 | {
98 | CGSize webviewContentSize = webView.scrollView.contentSize;
99 | [webView.scrollView scrollRectToVisible:CGRectMake(0, webviewContentSize.height - webView.bounds.size.height, webView.bounds.size.width, webView.bounds.size.height) animated:NO];
100 | }
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogStringImp.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLog.h"
14 |
15 | // Use fprintf
16 | CC_EXTERN void CCLogStringToStderr (CCLocation location, NSString *string);
17 |
18 | // Use NSLog
19 | CC_EXTERN void CCLogStringToNSLog (CCLocation location, NSString *string);
20 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogStringImp.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLogStringImp.h"
14 | #import "CCLocationMake.h"
15 |
16 | #pragma mark - Private
17 |
18 | static NSDateFormatter *regeneratedLogDateFormatter (void)
19 | {
20 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
21 | dateFormatter.locale = [NSLocale currentLocale];
22 | dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS";
23 | return dateFormatter;
24 | }
25 |
26 | static NSObject *CCNullForZeroLengthString (NSString *string)
27 | {
28 | return [string length] ? string : [NSNull null];
29 | }
30 |
31 | static NSString *stringWithLogInfo (CCLocation location, NSString *logInfo)
32 | {
33 | NSString *body = [[NSArray arrayWithObjects:@".", CCNullForZeroLengthString(CCLogPrefixFromLocation(location)), logInfo, nil] componentsJoinedByString:@" "];
34 |
35 | NSString *timestamp = [regeneratedLogDateFormatter() stringFromDate:[NSDate date]];
36 |
37 | NSString *string = [NSString stringWithFormat:@"%@ %@", timestamp, body];
38 |
39 | return string;
40 | }
41 |
42 | #pragma mark - Public
43 |
44 | void CCLogStringToNSLog (CCLocation location, NSString *string)
45 | {
46 | NSString *logString = stringWithLogInfo(location, string);
47 | NSLog(@"%@", logString);
48 | }
49 |
50 | void CCLogStringToStderr (CCLocation location, NSString *string)
51 | {
52 | NSString *logString = stringWithLogInfo(location, string);
53 | fprintf (stderr, "%s\n", [logString UTF8String]);
54 | }
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogSystem.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 | #import "CCLog.h"
15 |
16 | // Support two types for logging, CCLog and NSLog.
17 | // CCLog uses 'fprintf'
18 | typedef NS_ENUM(NSInteger, CCLogType) {
19 | CCLogTypeCCLOG = 0,
20 | CCLogTypeNSLOG,
21 | };
22 |
23 | // Use this Macro to log
24 | // Like: CC_LOG(@"This is a Log.");
25 | // The default output is "Timestamp + Thread Info + FILE + LINE + FUNCTION + Log content", like: "2014-10-31 10:09:05.361 . {number = 1, name = main} AppDelegate.m at 24 (-[AppDelegate log]): @"Thi is a Log"
26 | #define CC_LOG(...) \
27 | CCLog (CC_LOCATION(), __VA_ARGS__)
28 |
29 | // Use this Macro to directly log any value
30 | // Like CC_LOG_VALUE(self.window) or CC_LOG_VALUE(self.window.frame)
31 | #define CC_LOG_VALUE(...) \
32 | CC_LOG(@"%@", CC_STRING_FOR_LOG_VALUE(__VA_ARGS__))
33 |
34 | @interface CCLogSystem : NSObject
35 |
36 | // Set up default log configure, the default exceedint total log size is 10*1024*1024, ang logType is CCLogTypeCCLOG
37 | // We should call this function at "- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions"
38 | + (void)setupDefaultLogConfigure;
39 |
40 | // We need to set up the log environment when our app launch
41 | // totalLogSize : exceeding total log size, If log size is more than toalLogSize, will do some clean.
42 | // logType: Support CCLogTypeCCLOG and CCLogTypeNSLOG
43 | + (void)setupLogConfigureWithExceedingTotalLogSize:(unsigned long long)toalLogSize logType:(CCLogType)logType;
44 |
45 | // Call this method, If we want to review the logs, and we can email the log in Developer UI.
46 | + (void)activeDeveloperUI;
47 |
48 | // Return the available logs
49 | // If must call after setup log environment
50 | + (NSArray *)availableLogs;
51 |
52 | @end
53 |
54 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogSystem.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLogSystem.h"
14 | #import "CCLogController.h"
15 | #import "CCLogController+Utility.h"
16 | #import "CCTeeController.h"
17 | #import "CCSimpleFileOutputRedirectionController.h"
18 | #import "CCLogViewController.h"
19 | #import "CCLogController.h"
20 |
21 | #define DEFAULT_EXCEEDING_TOTAL_LOG_SIZE 10*1024*1024
22 |
23 | @interface CCLogSystem ()
24 |
25 | @property (nonatomic, strong) CCLogController *logController;
26 |
27 | @property (nonatomic, strong) NSObject *redirectionController;
28 |
29 | @end
30 |
31 | @implementation CCLogSystem
32 |
33 | + (CCLogSystem *)defaultLogSystem
34 | {
35 | static dispatch_once_t onceToken;
36 | static CCLogSystem *_defaultLogConfigure;
37 | dispatch_once(&onceToken, ^{
38 | _defaultLogConfigure = [[self alloc] init];
39 | });
40 | return _defaultLogConfigure;
41 | }
42 |
43 | - (id)init
44 | {
45 | self = [super init];
46 | if (self) {
47 | self.logController = [[CCLogController alloc] init];
48 | }
49 | return self;
50 | }
51 |
52 | + (void)setupDefaultLogConfigure
53 | {
54 | [self setupLogConfigureWithExceedingTotalLogSize:DEFAULT_EXCEEDING_TOTAL_LOG_SIZE logType:CCLogTypeCCLOG];
55 | }
56 |
57 | + (void)setupLogConfigureWithExceedingTotalLogSize:(unsigned long long)toalLogSize logType:(CCLogType)logType
58 | {
59 | CCLogSystem *logConfigure = [CCLogSystem defaultLogSystem];
60 |
61 | [logConfigure.logController removeOldLogsExceedingTotalSize:toalLogSize savingAtLeast:10];
62 |
63 | if (!logConfigure.redirectionController) {
64 | if ([CCLogController forceConsoleLog]) {
65 | logConfigure.redirectionController = [[CCTeeController alloc] init];
66 | } else {
67 | logConfigure.redirectionController = [[CCSimpleFileOutputRedirectionController alloc] init];
68 | }
69 | [logConfigure.logController startCapturingLogsWithRedirectionController:logConfigure.redirectionController logType:logType];
70 | [logConfigure.redirectionController startRecordLog];
71 | }
72 | }
73 |
74 | + (void)activeDeveloperUI
75 | {
76 | CCLogViewController *logViewController = [[CCLogViewController alloc] init];
77 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:logViewController];
78 |
79 | UIApplication *application = [UIApplication sharedApplication];
80 | [application.windows enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
81 | if ([obj isKeyWindow]) {
82 | UIWindow *keyWindow = obj;
83 | if (keyWindow.rootViewController) {
84 | [keyWindow.rootViewController presentViewController:navigationController animated:YES completion:NULL];
85 | }
86 | }
87 | }];
88 | }
89 |
90 | + (NSArray *)availableLogs
91 | {
92 | if ([CCLogSystem defaultLogSystem].logController) {
93 | return [CCLogSystem defaultLogSystem].logController.availableLogs;
94 | } else {
95 | return nil;
96 | }
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 |
15 | @interface CCLogViewController : UITableViewController
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCLogViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCLogViewController.h"
14 | #import "CCLogController.h"
15 | #import "CCLogSystem.h"
16 | #import "CCLogReviewViewController.h"
17 |
18 | static NSString *UITableViewCellReuseIdentifier = @"UITableViewCell";
19 |
20 | @interface CCLogViewController ()
21 |
22 | @property (nonatomic, strong) NSMutableArray *logDatas;
23 |
24 | @end
25 |
26 | @implementation CCLogViewController
27 |
28 | #pragma mark - Life
29 |
30 | - (id)initWithStyle:(UITableViewStyle)style
31 | {
32 | self = [super initWithStyle:UITableViewStylePlain];
33 | if (self) {
34 | self.title = @"Developer UI";
35 |
36 | self.logDatas = [NSMutableArray array];
37 | [self.logDatas addObjectsFromArray:[CCLogSystem availableLogs]];
38 | }
39 | return self;
40 | }
41 |
42 | - (void)viewDidLoad
43 | {
44 | [super viewDidLoad];
45 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(handleCloseBarButtonitem)];
46 | }
47 |
48 | #pragma mark - Private
49 |
50 | - (NSString *)logPathStringWithIndexPath:(NSIndexPath *)indexPath
51 | {
52 | return [self.logDatas objectAtIndex:indexPath.row];
53 | }
54 |
55 | - (void)handleCloseBarButtonitem
56 | {
57 | [self dismissViewControllerAnimated:YES completion:NULL];
58 | }
59 |
60 | #pragma mark - UITableView
61 |
62 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
63 | {
64 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:UITableViewCellReuseIdentifier];
65 | if (!cell) {
66 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:UITableViewCellReuseIdentifier];
67 | }
68 | NSString *logPath = [self logPathStringWithIndexPath:indexPath];
69 | cell.textLabel.text = [logPath lastPathComponent];
70 | cell.textLabel.numberOfLines = 0;
71 | return cell;
72 | }
73 |
74 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
75 | {
76 | return self.logDatas.count;
77 | }
78 |
79 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
80 | {
81 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
82 |
83 | NSString *logPathString = [self logPathStringWithIndexPath:indexPath];
84 | NSURL *logPathURL = [NSURL fileURLWithPath:logPathString];
85 | CCLogReviewViewController *logReviewViewController = [[CCLogReviewViewController alloc] initWithLogPathURL:logPathURL];
86 | [self.navigationController pushViewController:logReviewViewController animated:YES];
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCSimpleFileOutputRedirectionController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 | #import "CCFileOutputRedirectionController.h"
15 |
16 | @interface CCSimpleFileOutputRedirectionController : NSObject
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCSimpleFileOutputRedirectionController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCSimpleFileOutputRedirectionController.h"
14 |
15 | @interface CCSimpleFileOutputRedirectionController ()
16 |
17 | @property (nonatomic, strong) NSFileHandle *inputFileHandleDup;
18 |
19 | @end
20 |
21 | @implementation CCSimpleFileOutputRedirectionController
22 | @synthesize inputFileHandle;
23 | @synthesize outputFileHandle;
24 |
25 | - (void)startRecordLog
26 | {
27 | int inputFileDescriptionDup = dup(self.inputFileHandle.fileDescriptor);
28 | dup2(self.outputFileHandle.fileDescriptor, self.inputFileHandle.fileDescriptor);
29 |
30 | self.inputFileHandleDup = [[NSFileHandle alloc] initWithFileDescriptor:inputFileDescriptionDup];
31 | }
32 |
33 | - (void)stopRecordLog
34 | {
35 | dup2(self.inputFileHandleDup.fileDescriptor, self.inputFileHandle.fileDescriptor);
36 | self.inputFileHandleDup = nil;
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCTeeController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 | #import "CCFileOutputRedirectionController.h"
15 |
16 | @interface CCTeeController : NSObject
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/CCTeeController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "CCTeeController.h"
14 | #import
15 | #import
16 | #import
17 | #import
18 | #import
19 | #import
20 | #import "CCLogSystem.h"
21 |
22 | @interface CCTeeController ()
23 |
24 | @property (nonatomic, strong) NSPipe *dataPipe;
25 |
26 | @property (nonatomic, strong) NSPipe *pipeForSignallingEOF;
27 |
28 | @property (nonatomic, strong) NSOperation *operation;
29 |
30 | @property (nonatomic, strong) NSOperationQueue *operationQueue;
31 |
32 | @property (nonatomic, strong) NSFileHandle *inputFileHandleDup;
33 |
34 | @property (nonatomic) BOOL closingInputFileHandleDup;
35 |
36 | @end
37 |
38 | @implementation CCTeeController
39 | @synthesize inputFileHandle;
40 | @synthesize outputFileHandle;
41 |
42 | - (void)startRecordLog
43 | {
44 | NSPipe *pipe = [NSPipe pipe];
45 |
46 | int inputFileDescriptionDup = dup(self.inputFileHandle.fileDescriptor);
47 | dup2(pipe.fileHandleForWriting.fileDescriptor, self.inputFileHandle.fileDescriptor);
48 |
49 | self.dataPipe = pipe;
50 |
51 | self.inputFileHandleDup = [[NSFileHandle alloc] initWithFileDescriptor:inputFileDescriptionDup];
52 |
53 | self.pipeForSignallingEOF = [NSPipe pipe];
54 |
55 | self.operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(thread:) object:nil];
56 | self.operationQueue = [[NSOperationQueue alloc] init];
57 | [self.operationQueue addOperation:self.operation];
58 | }
59 |
60 | - (void)stopRecordLog
61 | {
62 | self.closingInputFileHandleDup = YES;
63 |
64 | [self.pipeForSignallingEOF.fileHandleForWriting writeData:[@"" dataUsingEncoding: NSUTF8StringEncoding]];
65 |
66 | [self.operationQueue waitUntilAllOperationsAreFinished];
67 |
68 | [self.dataPipe.fileHandleForWriting closeFile];
69 |
70 | dup2(self.inputFileHandleDup.fileDescriptor, self.inputFileHandle.fileDescriptor);
71 |
72 | self.closingInputFileHandleDup = NO;
73 |
74 | self.inputFileHandleDup = nil;
75 |
76 | self.dataPipe = nil;
77 | self.pipeForSignallingEOF = nil;
78 | }
79 |
80 | #pragma mark -
81 | #pragma mark - Thread
82 |
83 | - (void)thread:(NSDictionary *)arg
84 | {
85 | @autoreleasepool {
86 | BOOL shouldTerminate = NO;
87 |
88 | NSFileHandle *fileHandleForReading = self.dataPipe.fileHandleForReading;
89 | NSFileHandle *fileHandleForSignallingEOF = self.pipeForSignallingEOF.fileHandleForReading;
90 |
91 | int kq = kqueue();
92 |
93 | NSFileHandle *kqueueFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:kq closeOnDealloc:YES];
94 |
95 | struct kevent changes[2];
96 | EV_SET (&changes[0], fileHandleForReading.fileDescriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
97 | EV_SET (&changes[1], fileHandleForSignallingEOF.fileDescriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
98 |
99 | while (!shouldTerminate) {
100 | BOOL hasEOF;
101 | BOOL hasData;
102 | NSUInteger availableDataLength;
103 | BOOL hasPOSIXError;
104 | NSInteger POSIXError;
105 | struct kevent event;
106 |
107 | int numberOfEvents = kevent (kqueueFileHandle.fileDescriptor, changes, sizeof (changes) / sizeof (changes[0]), &event, 1, NULL);
108 |
109 | if (-1 == numberOfEvents) {
110 | availableDataLength = 0;
111 | hasData = NO;
112 | hasEOF = NO;
113 | hasPOSIXError = YES;
114 | POSIXError = errno;
115 | } else if (0 == numberOfEvents) {
116 | availableDataLength = 0;
117 | hasData = NO;
118 | hasEOF = NO;
119 | hasPOSIXError = NO;
120 | POSIXError = 0;
121 | } else if (1 < numberOfEvents) {
122 | abort ();
123 | } else if (EV_ERROR & event.flags) {
124 | availableDataLength = 0;
125 | hasData = NO;
126 | hasEOF = NO;
127 | hasPOSIXError = YES;
128 | POSIXError = event.data;
129 | } else if (event.ident == (uintptr_t)fileHandleForReading.fileDescriptor) {
130 | hasData = 0 != event.data;
131 | availableDataLength = event.data;
132 | hasEOF = 0 != (EV_EOF & event.flags);
133 | hasPOSIXError = NO;
134 | POSIXError = 0;
135 | } else if (event.ident == (uintptr_t)fileHandleForSignallingEOF.fileDescriptor) {
136 | hasData = NO;
137 | availableDataLength = 0;
138 | hasEOF = 0 != event.data;
139 | hasPOSIXError = NO;
140 | POSIXError = 0;
141 | } else {
142 | abort ();
143 | }
144 |
145 | shouldTerminate = hasEOF || hasPOSIXError;
146 |
147 | if (hasPOSIXError) {
148 | CC_LOG_VALUE(POSIXError);
149 | }
150 |
151 | if (hasData) {
152 | NSData *data = [fileHandleForReading readDataOfLength:availableDataLength];
153 | [self.outputFileHandle writeData:data];
154 | if (hasEOF) {
155 | [self.inputFileHandle writeData:data];
156 | } else {
157 | [self.inputFileHandleDup writeData:data];
158 | }
159 | }
160 | }
161 | }
162 | }
163 |
164 | @end
165 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/NSObject+CCReverseComparison.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import
14 |
15 | @interface NSObject (CCReverseComparison)
16 |
17 | - (NSComparisonResult)reverseCompare:(id)object;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystem/NSObject+CCReverseComparison.m:
--------------------------------------------------------------------------------
1 | /*
2 | * CCLogSystem - A Log system for iOS.Support print, record and review logs:
3 | *
4 | * https://github.com/yechunjun/CCLogSystem
5 | *
6 | * This code is distributed under the terms and conditions of the MIT license.
7 | *
8 | * Author:
9 | * Chun Ye
10 | *
11 | */
12 |
13 | #import "NSObject+CCReverseComparison.h"
14 | #import "CCLogSystem.h"
15 |
16 | @interface NSObject (CCComparison)
17 |
18 | - (NSComparisonResult)compare:(id)object;
19 |
20 | @end
21 |
22 | @implementation NSObject (CCReverseComparison)
23 |
24 | - (NSComparisonResult)reverseCompare:(id)object
25 | {
26 | NSComparisonResult directComparisonResult = NSOrderedSame;
27 | if ([self respondsToSelector:@selector(compare:)]) {
28 | directComparisonResult = [self compare: object];
29 | NSComparisonResult comparisonResult = (NSOrderedAscending == directComparisonResult)
30 | ? (NSComparisonResult) NSOrderedDescending
31 | : ((NSOrderedDescending == directComparisonResult)
32 | ? (NSComparisonResult) NSOrderedAscending
33 | : directComparisonResult);
34 |
35 | return comparisonResult;
36 | } else {
37 | CC_LOG(@"!!! %@ -> This object didn't implement \"comare\" function.", self);
38 | return directComparisonResult;
39 | }
40 | }
41 |
42 | @end
43 |
44 |
--------------------------------------------------------------------------------
/CCLogSystem/CCLogSystemTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | chun.tips.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3465FADF1A033593007632EF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3465FADE1A033593007632EF /* main.m */; };
11 | 3465FAE21A033593007632EF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3465FAE11A033593007632EF /* AppDelegate.m */; };
12 | 3465FAE51A033593007632EF /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3465FAE41A033593007632EF /* ViewController.m */; };
13 | 3465FAE81A033593007632EF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3465FAE61A033593007632EF /* Main.storyboard */; };
14 | 3465FAEA1A033593007632EF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3465FAE91A033593007632EF /* Images.xcassets */; };
15 | 3465FAED1A033593007632EF /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3465FAEB1A033593007632EF /* LaunchScreen.xib */; };
16 | 3465FAF91A033593007632EF /* CCLogSystemDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3465FAF81A033593007632EF /* CCLogSystemDemoTests.m */; };
17 | 3467CAB81A03658F00DA6C84 /* CCLocationMake.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAA31A03658F00DA6C84 /* CCLocationMake.m */; };
18 | 3467CAB91A03658F00DA6C84 /* CCLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAA51A03658F00DA6C84 /* CCLog.m */; };
19 | 3467CABA1A03658F00DA6C84 /* CCLogController+Utility.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAA71A03658F00DA6C84 /* CCLogController+Utility.m */; };
20 | 3467CABB1A03658F00DA6C84 /* CCLogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAA91A03658F00DA6C84 /* CCLogController.m */; };
21 | 3467CABC1A03658F00DA6C84 /* CCLogReviewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAAB1A03658F00DA6C84 /* CCLogReviewViewController.m */; };
22 | 3467CABD1A03658F00DA6C84 /* CCLogStringImp.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAAD1A03658F00DA6C84 /* CCLogStringImp.m */; };
23 | 3467CABE1A03658F00DA6C84 /* CCLogSystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAAF1A03658F00DA6C84 /* CCLogSystem.m */; };
24 | 3467CABF1A03658F00DA6C84 /* CCLogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAB11A03658F00DA6C84 /* CCLogViewController.m */; };
25 | 3467CAC01A03658F00DA6C84 /* CCSimpleFileOutputRedirectionController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAB31A03658F00DA6C84 /* CCSimpleFileOutputRedirectionController.m */; };
26 | 3467CAC11A03658F00DA6C84 /* CCTeeController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAB51A03658F00DA6C84 /* CCTeeController.m */; };
27 | 3467CAC21A03658F00DA6C84 /* NSObject+CCReverseComparison.m in Sources */ = {isa = PBXBuildFile; fileRef = 3467CAB71A03658F00DA6C84 /* NSObject+CCReverseComparison.m */; };
28 | /* End PBXBuildFile section */
29 |
30 | /* Begin PBXContainerItemProxy section */
31 | 3465FAF31A033593007632EF /* PBXContainerItemProxy */ = {
32 | isa = PBXContainerItemProxy;
33 | containerPortal = 3465FAD11A033593007632EF /* Project object */;
34 | proxyType = 1;
35 | remoteGlobalIDString = 3465FAD81A033593007632EF;
36 | remoteInfo = CCLogSystemDemo;
37 | };
38 | /* End PBXContainerItemProxy section */
39 |
40 | /* Begin PBXFileReference section */
41 | 3465FAD91A033593007632EF /* CCLogSystemDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CCLogSystemDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 3465FADD1A033593007632EF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
43 | 3465FADE1A033593007632EF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
44 | 3465FAE01A033593007632EF /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
45 | 3465FAE11A033593007632EF /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
46 | 3465FAE31A033593007632EF /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
47 | 3465FAE41A033593007632EF /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
48 | 3465FAE71A033593007632EF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
49 | 3465FAE91A033593007632EF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
50 | 3465FAEC1A033593007632EF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
51 | 3465FAF21A033593007632EF /* CCLogSystemDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CCLogSystemDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 3465FAF71A033593007632EF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
53 | 3465FAF81A033593007632EF /* CCLogSystemDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CCLogSystemDemoTests.m; sourceTree = ""; };
54 | 3467CAA11A03658F00DA6C84 /* CCFileOutputRedirectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCFileOutputRedirectionController.h; sourceTree = ""; };
55 | 3467CAA21A03658F00DA6C84 /* CCLocationMake.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLocationMake.h; sourceTree = ""; };
56 | 3467CAA31A03658F00DA6C84 /* CCLocationMake.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLocationMake.m; sourceTree = ""; };
57 | 3467CAA41A03658F00DA6C84 /* CCLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLog.h; sourceTree = ""; };
58 | 3467CAA51A03658F00DA6C84 /* CCLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLog.m; sourceTree = ""; };
59 | 3467CAA61A03658F00DA6C84 /* CCLogController+Utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CCLogController+Utility.h"; sourceTree = ""; };
60 | 3467CAA71A03658F00DA6C84 /* CCLogController+Utility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CCLogController+Utility.m"; sourceTree = ""; };
61 | 3467CAA81A03658F00DA6C84 /* CCLogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogController.h; sourceTree = ""; };
62 | 3467CAA91A03658F00DA6C84 /* CCLogController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogController.m; sourceTree = ""; };
63 | 3467CAAA1A03658F00DA6C84 /* CCLogReviewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogReviewViewController.h; sourceTree = ""; };
64 | 3467CAAB1A03658F00DA6C84 /* CCLogReviewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogReviewViewController.m; sourceTree = ""; };
65 | 3467CAAC1A03658F00DA6C84 /* CCLogStringImp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogStringImp.h; sourceTree = ""; };
66 | 3467CAAD1A03658F00DA6C84 /* CCLogStringImp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogStringImp.m; sourceTree = ""; };
67 | 3467CAAE1A03658F00DA6C84 /* CCLogSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogSystem.h; sourceTree = ""; };
68 | 3467CAAF1A03658F00DA6C84 /* CCLogSystem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogSystem.m; sourceTree = ""; };
69 | 3467CAB01A03658F00DA6C84 /* CCLogViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLogViewController.h; sourceTree = ""; };
70 | 3467CAB11A03658F00DA6C84 /* CCLogViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCLogViewController.m; sourceTree = ""; };
71 | 3467CAB21A03658F00DA6C84 /* CCSimpleFileOutputRedirectionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSimpleFileOutputRedirectionController.h; sourceTree = ""; };
72 | 3467CAB31A03658F00DA6C84 /* CCSimpleFileOutputRedirectionController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCSimpleFileOutputRedirectionController.m; sourceTree = ""; };
73 | 3467CAB41A03658F00DA6C84 /* CCTeeController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTeeController.h; sourceTree = ""; };
74 | 3467CAB51A03658F00DA6C84 /* CCTeeController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCTeeController.m; sourceTree = ""; };
75 | 3467CAB61A03658F00DA6C84 /* NSObject+CCReverseComparison.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+CCReverseComparison.h"; sourceTree = ""; };
76 | 3467CAB71A03658F00DA6C84 /* NSObject+CCReverseComparison.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+CCReverseComparison.m"; sourceTree = ""; };
77 | /* End PBXFileReference section */
78 |
79 | /* Begin PBXFrameworksBuildPhase section */
80 | 3465FAD61A033593007632EF /* Frameworks */ = {
81 | isa = PBXFrameworksBuildPhase;
82 | buildActionMask = 2147483647;
83 | files = (
84 | );
85 | runOnlyForDeploymentPostprocessing = 0;
86 | };
87 | 3465FAEF1A033593007632EF /* Frameworks */ = {
88 | isa = PBXFrameworksBuildPhase;
89 | buildActionMask = 2147483647;
90 | files = (
91 | );
92 | runOnlyForDeploymentPostprocessing = 0;
93 | };
94 | /* End PBXFrameworksBuildPhase section */
95 |
96 | /* Begin PBXGroup section */
97 | 3465FAD01A033593007632EF = {
98 | isa = PBXGroup;
99 | children = (
100 | 3465FADB1A033593007632EF /* CCLogSystemDemo */,
101 | 3465FAF51A033593007632EF /* CCLogSystemDemoTests */,
102 | 3465FADA1A033593007632EF /* Products */,
103 | );
104 | sourceTree = "";
105 | };
106 | 3465FADA1A033593007632EF /* Products */ = {
107 | isa = PBXGroup;
108 | children = (
109 | 3465FAD91A033593007632EF /* CCLogSystemDemo.app */,
110 | 3465FAF21A033593007632EF /* CCLogSystemDemoTests.xctest */,
111 | );
112 | name = Products;
113 | sourceTree = "";
114 | };
115 | 3465FADB1A033593007632EF /* CCLogSystemDemo */ = {
116 | isa = PBXGroup;
117 | children = (
118 | 3467CAA01A03658F00DA6C84 /* CCLogSystem */,
119 | 3465FAE01A033593007632EF /* AppDelegate.h */,
120 | 3465FAE11A033593007632EF /* AppDelegate.m */,
121 | 3465FAE31A033593007632EF /* ViewController.h */,
122 | 3465FAE41A033593007632EF /* ViewController.m */,
123 | 3465FAE61A033593007632EF /* Main.storyboard */,
124 | 3465FAE91A033593007632EF /* Images.xcassets */,
125 | 3465FAEB1A033593007632EF /* LaunchScreen.xib */,
126 | 3465FADC1A033593007632EF /* Supporting Files */,
127 | );
128 | path = CCLogSystemDemo;
129 | sourceTree = "";
130 | };
131 | 3465FADC1A033593007632EF /* Supporting Files */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 3465FADD1A033593007632EF /* Info.plist */,
135 | 3465FADE1A033593007632EF /* main.m */,
136 | );
137 | name = "Supporting Files";
138 | sourceTree = "";
139 | };
140 | 3465FAF51A033593007632EF /* CCLogSystemDemoTests */ = {
141 | isa = PBXGroup;
142 | children = (
143 | 3465FAF81A033593007632EF /* CCLogSystemDemoTests.m */,
144 | 3465FAF61A033593007632EF /* Supporting Files */,
145 | );
146 | path = CCLogSystemDemoTests;
147 | sourceTree = "";
148 | };
149 | 3465FAF61A033593007632EF /* Supporting Files */ = {
150 | isa = PBXGroup;
151 | children = (
152 | 3465FAF71A033593007632EF /* Info.plist */,
153 | );
154 | name = "Supporting Files";
155 | sourceTree = "";
156 | };
157 | 3467CAA01A03658F00DA6C84 /* CCLogSystem */ = {
158 | isa = PBXGroup;
159 | children = (
160 | 3467CAAE1A03658F00DA6C84 /* CCLogSystem.h */,
161 | 3467CAAF1A03658F00DA6C84 /* CCLogSystem.m */,
162 | 3467CAA41A03658F00DA6C84 /* CCLog.h */,
163 | 3467CAA51A03658F00DA6C84 /* CCLog.m */,
164 | 3467CAA81A03658F00DA6C84 /* CCLogController.h */,
165 | 3467CAA91A03658F00DA6C84 /* CCLogController.m */,
166 | 3467CAA61A03658F00DA6C84 /* CCLogController+Utility.h */,
167 | 3467CAA71A03658F00DA6C84 /* CCLogController+Utility.m */,
168 | 3467CAB01A03658F00DA6C84 /* CCLogViewController.h */,
169 | 3467CAB11A03658F00DA6C84 /* CCLogViewController.m */,
170 | 3467CAAA1A03658F00DA6C84 /* CCLogReviewViewController.h */,
171 | 3467CAAB1A03658F00DA6C84 /* CCLogReviewViewController.m */,
172 | 3467CAA11A03658F00DA6C84 /* CCFileOutputRedirectionController.h */,
173 | 3467CAB21A03658F00DA6C84 /* CCSimpleFileOutputRedirectionController.h */,
174 | 3467CAB31A03658F00DA6C84 /* CCSimpleFileOutputRedirectionController.m */,
175 | 3467CAB41A03658F00DA6C84 /* CCTeeController.h */,
176 | 3467CAB51A03658F00DA6C84 /* CCTeeController.m */,
177 | 3467CAB61A03658F00DA6C84 /* NSObject+CCReverseComparison.h */,
178 | 3467CAB71A03658F00DA6C84 /* NSObject+CCReverseComparison.m */,
179 | 3467CAAC1A03658F00DA6C84 /* CCLogStringImp.h */,
180 | 3467CAAD1A03658F00DA6C84 /* CCLogStringImp.m */,
181 | 3467CAA21A03658F00DA6C84 /* CCLocationMake.h */,
182 | 3467CAA31A03658F00DA6C84 /* CCLocationMake.m */,
183 | );
184 | name = CCLogSystem;
185 | path = ../../CCLogSystem/CCLogSystem;
186 | sourceTree = "";
187 | };
188 | /* End PBXGroup section */
189 |
190 | /* Begin PBXNativeTarget section */
191 | 3465FAD81A033593007632EF /* CCLogSystemDemo */ = {
192 | isa = PBXNativeTarget;
193 | buildConfigurationList = 3465FAFC1A033593007632EF /* Build configuration list for PBXNativeTarget "CCLogSystemDemo" */;
194 | buildPhases = (
195 | 3465FAD51A033593007632EF /* Sources */,
196 | 3465FAD61A033593007632EF /* Frameworks */,
197 | 3465FAD71A033593007632EF /* Resources */,
198 | );
199 | buildRules = (
200 | );
201 | dependencies = (
202 | );
203 | name = CCLogSystemDemo;
204 | productName = CCLogSystemDemo;
205 | productReference = 3465FAD91A033593007632EF /* CCLogSystemDemo.app */;
206 | productType = "com.apple.product-type.application";
207 | };
208 | 3465FAF11A033593007632EF /* CCLogSystemDemoTests */ = {
209 | isa = PBXNativeTarget;
210 | buildConfigurationList = 3465FAFF1A033593007632EF /* Build configuration list for PBXNativeTarget "CCLogSystemDemoTests" */;
211 | buildPhases = (
212 | 3465FAEE1A033593007632EF /* Sources */,
213 | 3465FAEF1A033593007632EF /* Frameworks */,
214 | 3465FAF01A033593007632EF /* Resources */,
215 | );
216 | buildRules = (
217 | );
218 | dependencies = (
219 | 3465FAF41A033593007632EF /* PBXTargetDependency */,
220 | );
221 | name = CCLogSystemDemoTests;
222 | productName = CCLogSystemDemoTests;
223 | productReference = 3465FAF21A033593007632EF /* CCLogSystemDemoTests.xctest */;
224 | productType = "com.apple.product-type.bundle.unit-test";
225 | };
226 | /* End PBXNativeTarget section */
227 |
228 | /* Begin PBXProject section */
229 | 3465FAD11A033593007632EF /* Project object */ = {
230 | isa = PBXProject;
231 | attributes = {
232 | LastUpgradeCheck = 0610;
233 | ORGANIZATIONNAME = "Chun Tips";
234 | TargetAttributes = {
235 | 3465FAD81A033593007632EF = {
236 | CreatedOnToolsVersion = 6.1;
237 | };
238 | 3465FAF11A033593007632EF = {
239 | CreatedOnToolsVersion = 6.1;
240 | TestTargetID = 3465FAD81A033593007632EF;
241 | };
242 | };
243 | };
244 | buildConfigurationList = 3465FAD41A033593007632EF /* Build configuration list for PBXProject "CCLogSystemDemo" */;
245 | compatibilityVersion = "Xcode 3.2";
246 | developmentRegion = English;
247 | hasScannedForEncodings = 0;
248 | knownRegions = (
249 | en,
250 | Base,
251 | );
252 | mainGroup = 3465FAD01A033593007632EF;
253 | productRefGroup = 3465FADA1A033593007632EF /* Products */;
254 | projectDirPath = "";
255 | projectRoot = "";
256 | targets = (
257 | 3465FAD81A033593007632EF /* CCLogSystemDemo */,
258 | 3465FAF11A033593007632EF /* CCLogSystemDemoTests */,
259 | );
260 | };
261 | /* End PBXProject section */
262 |
263 | /* Begin PBXResourcesBuildPhase section */
264 | 3465FAD71A033593007632EF /* Resources */ = {
265 | isa = PBXResourcesBuildPhase;
266 | buildActionMask = 2147483647;
267 | files = (
268 | 3465FAE81A033593007632EF /* Main.storyboard in Resources */,
269 | 3465FAED1A033593007632EF /* LaunchScreen.xib in Resources */,
270 | 3465FAEA1A033593007632EF /* Images.xcassets in Resources */,
271 | );
272 | runOnlyForDeploymentPostprocessing = 0;
273 | };
274 | 3465FAF01A033593007632EF /* Resources */ = {
275 | isa = PBXResourcesBuildPhase;
276 | buildActionMask = 2147483647;
277 | files = (
278 | );
279 | runOnlyForDeploymentPostprocessing = 0;
280 | };
281 | /* End PBXResourcesBuildPhase section */
282 |
283 | /* Begin PBXSourcesBuildPhase section */
284 | 3465FAD51A033593007632EF /* Sources */ = {
285 | isa = PBXSourcesBuildPhase;
286 | buildActionMask = 2147483647;
287 | files = (
288 | 3467CAB81A03658F00DA6C84 /* CCLocationMake.m in Sources */,
289 | 3467CABD1A03658F00DA6C84 /* CCLogStringImp.m in Sources */,
290 | 3467CABA1A03658F00DA6C84 /* CCLogController+Utility.m in Sources */,
291 | 3467CAC21A03658F00DA6C84 /* NSObject+CCReverseComparison.m in Sources */,
292 | 3467CAC11A03658F00DA6C84 /* CCTeeController.m in Sources */,
293 | 3467CABE1A03658F00DA6C84 /* CCLogSystem.m in Sources */,
294 | 3467CAB91A03658F00DA6C84 /* CCLog.m in Sources */,
295 | 3467CAC01A03658F00DA6C84 /* CCSimpleFileOutputRedirectionController.m in Sources */,
296 | 3467CABB1A03658F00DA6C84 /* CCLogController.m in Sources */,
297 | 3465FAE51A033593007632EF /* ViewController.m in Sources */,
298 | 3465FAE21A033593007632EF /* AppDelegate.m in Sources */,
299 | 3465FADF1A033593007632EF /* main.m in Sources */,
300 | 3467CABF1A03658F00DA6C84 /* CCLogViewController.m in Sources */,
301 | 3467CABC1A03658F00DA6C84 /* CCLogReviewViewController.m in Sources */,
302 | );
303 | runOnlyForDeploymentPostprocessing = 0;
304 | };
305 | 3465FAEE1A033593007632EF /* Sources */ = {
306 | isa = PBXSourcesBuildPhase;
307 | buildActionMask = 2147483647;
308 | files = (
309 | 3465FAF91A033593007632EF /* CCLogSystemDemoTests.m in Sources */,
310 | );
311 | runOnlyForDeploymentPostprocessing = 0;
312 | };
313 | /* End PBXSourcesBuildPhase section */
314 |
315 | /* Begin PBXTargetDependency section */
316 | 3465FAF41A033593007632EF /* PBXTargetDependency */ = {
317 | isa = PBXTargetDependency;
318 | target = 3465FAD81A033593007632EF /* CCLogSystemDemo */;
319 | targetProxy = 3465FAF31A033593007632EF /* PBXContainerItemProxy */;
320 | };
321 | /* End PBXTargetDependency section */
322 |
323 | /* Begin PBXVariantGroup section */
324 | 3465FAE61A033593007632EF /* Main.storyboard */ = {
325 | isa = PBXVariantGroup;
326 | children = (
327 | 3465FAE71A033593007632EF /* Base */,
328 | );
329 | name = Main.storyboard;
330 | sourceTree = "";
331 | };
332 | 3465FAEB1A033593007632EF /* LaunchScreen.xib */ = {
333 | isa = PBXVariantGroup;
334 | children = (
335 | 3465FAEC1A033593007632EF /* Base */,
336 | );
337 | name = LaunchScreen.xib;
338 | sourceTree = "";
339 | };
340 | /* End PBXVariantGroup section */
341 |
342 | /* Begin XCBuildConfiguration section */
343 | 3465FAFA1A033593007632EF /* Debug */ = {
344 | isa = XCBuildConfiguration;
345 | buildSettings = {
346 | ALWAYS_SEARCH_USER_PATHS = NO;
347 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
348 | CLANG_CXX_LIBRARY = "libc++";
349 | CLANG_ENABLE_MODULES = YES;
350 | CLANG_ENABLE_OBJC_ARC = YES;
351 | CLANG_WARN_BOOL_CONVERSION = YES;
352 | CLANG_WARN_CONSTANT_CONVERSION = YES;
353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
354 | CLANG_WARN_EMPTY_BODY = YES;
355 | CLANG_WARN_ENUM_CONVERSION = YES;
356 | CLANG_WARN_INT_CONVERSION = YES;
357 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
358 | CLANG_WARN_UNREACHABLE_CODE = YES;
359 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
360 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
361 | COPY_PHASE_STRIP = NO;
362 | ENABLE_STRICT_OBJC_MSGSEND = YES;
363 | GCC_C_LANGUAGE_STANDARD = gnu99;
364 | GCC_DYNAMIC_NO_PIC = NO;
365 | GCC_OPTIMIZATION_LEVEL = 0;
366 | GCC_PREPROCESSOR_DEFINITIONS = (
367 | "DEBUG=1",
368 | "$(inherited)",
369 | );
370 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
371 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
372 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
373 | GCC_WARN_UNDECLARED_SELECTOR = YES;
374 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
375 | GCC_WARN_UNUSED_FUNCTION = YES;
376 | GCC_WARN_UNUSED_VARIABLE = YES;
377 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
378 | MTL_ENABLE_DEBUG_INFO = YES;
379 | ONLY_ACTIVE_ARCH = YES;
380 | SDKROOT = iphoneos;
381 | TARGETED_DEVICE_FAMILY = "1,2";
382 | };
383 | name = Debug;
384 | };
385 | 3465FAFB1A033593007632EF /* Release */ = {
386 | isa = XCBuildConfiguration;
387 | buildSettings = {
388 | ALWAYS_SEARCH_USER_PATHS = NO;
389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
390 | CLANG_CXX_LIBRARY = "libc++";
391 | CLANG_ENABLE_MODULES = YES;
392 | CLANG_ENABLE_OBJC_ARC = YES;
393 | CLANG_WARN_BOOL_CONVERSION = YES;
394 | CLANG_WARN_CONSTANT_CONVERSION = YES;
395 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
396 | CLANG_WARN_EMPTY_BODY = YES;
397 | CLANG_WARN_ENUM_CONVERSION = YES;
398 | CLANG_WARN_INT_CONVERSION = YES;
399 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
400 | CLANG_WARN_UNREACHABLE_CODE = YES;
401 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
402 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
403 | COPY_PHASE_STRIP = YES;
404 | ENABLE_NS_ASSERTIONS = NO;
405 | ENABLE_STRICT_OBJC_MSGSEND = YES;
406 | GCC_C_LANGUAGE_STANDARD = gnu99;
407 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
408 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
409 | GCC_WARN_UNDECLARED_SELECTOR = YES;
410 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
411 | GCC_WARN_UNUSED_FUNCTION = YES;
412 | GCC_WARN_UNUSED_VARIABLE = YES;
413 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
414 | MTL_ENABLE_DEBUG_INFO = NO;
415 | SDKROOT = iphoneos;
416 | TARGETED_DEVICE_FAMILY = "1,2";
417 | VALIDATE_PRODUCT = YES;
418 | };
419 | name = Release;
420 | };
421 | 3465FAFD1A033593007632EF /* Debug */ = {
422 | isa = XCBuildConfiguration;
423 | buildSettings = {
424 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
425 | INFOPLIST_FILE = CCLogSystemDemo/Info.plist;
426 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
427 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
428 | PRODUCT_NAME = "$(TARGET_NAME)";
429 | };
430 | name = Debug;
431 | };
432 | 3465FAFE1A033593007632EF /* Release */ = {
433 | isa = XCBuildConfiguration;
434 | buildSettings = {
435 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
436 | INFOPLIST_FILE = CCLogSystemDemo/Info.plist;
437 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
439 | PRODUCT_NAME = "$(TARGET_NAME)";
440 | };
441 | name = Release;
442 | };
443 | 3465FB001A033593007632EF /* Debug */ = {
444 | isa = XCBuildConfiguration;
445 | buildSettings = {
446 | BUNDLE_LOADER = "$(TEST_HOST)";
447 | FRAMEWORK_SEARCH_PATHS = (
448 | "$(SDKROOT)/Developer/Library/Frameworks",
449 | "$(inherited)",
450 | );
451 | GCC_PREPROCESSOR_DEFINITIONS = (
452 | "DEBUG=1",
453 | "$(inherited)",
454 | );
455 | INFOPLIST_FILE = CCLogSystemDemoTests/Info.plist;
456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
457 | PRODUCT_NAME = "$(TARGET_NAME)";
458 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CCLogSystemDemo.app/CCLogSystemDemo";
459 | };
460 | name = Debug;
461 | };
462 | 3465FB011A033593007632EF /* Release */ = {
463 | isa = XCBuildConfiguration;
464 | buildSettings = {
465 | BUNDLE_LOADER = "$(TEST_HOST)";
466 | FRAMEWORK_SEARCH_PATHS = (
467 | "$(SDKROOT)/Developer/Library/Frameworks",
468 | "$(inherited)",
469 | );
470 | INFOPLIST_FILE = CCLogSystemDemoTests/Info.plist;
471 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
472 | PRODUCT_NAME = "$(TARGET_NAME)";
473 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CCLogSystemDemo.app/CCLogSystemDemo";
474 | };
475 | name = Release;
476 | };
477 | /* End XCBuildConfiguration section */
478 |
479 | /* Begin XCConfigurationList section */
480 | 3465FAD41A033593007632EF /* Build configuration list for PBXProject "CCLogSystemDemo" */ = {
481 | isa = XCConfigurationList;
482 | buildConfigurations = (
483 | 3465FAFA1A033593007632EF /* Debug */,
484 | 3465FAFB1A033593007632EF /* Release */,
485 | );
486 | defaultConfigurationIsVisible = 0;
487 | defaultConfigurationName = Release;
488 | };
489 | 3465FAFC1A033593007632EF /* Build configuration list for PBXNativeTarget "CCLogSystemDemo" */ = {
490 | isa = XCConfigurationList;
491 | buildConfigurations = (
492 | 3465FAFD1A033593007632EF /* Debug */,
493 | 3465FAFE1A033593007632EF /* Release */,
494 | );
495 | defaultConfigurationIsVisible = 0;
496 | defaultConfigurationName = Release;
497 | };
498 | 3465FAFF1A033593007632EF /* Build configuration list for PBXNativeTarget "CCLogSystemDemoTests" */ = {
499 | isa = XCConfigurationList;
500 | buildConfigurations = (
501 | 3465FB001A033593007632EF /* Debug */,
502 | 3465FB011A033593007632EF /* Release */,
503 | );
504 | defaultConfigurationIsVisible = 0;
505 | defaultConfigurationName = Release;
506 | };
507 | /* End XCConfigurationList section */
508 | };
509 | rootObject = 3465FAD11A033593007632EF /* Project object */;
510 | }
511 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // CCLogSystemDemo
4 | //
5 | // Created by Chun Ye on 10/31/14.
6 | // Copyright (c) 2014 Chun Tips. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // CCLogSystemDemo
4 | //
5 | // Created by Chun Ye on 10/31/14.
6 | // Copyright (c) 2014 Chun Tips. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "CCLogSystem.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 | typedef void (^TestBlock)();
19 |
20 | - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
21 | {
22 | [CCLogSystem setupDefaultLogConfigure];
23 |
24 | CC_LOG(@"%@", application);
25 |
26 | CC_LOG_VALUE(application);
27 |
28 | id applicationTemp = application;
29 | CC_LOG_VALUE(applicationTemp);
30 |
31 | CC_LOG_VALUE(self.window);
32 |
33 | CC_LOG_VALUE(self.window.frame);
34 |
35 | CC_LOG_VALUE(self.window.transform);
36 |
37 | Class applicationClass = NSClassFromString(@"UIApplication");
38 | CC_LOG_VALUE(applicationClass);
39 |
40 | SEL selector = @selector(application:continueUserActivity:restorationHandler:);
41 | CC_LOG_VALUE(selector);
42 |
43 | NSInteger test = 100;
44 | CC_LOG_VALUE(test);
45 |
46 | float test2 = 100.000001;
47 | CC_LOG_VALUE(test2);
48 |
49 | char test3 = 'a';
50 | CC_LOG_VALUE(test3);
51 |
52 | TestBlock testBlock = ^{
53 | };
54 | CC_LOG_VALUE(testBlock);
55 |
56 | NSObject *a = [[NSObject alloc] init];
57 | CC_LOG_VALUE(a);
58 | return YES;
59 | }
60 |
61 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
62 | {
63 | // Override point for customization after application launch.
64 | return YES;
65 | }
66 |
67 | - (void)applicationWillResignActive:(UIApplication *)application {
68 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
69 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
70 | }
71 |
72 | - (void)applicationDidEnterBackground:(UIApplication *)application {
73 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
74 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
75 | }
76 |
77 | - (void)applicationWillEnterForeground:(UIApplication *)application {
78 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
79 | }
80 |
81 | - (void)applicationDidBecomeActive:(UIApplication *)application {
82 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
83 | }
84 |
85 | - (void)applicationWillTerminate:(UIApplication *)application {
86 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
87 | }
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | chun.tips.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // CCLogSystemDemo
4 | //
5 | // Created by Chun Ye on 10/31/14.
6 | // Copyright (c) 2014 Chun Tips. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // CCLogSystemDemo
4 | //
5 | // Created by Chun Ye on 10/31/14.
6 | // Copyright (c) 2014 Chun Tips. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "CCLogSystem.h"
11 |
12 | @interface ViewController ()
13 |
14 | @end
15 |
16 | @implementation ViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
22 | [button setTitle:@"Open Developer UI" forState:UIControlStateNormal];
23 | [button addTarget:self action:@selector(openDeveloperUI) forControlEvents:UIControlEventTouchUpInside];
24 | button.translatesAutoresizingMaskIntoConstraints = NO;
25 | [self.view addSubview:button];
26 |
27 | NSMutableArray *constraits = [NSMutableArray array];
28 | [constraits addObject:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
29 | [constraits addObject:[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
30 | [self.view addConstraints:constraits];
31 | }
32 |
33 | - (void)didReceiveMemoryWarning {
34 | [super didReceiveMemoryWarning];
35 | // Dispose of any resources that can be recreated.
36 | }
37 |
38 | - (void)openDeveloperUI
39 | {
40 | [CCLogSystem activeDeveloperUI];
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // CCLogSystemDemo
4 | //
5 | // Created by Chun Ye on 10/31/14.
6 | // Copyright (c) 2014 Chun Tips. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemoTests/CCLogSystemDemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // CCLogSystemDemoTests.m
3 | // CCLogSystemDemoTests
4 | //
5 | // Created by Chun Ye on 10/31/14.
6 | // Copyright (c) 2014 Chun Tips. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface CCLogSystemDemoTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation CCLogSystemDemoTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/CCLogSystemDemo/CCLogSystemDemoTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | chun.tips.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Chun Ye
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ###CCLogSystem
2 | ***
3 |
4 | CCLogSystem provide an iOS Log System. We can use to replace *NSLog* in our project.And it also provide recording logs to the local file and review or email logs in our app.
5 |
6 | 中文版本请戳: [Chun Tips](http://chun.tips/blog/2014/10/31/fen-xiang-ge-ren-xiang-mu-zhong-de-logxi-tong-cclogsystem/)
7 |
8 | ####Main Features
9 |
10 | * Very simplay API to use
11 | * Use *CC_LOG* to print that get more info. The output info is include "TIMESTAMP" + "THREAD" + "FILE" + "LINE" + "FUNCTION" + origin print info.
12 | * Use *CC_LOG_VALUE* to print any value directly. Like: CC_LOG_VALUE(self.window) or CC_LOG_VALUE(self.window.frame)
13 | * Record crash issue
14 | * Record the logs to the local file
15 | * Provide the Developer UI to review and email the logs in the App
16 |
17 | ####Installation
18 | CCLogSytem is available as a [CocoaPod](http://cocoapods.org/?q=CCLogSystem).
19 |
20 | pod 'CCLogSystem'
21 |
22 | You can also simply copy all the source files located inside CCLogSystem/CCLogSystem/* into your iOS project.
23 |
24 | ####Example
25 |
26 | ###### How to setup CCLogSystem
27 |
28 | - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions: (NSDictionary *)launchOptions
29 | {
30 | [CCLogSystem setupDefaultLogConfigure];
31 | }
32 |
33 | ##### Use CC_LOG macro to print log
34 |
35 | - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
36 | {
37 | [CCLogSystem setupDefaultLogConfigure];
38 |
39 | CC_LOG(@"%@", application);
40 | // print: 2014-10-31 15:28:41.038 . {number = 1, name = main} AppDelegate.m at 24 (-[AppDelegate application:willFinishLaunchingWithOptions:]):
41 | }
42 |
43 | ##### Use CC_LOG_VALUE macro to print any value
44 |
45 | CC_LOG_VALUE(application);
46 |
47 | id applicationTemp = application;
48 | CC_LOG_VALUE(applicationTemp);
49 |
50 | CC_LOG_VALUE(self.window);
51 |
52 | CC_LOG_VALUE(self.window.frame);
53 |
54 | CC_LOG_VALUE(self.window.transform);
55 |
56 | Class applicationClass = NSClassFromString(@"UIApplication");
57 | CC_LOG_VALUE(applicationClass);
58 |
59 | SEL selector = @selector(application:continueUserActivity:restorationHandler:);
60 | CC_LOG_VALUE(selector);
61 |
62 | NSInteger test = 100;
63 | CC_LOG_VALUE(test);
64 |
65 | float test2 = 100.000001;
66 | CC_LOG_VALUE(test2);
67 |
68 | char test3 = 'a';
69 | CC_LOG_VALUE(test3);
70 |
71 | TestBlock testBlock = ^{
72 | };
73 | CC_LOG_VALUE(testBlock);
74 |
75 | ##### Review the logs in our app
76 |
77 | [CCLogSystem activeDeveloperUI];
78 |
79 |
80 |
81 |
82 |
83 | #### Authors and License
84 |
85 | * All source code is licensed under the MIT License.
86 | * Copyright (c) 2014-2015, [@Chun Ye](http://chun.tips)
87 |
88 |
89 |
--------------------------------------------------------------------------------