Compare commits

...

128 Commits
v3.0 ... master

Author SHA1 Message Date
Robbie Hanson
772efef2ed Incrementing podspec version. 2018-07-22 12:59:03 -04:00
Robbie Hanson
e8c4021aa1
Merge pull request #458 from wjmelements/ydcu-import-foundation
Add missing foundation import
2018-07-12 12:00:58 -04:00
William Morriss
5fa11c84d3 <> 2018-07-04 02:21:55 -07:00
William Morriss
190cbb6c98 add foundation import 2018-07-03 14:42:09 -07:00
Robbie Hanson
31475d08ff Bug fix for previous commit. 2018-06-28 16:05:50 -04:00
Robbie Hanson
81c2f830d4 Adding new insertedKeys set to YapDatabaseModifiedNotification. 2018-06-28 12:36:44 -04:00
Robbie Hanson
a2fa29e545 Merge branch 'master' of https://github.com/yapstudios/YapDatabase 2018-06-20 15:18:31 -04:00
Robbie Hanson
4e59aff974 Adding convenience method to detect when all previous asyncRegisterExtension requests have completed. 2018-06-20 15:18:25 -04:00
Robbie Hanson
cf9692ebea
Update README.md 2018-06-15 09:54:51 -04:00
Robbie Hanson
7e0919da7c Incrementing podspec version. 2018-06-14 22:18:28 -04:00
Robbie Hanson
fcfda4e5f0 Improving documentation in ConnectionProxy, and adding another reset-like method. 2018-05-23 19:09:49 -04:00
Robbie Hanson
5f480844db Fixing more compiler warnings for issue #444 2018-05-23 19:07:34 -04:00
Robbie Hanson
b5c42db8c6 Minor changes recommended by analyzer. 2018-05-23 17:31:07 -04:00
Robbie Hanson
ca0cb15154 Fix for issue #444 - Compiler warnings in Xcode 9 2018-05-23 17:30:28 -04:00
Robbie Hanson
5d3ea2e97b Adding NS_ASSUME_NONNULL header/footer to YapManyToManyCache.h, and fixing some nullability annotations. Also removing the nullability annotations from private header files, as the compiler throws a fit about all the other missing annotations within the file. (And because the private header files are only used by Obj-C.) 2018-04-05 10:17:37 -07:00
Denis Zubkov
4a207244ae Added __nullable to metadata in headers to make sure Swift 4.1 doesn't throw EXC_BAD_ACCESS 2018-04-05 15:25:14 +10:00
Robbie Hanson
cc678addef Updating YDBRelationship delete rules for files, to match recent changes for delete rules for nodes. Addresses issue #148 2018-04-04 10:56:58 -07:00
Robbie Hanson
88adbb028f
Merge pull request #447 from EnvionSoftwareMobile/master
Edges processing updated to fix #148
2018-04-03 18:20:52 -07:00
Artem Kirienko
66568fedc2 CocoaLumberjack pod updated 2018-03-28 21:41:17 +03:00
Artem Kirienko
fc3b157c0e Travis CI config updated 2018-03-28 21:37:16 +03:00
Artem Kirienko
9bf0ddf311 Edges processing updated to fix #148
Edge count query doesn't include edge name anymore.
2018-03-28 20:08:42 +03:00
Robbie Hanson
2947fda783 Potential bug fix for issues #437 and #441 2018-03-27 11:18:11 -07:00
Robbie Hanson
5b3f5030e7 Adding hook to additionally configure newly created connections in a connection pool. This is useful for configuring things such as permittedTransactions. 2018-03-19 15:00:56 -06:00
Robbie Hanson
b9d9fe42f6 Adding ConnectionPool to CocoaPods & Carthage. 2018-03-19 14:01:44 -06:00
Robbie Hanson
e26639737d New utility class: YapDatabaseConnectionPool. A simple load balancer designed for background (non-main-thread) tasks that perform read-only transactions. 2018-03-19 13:30:56 -06:00
Robbie Hanson
e59d5fb5f9 Adding new property on YapDatabaseConnection: pendingTransactionCount 2018-03-19 12:02:11 -06:00
Robbie Hanson
27b32aa3ea Minor optimization - check completionBlock for NULL once, instead of twice. 2018-03-19 12:00:12 -06:00
Robbie Hanson
30b053c000 Explicitly marking dynamic properties dynamic. This makes it easier to find spelling mistakes in function names. 2018-03-19 11:57:56 -06:00
Robbie Hanson
114d371b7a Adding ability to create a databaseConnection with a pre-configured set of configuration options. 2018-03-19 11:56:41 -06:00
Robbie Hanson
102a3436b9 Deprecating the defaultX properties in YapDatabase, in favor of the new(ish) YapDatabaseConnectionConfig class. 2018-03-18 13:41:13 -06:00
Robbie Hanson
05a3bbf01d Updating unit test project via 'pod install'. 2018-03-18 12:44:31 -06:00
Robbie Hanson
5969174262 Updating macOS deployment target from 10.9 to 10.10. The primary motivation for this is to silence the hundreds of compiler warnings about CloudKit not being available in 10.9. 2018-03-18 12:43:42 -06:00
Robbie Hanson
5df37ee440 Fixing compiler warning & bug in YDBCloudCore. 2018-03-18 12:28:46 -06:00
Robbie Hanson
ec857d7021
Merge pull request #439 from signalapp/charlesmchen/unencryptedHeaders
Charlesmchen/unencrypted headers
2018-03-18 12:18:59 -06:00
Robbie Hanson
d07f12b50d
Merge pull request #443 from mathieualvado/fix_nullability_annotations
Fix missing nullability annotation in backup methods
2018-03-15 14:07:56 -06:00
Mathieu Alvado
3174f45e67 Fix missing nullability annotation in backup methods
Missing annotations were causing a crash in Swift when accessing error argument.
2018-03-09 01:17:13 -05:00
Robbie Hanson
9f97fed893 Bug fix: enumeration code was skipping inserted operations in the last commit. 2018-03-08 15:38:10 -07:00
Robbie Hanson
f91e7a191e Adding a few convenience methods to YapDatabaseCloudCoreTransaction. 2018-03-08 15:35:51 -07:00
Robbie Hanson
a19f0d29e4 Fixing a crash that was described in issue #399 but this time with protocolEdges instead of manualEdges. Added corresponding unit test as well. 2018-03-08 15:32:14 -07:00
Robbie Hanson
9ac1bce51a
Merge pull request #440 from rupertdaniel/fts-add-transaction-to-handler-block
Fts add transaction to handler blocks
2018-03-08 17:43:55 -03:00
Robbie Hanson
15c3145e21
Merge pull request #442 from marcpalmer/marcpalmer-patch-1
Fix for _enumerateRowidsForKeys only working for 1 key
2018-03-08 17:38:16 -03:00
Marc Palmer
d9199ca084
Fix for _enumerateRowidsForKeys only working for 1 key
If the fast path for 1 key lookup is not taken because there are > 1 keys, the `keyIndexDict` is never allocated a value due to a logic bug. Objective-C then conspired to hide this problem from us thanks to messaging of nil.
2018-03-08 14:45:54 +00:00
Matthew Chen
373f0d4de7 Clean up ahead of PR. 2018-01-25 10:56:59 -05:00
Matthew Chen
3ed77a8f38 Clean up ahead of PR. 2018-01-25 10:43:33 -05:00
Matthew Chen
fcc56870be Clean up ahead of PR. 2018-01-25 10:22:08 -05:00
Matthew Chen
a57b0c1adb Add database conversion class. 2018-01-24 17:10:59 -05:00
Matthew Chen
40ab4d2fe2 Add support for key specs. 2018-01-24 16:05:18 -05:00
Matthew Chen
302a1c86e4 Fix tests broken on device. 2018-01-24 10:00:42 -05:00
Rupert Daniel
db05d876f7 Updated FTS unit tests. 2018-01-24 11:29:57 +00:00
Rupert Daniel
1aac5034f8 Pass the database transaction as a parameter to FTS extension handler
blocks.
2018-01-24 11:21:45 +00:00
Matthew Chen
9ef73cbc91 Clean up ahead of PR. 2018-01-23 17:11:40 -05:00
Matthew Chen
27019b5260 Clean up ahead of PR. 2018-01-23 16:57:10 -05:00
Matthew Chen
91cb9f50c1 Modify YapDatabase to read converted database. 2018-01-23 16:40:35 -05:00
Matthew Chen
3941d566a6 Modify YapDatabase to read converted database. 2018-01-23 09:49:16 -05:00
Matthew Chen
72e05df4cd Support unencrypted headers and manual salts. 2018-01-19 18:15:55 -05:00
Robbie Hanson
6dce343afb Bug fix for issue #433 - Initialisers are marked non-nullable in header, but can return nil 2018-01-02 13:10:47 -05:00
Robbie Hanson
65cb53830f Bug fix for issue #437 - Possible deadlock in [YapDatabaseConnection dealloc] 2018-01-02 12:57:50 -05:00
Robbie Hanson
cc73216ebf
Merge pull request #435 from ksuther/fts-upgrade
Fixed FTS extension repeatedly reindexing
2018-01-02 12:34:24 -05:00
Robbie Hanson
f0016bcc0a
Merge pull request #438 from ksuther/remove-crossprocess-logs
Adjusted logging in CrossProcessNotification extension
2018-01-02 12:32:04 -05:00
Robbie Hanson
8714d467ef Decreasing default log level for YDBActionManager. 2018-01-02 12:28:26 -05:00
Kent Sutherland
66dfd5d809 Adjusted logging in CrossProcessNotification extension
Remove NSLogging when creating and destroying the cross process notification extension.
Changed cross-process notification log to use YDBLog.
2017-12-23 14:44:24 -05:00
Kent Sutherland
ae814eaa89 Fixed FTS extension repeatedly reindexing if the original database was created with the version of the extension that didn't save ftsVersion to the database. 2017-12-05 17:01:02 -06:00
Robbie Hanson
ce9c8dbcee Bug fix for issue #426 2017-11-24 20:10:24 -05:00
Robbie Hanson
9cbc4a0132 Adding unit test for issue #399 & simplifying code 2017-11-24 19:15:22 -05:00
Robbie Hanson
b142d8b69d Adding unit test for issue #426 2017-11-24 18:16:20 -05:00
Robbie Hanson
690cb2de14 Fixing Xcode project for unit tests (desktop) 2017-11-24 18:15:52 -05:00
Robbie Hanson
6324181181 Bug fix for issue #427 - CloudCore extension wasn't registering properly (if not subclassed). 2017-11-04 16:54:27 -05:00
Robbie Hanson
03baeb1336 Updating CocoaLumberjack version in Carthage to fix compiler warnings. 2017-11-04 15:52:51 -05:00
Robbie Hanson
0cd8bf6c8e Adding YapDatabaseCloudCore to Carthage builds. 2017-11-04 10:25:11 -05:00
Robbie Hanson
bf499db56a Fixing swift annotations in YDBCloudKit extension. 2017-10-30 10:51:01 -04:00
Robbie Hanson
4d83a42a11 Bumping podspec version 2017-10-30 10:50:32 -04:00
Robbie Hanson
876e085aa8 Decreasing log levels for YDBCloudKit extension. 2017-10-07 09:42:36 -04:00
Robbie Hanson
15f8dfb048 Updated CloudKitTodo - updated from deprecated CloudKit API's 2017-09-16 17:56:50 -04:00
Robbie Hanson
25f0966d2f Fixing lots of compiler warnings for CloudKitTodo example application. 2017-09-16 13:44:49 -04:00
Robbie Hanson
04ef18a48f Fixing a few minor bugs in YDBCloudCore. Thanks new compiler. 2017-09-16 12:31:55 -04:00
Robbie Hanson
6b6f3785ea Fixing CloudKitTodo sample project via 'pod install'. 2017-09-16 12:23:21 -04:00
Robbie Hanson
dcf12ff94c Fixing Carthage build. 2017-09-16 11:55:24 -04:00
Robbie Hanson
97adeabfe8 Merge branch 'master' of https://github.com/yapstudios/YapDatabase
* 'master' of https://github.com/yapstudios/YapDatabase:
  Xcode 9 warnings
2017-09-06 15:23:07 -04:00
Robbie Hanson
2329a34c1c Adding general status notification for YDBCloudCorePipeline. Helpful in determining if there are any active uploads. 2017-09-06 15:23:02 -04:00
Robbie Hanson
34cd022c82 Adding reverse reference from YDBCloudCorePipeline to YDBCloudCore. This is helpful when receiving notifications from the pipeline. 2017-09-06 15:22:15 -04:00
Robbie Hanson
6c6a941a6e Merge pull request #421 from adamwulf/xcode9-warnings
Xcode 9 warnings
2017-09-06 15:16:52 -04:00
Robbie Hanson
4105aaaf9e Multiple bug fixes for YapDatabaseCloudCore. 2017-08-21 17:35:32 -07:00
Adam Wulf
c1708752f7 Xcode 9 warnings 2017-08-05 21:21:05 -05:00
Robbie Hanson
462c2b5ea4 Bumping podspec 2017-07-18 17:30:57 -07:00
Robbie Hanson
60d9471c7f New method: [YapDatabaseReadWriteTransaction addCompletionQueue:completionBlock:] 2017-07-18 17:26:45 -07:00
Robbie Hanson
8e455fe858 Fixing unit test projects via pod install. 2017-07-18 16:28:01 -07:00
Robbie Hanson
6e863cbe33 Fixing deadlock issue when passing custom connections during extension registration. This is no longer supported. In its place is a way of passing a connection 'config', which allows one to tweak the memory options of the internal database connection. This was the original motivation for the functionality (performance optimizations). Fixes issue #371 2017-07-18 16:26:31 -07:00
Robbie Hanson
b0f9ea9e25 Fixing compiler warning about unused variable. 2017-07-18 15:36:01 -07:00
Robbie Hanson
f8c2f2211c Fixing a bunch of compiler warnings about documentation. 2017-07-18 15:35:43 -07:00
Robbie Hanson
2e9ec5fb6d Trying to fix Travis build. (Switching from xctool to xcodebuild) 2017-07-18 15:16:00 -07:00
Robbie Hanson
05bba703d7 Merge pull request #414 from fabiankr/reachability
Make -initWithReachabilityRef: retain the ref argument, fixing a Clang analyzer warning.
2017-07-18 14:45:33 -07:00
Robbie Hanson
82ca5253b8 Merge branch 'fabiankr-shadow' 2017-07-18 14:36:28 -07:00
Robbie Hanson
fc778139f5 Merge branch 'shadow' of https://github.com/fabiankr/YapDatabase into fabiankr-shadow 2017-07-18 14:17:05 -07:00
Robbie Hanson
cc69137d22 Merge pull request #412 from fabiankr/cast
Add some explicit casts when implicitly converting types.
2017-07-18 14:11:51 -07:00
Robbie Hanson
aed881421a Merge pull request #411 from fabiankr/prefix
Add prefix for NSDate category methods.
2017-07-18 14:09:30 -07:00
Robbie Hanson
361eecf215 Fixing unit test projects via pod install. 2017-07-18 14:08:27 -07:00
Robbie Hanson
86c565e961 Merge branch 'fabiankr-lock' 2017-07-18 13:57:29 -07:00
Fabian Kreiser
ffd8d692c6 -initWithReachabilityRef: now retains the ref argument.
Without this Clang shows an analyzer warning that after calling -initWithReachabilityRef: the ref should be released. Because -initWithReachabilityRef: doesn’t retain the argument, this would result in a dangling pointer.

Warning: This change fixes the issue in YapDatabase internally, but it introduces a memory leak for consumers that are currently using -initWithReachabilityRef without releasing the ref.
2017-07-10 20:38:42 +02:00
Fabian Kreiser
04eb3b9fc0 Replace OSSpinLock with os_unfair_lock when building for macOS 10.12, iOS 10.0, watchOS 3.0 or tvOS 10.0.
OSSpinLock is deprecated and should be replaced by os_unfair_lock. However, os_unfair_lock is not available prior to the aforementioned platforms. Added some defined to seamlessly map between OSSpinLock and os_unfair_lock in YapDatabaseAtomic.h.

YapDatabase deploys to earlier versions so OSSpinLock is still used by default. But if consumers of the framework decide to rebuild it for more modern platforms, os_unfair_lock will be used.
2017-07-10 20:10:56 +02:00
Fabian Kreiser
7354c0b7d0 Add some explicit casts when implicitly converting types.
Very cosmetic change.
2017-07-10 20:10:43 +02:00
Fabian Kreiser
2e299370d7 Add prefix for NSDate category methods.
The NSDictionary category does this already. Without prefixing the method names might clash with consumer code.
2017-07-10 20:10:18 +02:00
Fabian Kreiser
c568675ef3 Fixed shadowing of local variables by renaming them.
While the „Hidden Local Variables“ setting is turned off by default it’s better to give the variables slightly more descriptive names.
2017-07-10 20:10:01 +02:00
Robbie Hanson
4b6f2bb546 Merge pull request #409 from vkovtash/fts5
FTS5 with bm25 ranking queries
2017-06-28 08:52:04 -07:00
Robbie Hanson
227c09a4fb Merge pull request #408 from vkovtash/fix_crossprocess_notifications
Cross process notifications about all db events
2017-06-28 08:46:34 -07:00
Vlad Kovtash
c6ab78abf0 Fixing tests 2017-06-28 12:25:52 +03:00
Vlad Kovtash
8b52eced7d Fixing tests 2017-06-28 12:24:38 +03:00
Vlad Kovtash
e8371ad93d FTS5 with bm25 ranking queries 2017-06-28 11:56:48 +03:00
Vlad Kovtash
bc556eb381 Cross process notifications about all db events 2017-06-28 11:34:04 +03:00
Robbie Hanson
f0b92487a9 Merge pull request #407 from emoryalimam/feature/ReadMeLogo
Add refreshed YapDatabase logo to Readme.
2017-06-27 17:56:47 -07:00
Emory Al-Imam
eaf8358870 Add refreshed YapDatabase logo to Readme. 2017-06-27 14:39:58 -07:00
Robbie Hanson
d6326587cb Removing debug logging leftover from testing. 2017-06-23 16:45:46 -07:00
Robbie Hanson
83dadd4897 Increasing default aggressiveWALTruncationSize. 2017-06-23 16:26:56 -07:00
Robbie Hanson
99ec47fce6 Re-thinking aggressive checkpointing architecture. 2017-06-23 16:22:02 -07:00
Robbie Hanson
e0f0dfc746 Checkpoint optimization: don't queue additional checkpoint operations if there are still pending operations. 2017-06-22 16:00:59 -07:00
Robbie Hanson
e55b8f2693 Fixing iOS compiler issues. 2017-06-22 11:16:01 -07:00
Robbie Hanson
aa50e06cd8 Updating CocoaLumberjack to v3 in Carthage build. 2017-06-22 11:15:37 -07:00
Robbie Hanson
3c8732a674 Fixing Carthage references in Xcode. 2017-06-22 11:15:16 -07:00
Robbie Hanson
2ed41442a4 Merge pull request #404 from ksuther/project-fixes
Fixed build errors and bad project references
2017-06-22 10:42:07 -07:00
Robbie Hanson
d51665ab59 Merge pull request #401 from vkovtash/fix_multipricess_dealloc
Flushing beginImmediateTransactionStatement
2017-06-22 09:59:01 -07:00
Kent Sutherland
6c8eb031d8 Fixed build errors and bad project references
Some of the Xcode group folders were misnamed.
YapDatabaseAutoView wasn't added to the xcodeproj.
Updated modulemaps to include YapDatabaseAutoView.
2017-06-14 10:30:44 -05:00
Robbie Hanson
5de44c5c5d Working on fixing Travis build. 2017-06-12 17:49:25 -07:00
Robbie Hanson
ea55dc3b9e Merge pull request #403 from ksuther/fix-warnings
Fix warnings
2017-06-12 17:43:50 -07:00
Kent Sutherland
c7edd1a146 Silence shadowed variable warning 2017-06-08 11:35:11 -05:00
Kent Sutherland
851645a85a A bitwise & should be a &&
Silences a warning in Xcode 9.
2017-06-08 11:35:04 -05:00
Vlad Kovtash
0ec0f64f83 Flushing beginImmediateTransactionStatement 2017-06-05 16:20:49 +03:00
Robbie Hanson
d8539e1f10 Fixing more podspec issues. 2017-05-17 17:25:21 -07:00
Robbie Hanson
1dbc8722bc Fixing podspec issue. 2017-05-17 14:20:23 -07:00
Robbie Hanson
d90754e9e9 Fixing podspec issue. 2017-05-17 13:23:59 -07:00
387 changed files with 18113 additions and 13104 deletions

View File

@ -1,11 +1,9 @@
language: objective-c
osx_image: xcode7
osx_image: xcode9.2
before_install:
- gem update cocoapods
before_script:
- export LANG=en_US.UTF-8
script:
- cd ./Testing/Xcode-desktop
- pod update
- xctool -workspace YapDatabaseTesting.xcworkspace -scheme YapDatabaseTesting -sdk macosx -arch x86_64 test
- xcodebuild -workspace YapDatabaseTesting.xcworkspace -scheme YapDatabaseTesting clean
- xcodebuild -workspace YapDatabaseTesting.xcworkspace -scheme YapDatabaseTesting -configuration release test

View File

@ -1 +1 @@
github "CocoaLumberjack/CocoaLumberjack" "2.3.0"
github "CocoaLumberjack/CocoaLumberjack" "3.3.0"

View File

@ -8,11 +8,11 @@
/* Begin PBXBuildFile section */
51EE553F951BF40945032BD5 /* libPods-CloudKitTodo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABB1832E9FCC349F48EB4C9C /* libPods-CloudKitTodo.a */; };
DC212CE11F6D98F600C11BF0 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC212CE01F6D98F600C11BF0 /* CloudKit.framework */; };
DC6071471A33F3FF00207DE9 /* TodoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6071461A33F3FF00207DE9 /* TodoCell.m */; };
DC60714A1A33FC3900207DE9 /* checkmark-off.png in Resources */ = {isa = PBXBuildFile; fileRef = DC6071481A33FC3900207DE9 /* checkmark-off.png */; };
DC60714B1A33FC3900207DE9 /* checkmark-on.png in Resources */ = {isa = PBXBuildFile; fileRef = DC6071491A33FC3900207DE9 /* checkmark-on.png */; };
DC927FFD1A344BA500FEEAEA /* TodoTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = DC927FFC1A344BA500FEEAEA /* TodoTextView.m */; };
DC9A34D61BB5CA650067AD13 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC9A34D51BB5CA650067AD13 /* CloudKit.framework */; };
DCDE77211A3023E9001D8FCE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDE77201A3023E9001D8FCE /* main.m */; };
DCDE77241A3023E9001D8FCE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDE77231A3023E9001D8FCE /* AppDelegate.m */; };
DCDE772A1A3023E9001D8FCE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DCDE77281A3023E9001D8FCE /* Main.storyboard */; };
@ -30,13 +30,13 @@
/* Begin PBXFileReference section */
703B5BE0F88E9B9E927805E5 /* Pods-CloudKitTodo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CloudKitTodo.release.xcconfig"; path = "Pods/Target Support Files/Pods-CloudKitTodo/Pods-CloudKitTodo.release.xcconfig"; sourceTree = "<group>"; };
ABB1832E9FCC349F48EB4C9C /* libPods-CloudKitTodo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CloudKitTodo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DC212CE01F6D98F600C11BF0 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
DC6071451A33F3FF00207DE9 /* TodoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TodoCell.h; sourceTree = "<group>"; };
DC6071461A33F3FF00207DE9 /* TodoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TodoCell.m; sourceTree = "<group>"; };
DC6071481A33FC3900207DE9 /* checkmark-off.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkmark-off.png"; sourceTree = "<group>"; };
DC6071491A33FC3900207DE9 /* checkmark-on.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "checkmark-on.png"; sourceTree = "<group>"; };
DC927FFB1A344BA500FEEAEA /* TodoTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TodoTextView.h; sourceTree = "<group>"; };
DC927FFC1A344BA500FEEAEA /* TodoTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TodoTextView.m; sourceTree = "<group>"; };
DC9A34D51BB5CA650067AD13 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
DCDE771B1A3023E9001D8FCE /* CloudKitTodo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CloudKitTodo.app; sourceTree = BUILT_PRODUCTS_DIR; };
DCDE771F1A3023E9001D8FCE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DCDE77201A3023E9001D8FCE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
@ -67,7 +67,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DC9A34D61BB5CA650067AD13 /* CloudKit.framework in Frameworks */,
DC212CE11F6D98F600C11BF0 /* CloudKit.framework in Frameworks */,
DCDE78831A302B46001D8FCE /* libsqlite3.dylib in Frameworks */,
51EE553F951BF40945032BD5 /* libPods-CloudKitTodo.a in Frameworks */,
);
@ -129,7 +129,7 @@
DCDE776B1A3028EA001D8FCE /* Frameworks */ = {
isa = PBXGroup;
children = (
DC9A34D51BB5CA650067AD13 /* CloudKit.framework */,
DC212CE01F6D98F600C11BF0 /* CloudKit.framework */,
DCDE78821A302B46001D8FCE /* libsqlite3.dylib */,
ABB1832E9FCC349F48EB4C9C /* libPods-CloudKitTodo.a */,
);
@ -207,7 +207,7 @@
DCDE77131A3023E9001D8FCE /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0820;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Deusty LLC";
TargetAttributes = {
DCDE771A1A3023E9001D8FCE = {
@ -217,6 +217,9 @@
com.apple.BackgroundModes = {
enabled = 1;
};
com.apple.Push = {
enabled = 1;
};
com.apple.iCloud = {
enabled = 1;
};
@ -264,13 +267,16 @@
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-CloudKitTodo-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
A7E36A79EF95353C65F5D2B6 /* [CP] Embed Pods Frameworks */ = {
@ -353,14 +359,20 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -383,7 +395,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -399,14 +411,20 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -422,7 +440,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
@ -447,7 +465,6 @@
"\"${PODS_ROOT}/Headers/Private/YapDatabase\"",
);
INFOPLIST_FILE = CloudKitTodo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.4th-a.CloudKitTodo";
PRODUCT_NAME = "$(TARGET_NAME)";
@ -472,7 +489,6 @@
"\"${PODS_ROOT}/Headers/Private/YapDatabase\"",
);
INFOPLIST_FILE = CloudKitTodo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.4th-a.CloudKitTodo";
PRODUCT_NAME = "$(TARGET_NAME)";

View File

@ -1,11 +1,10 @@
#import <UIKit/UIKit.h>
#import <Reachability/Reachability.h>
#import "YapDatabase.h"
#import "YapDatabaseCloudKit.h"
#import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseCloudKit.h>
@class AppDelegate;
extern AppDelegate *MyAppDelegate;
@ -16,4 +15,3 @@ extern AppDelegate *MyAppDelegate;
@property (nonatomic, strong, readonly) Reachability *reachability;
@end

View File

@ -1,16 +1,15 @@
#import "AppDelegate.h"
#import "DatabaseManager.h"
#import "CloudKitManager.h"
#import "DatabaseManager.h"
#import "MyTodo.h"
#import "YapDatabaseLogging.h"
#import <CocoaLumberjack/CocoaLumberjack.h>
#import <CocoaLumberjack/DDTTYLogger.h>
#import <CloudKit/CloudKit.h>
#import <Reachability/Reachability.h>
#import <UserNotifications/UserNotifications.h>
#if DEBUG
static const NSUInteger ddLogLevel = DDLogLevelAll;
@ -76,10 +75,21 @@ AppDelegate *MyAppDelegate;
// Register for push notifications
UIUserNotificationSettings *notificationSettings =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[application registerUserNotificationSettings:notificationSettings];
UNAuthorizationOptions options = UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:options
completionHandler:^(BOOL granted, NSError *_Nullable error)
{
if (granted)
DDLogVerbose(@"UNAuthorizationOptionBadge: granted");
else
DDLogWarn(@"UNAuthorizationOptionBadge: NOT granted !");
dispatch_async(dispatch_get_main_queue(), ^{
[application registerForRemoteNotifications];
});
}];
// Start reachability
@ -118,14 +128,6 @@ AppDelegate *MyAppDelegate;
#pragma mark Push (iOS 8)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)application:(UIApplication *)application
didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
DDLogVerbose(@"application:didRegisterUserNotificationSettings: %@", notificationSettings);
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
DDLogVerbose(@"Registered for Push notifications with token: %@", deviceToken);

View File

@ -197,14 +197,23 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
NSString *title = @"You're not signed into iCloud.";
NSString *message = @"You must be signed into iCloud for syncing to work.";
UIAlertView *alertView =
[[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Oops", nil];
UIAlertController* alert =
[UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
[alertView show];
UIAlertAction* defaultAction =
[UIAlertAction actionWithTitle:@"Oops"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:defaultAction];
UIViewController *rootViewController = MyAppDelegate.window.rootViewController;
[rootViewController presentViewController:alert animated:YES completion:nil];
};
if ([NSThread isMainThread])
@ -220,14 +229,23 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
NSString *title = @"This sample app doesn't support switching iCloud accounts.";
NSString *message = @"But, of course, your app will, right ???";
UIAlertView *alertView =
[[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Of Course", nil];
UIAlertController* alert =
[UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
[alertView show];
UIAlertAction* defaultAction =
[UIAlertAction actionWithTitle:@"Of Course"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:defaultAction];
UIViewController *rootViewController = MyAppDelegate.window.rootViewController;
[rootViewController presentViewController:alert animated:YES completion:nil];
};
if ([NSThread isMainThread])
@ -349,10 +367,14 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
}
CKRecordZoneID *recordZoneID =
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKOwnerDefaultName];
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKCurrentUserDefaultName];
CKSubscription *subscription =
[[CKSubscription alloc] initWithZoneID:recordZoneID subscriptionID:CloudKitZoneName options:0];
CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.shouldSendContentAvailable = YES;
CKRecordZoneSubscription *subscription =
[[CKRecordZoneSubscription alloc] initWithZoneID:recordZoneID subscriptionID:CloudKitZoneName];
subscription.notificationInfo = notificationInfo;
CKModifySubscriptionsOperation *modifySubscriptionsOperation =
[[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:@[ subscription ]
@ -463,16 +485,20 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
(void (^)(UIBackgroundFetchResult result, BOOL moreComing))completionHandler
{
CKRecordZoneID *recordZoneID =
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKOwnerDefaultName];
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKCurrentUserDefaultName];
CKFetchRecordChangesOperation *operation =
[[CKFetchRecordChangesOperation alloc] initWithRecordZoneID:recordZoneID
previousServerChangeToken:prevServerChangeToken];
CKFetchRecordZoneChangesOptions *zoneOptions = [CKFetchRecordZoneChangesOptions new];
zoneOptions.previousServerChangeToken = prevServerChangeToken;
CKFetchRecordZoneChangesOperation *operation =
[[CKFetchRecordZoneChangesOperation alloc] initWithRecordZoneIDs:@[recordZoneID]
optionsByRecordZoneID:@{recordZoneID: zoneOptions}];
operation.fetchAllChanges = NO;
__block NSMutableArray *deletedRecordIDs = nil;
__block NSMutableArray *changedRecords = nil;
operation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID){
operation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID, NSString *recordType){
if (deletedRecordIDs == nil)
deletedRecordIDs = [[NSMutableArray alloc] init];
@ -488,14 +514,14 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
[changedRecords addObject:record];
};
__weak CKFetchRecordChangesOperation *weakOperation = operation;
operation.fetchRecordChangesCompletionBlock =
^(CKServerChangeToken *newServerChangeToken, NSData *clientChangeTokenData, NSError *operationError){
operation.recordZoneFetchCompletionBlock =
^(CKRecordZoneID *recordZoneID, CKServerChangeToken *newServerChangeToken,
NSData *clientChangeTokenData, BOOL moreComing, NSError *operationError)
{
DDLogVerbose(@"CKFetchRecordZoneChangesOperation.recordZoneFetchCompletionBlock");
DDLogVerbose(@"CKFetchRecordChangesOperation.fetchRecordChangesCompletionBlock");
DDLogVerbose(@"CKFetchRecordChangesOperation: serverChangeToken: %@", newServerChangeToken);
DDLogVerbose(@"CKFetchRecordChangesOperation: clientChangeTokenData: %@", clientChangeTokenData);
DDLogVerbose(@"CKFetchRecordZoneChangesOperation: serverChangeToken: %@", newServerChangeToken);
DDLogVerbose(@"CKFetchRecordZoneChangesOperation: clientChangeTokenData: %@", clientChangeTokenData);
// Edge Case:
//
@ -512,8 +538,6 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
// And, in fact, if we don't follow that up with another fetch,
// then we fail to properly fetch what's on the server.
BOOL moreComing = weakOperation.moreComing;
BOOL hasChanges = NO;
if (!operationError)
{

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.$(CFBundleIdentifier)</string>

View File

@ -6,7 +6,6 @@
#import "MyTodo.h"
#import <CocoaLumberjack/CocoaLumberjack.h>
#import <Reachability/Reachability.h>
// Log Levels: off, error, warn, info, verbose
// Log Flags : trace
@ -291,7 +290,7 @@ DatabaseManager *MyDatabaseManager;
if (record == nil)
{
CKRecordZoneID *zoneID =
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKOwnerDefaultName];
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKCurrentUserDefaultName];
CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:todo.uuid zoneID:zoneID];

View File

@ -1,5 +1,15 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
@ -30,6 +40,16 @@
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
@ -59,6 +79,16 @@
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {

View File

@ -1,6 +1,6 @@
platform :ios, '8.0'
platform :ios, '10.0'
target 'CloudKitTodo' do
pod 'Reachability', '3.2'
pod "YapDatabase", path: '../../'
end
end

View File

@ -1,69 +1,70 @@
PODS:
- CocoaLumberjack (2.2.0):
- CocoaLumberjack/Default (= 2.2.0)
- CocoaLumberjack/Extensions (= 2.2.0)
- CocoaLumberjack/Core (2.2.0)
- CocoaLumberjack/Default (2.2.0):
- CocoaLumberjack/Core
- CocoaLumberjack/Extensions (2.2.0):
- CocoaLumberjack (3.2.1):
- CocoaLumberjack/Default (= 3.2.1)
- CocoaLumberjack/Extensions (= 3.2.1)
- CocoaLumberjack/Default (3.2.1)
- CocoaLumberjack/Extensions (3.2.1):
- CocoaLumberjack/Default
- Reachability (3.2)
- YapDatabase (2.9.3):
- YapDatabase/Standard (= 2.9.3)
- YapDatabase/Standard (2.9.3):
- YapDatabase/Standard/Core (= 2.9.3)
- YapDatabase/Standard/Extensions (= 2.9.3)
- YapDatabase/Standard/Core (2.9.3):
- CocoaLumberjack (~> 2)
- YapDatabase/Standard/Extensions (2.9.3):
- YapDatabase (3.0.1):
- YapDatabase/Standard (= 3.0.1)
- YapDatabase/Standard (3.0.1):
- YapDatabase/Standard/Core (= 3.0.1)
- YapDatabase/Standard/Extensions (= 3.0.1)
- YapDatabase/Standard/Core (3.0.1):
- CocoaLumberjack
- YapDatabase/Standard/Extensions (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ActionManager (= 2.9.3)
- YapDatabase/Standard/Extensions/AutoView (= 2.9.3)
- YapDatabase/Standard/Extensions/CloudKit (= 2.9.3)
- YapDatabase/Standard/Extensions/ConnectionProxy (= 2.9.3)
- YapDatabase/Standard/Extensions/CrossProcessNotification (= 2.9.3)
- YapDatabase/Standard/Extensions/FilteredView (= 2.9.3)
- YapDatabase/Standard/Extensions/FullTextSearch (= 2.9.3)
- YapDatabase/Standard/Extensions/Hooks (= 2.9.3)
- YapDatabase/Standard/Extensions/ManualView (= 2.9.3)
- YapDatabase/Standard/Extensions/Relationships (= 2.9.3)
- YapDatabase/Standard/Extensions/RTreeIndex (= 2.9.3)
- YapDatabase/Standard/Extensions/SearchResultsView (= 2.9.3)
- YapDatabase/Standard/Extensions/SecondaryIndex (= 2.9.3)
- YapDatabase/Standard/Extensions/View (= 2.9.3)
- YapDatabase/Standard/Extensions/ActionManager (2.9.3):
- YapDatabase/Standard/Extensions/ActionManager (= 3.0.1)
- YapDatabase/Standard/Extensions/AutoView (= 3.0.1)
- YapDatabase/Standard/Extensions/CloudCore (= 3.0.1)
- YapDatabase/Standard/Extensions/CloudKit (= 3.0.1)
- YapDatabase/Standard/Extensions/ConnectionProxy (= 3.0.1)
- YapDatabase/Standard/Extensions/CrossProcessNotification (= 3.0.1)
- YapDatabase/Standard/Extensions/FilteredView (= 3.0.1)
- YapDatabase/Standard/Extensions/FullTextSearch (= 3.0.1)
- YapDatabase/Standard/Extensions/Hooks (= 3.0.1)
- YapDatabase/Standard/Extensions/ManualView (= 3.0.1)
- YapDatabase/Standard/Extensions/Relationships (= 3.0.1)
- YapDatabase/Standard/Extensions/RTreeIndex (= 3.0.1)
- YapDatabase/Standard/Extensions/SearchResultsView (= 3.0.1)
- YapDatabase/Standard/Extensions/SecondaryIndex (= 3.0.1)
- YapDatabase/Standard/Extensions/View (= 3.0.1)
- YapDatabase/Standard/Extensions/ActionManager (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/AutoView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/AutoView (2.9.3):
- YapDatabase/Standard/Extensions/CloudCore (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CloudKit (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ConnectionProxy (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CrossProcessNotification (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/CloudKit (2.9.3):
- YapDatabase/Standard/Extensions/FullTextSearch (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ConnectionProxy (2.9.3):
- YapDatabase/Standard/Extensions/Hooks (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CrossProcessNotification (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (2.9.3):
- YapDatabase/Standard/Extensions/ManualView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/FullTextSearch (2.9.3):
- YapDatabase/Standard/Extensions/Relationships (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/Hooks (2.9.3):
- YapDatabase/Standard/Extensions/RTreeIndex (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ManualView (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/Relationships (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/RTreeIndex (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/SearchResultsView (2.9.3):
- YapDatabase/Standard/Extensions/SearchResultsView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/FullTextSearch
- YapDatabase/Standard/Extensions/SecondaryIndex (2.9.3):
- YapDatabase/Standard/Extensions/SecondaryIndex (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View (2.9.3):
- YapDatabase/Standard/Extensions/View (3.0.1):
- YapDatabase/Standard/Core
DEPENDENCIES:
@ -75,10 +76,10 @@ EXTERNAL SOURCES:
:path: ../../
SPEC CHECKSUMS:
CocoaLumberjack: 17fe8581f84914d5d7e6360f7c70022b173c3ae0
CocoaLumberjack: 2800c03334042fe80589423c8d80e582dcaec482
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
YapDatabase: cf1907a45a8e033d8205381e096dd73b5d4d261e
YapDatabase: 69ca88a2dfee305fde4412cf670c76f75aa7ccd0
PODFILE CHECKSUM: f638f9f64b041c51ac6d2f50f15969b4ed017571
PODFILE CHECKSUM: 39de1b3e71c8e5fd8a2fd5205a886ee12a55be4a
COCOAPODS: 1.1.1
COCOAPODS: 1.3.1

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -78,4 +78,9 @@
#import "DDTTYLogger.h"
#import "DDASLLogger.h"
#import "DDFileLogger.h"
#import "DDOSLogger.h"
// CLI
#if __has_include("CLIColor.h") && TARGET_OS_OSX
#import "CLIColor.h"
#endif

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2014-2015, Deusty, LLC
// Copyright (c) 2014-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -16,7 +16,7 @@
import Foundation
extension DDLogFlag {
public static func fromLogLevel(logLevel: DDLogLevel) -> DDLogFlag {
public static func from(_ logLevel: DDLogLevel) -> DDLogFlag {
return DDLogFlag(rawValue: logLevel.rawValue)
}
@ -26,66 +26,70 @@ extension DDLogFlag {
///returns the log level, or the lowest equivalant.
public func toLogLevel() -> DDLogLevel {
if let ourValid = DDLogLevel(rawValue: self.rawValue) {
if let ourValid = DDLogLevel(rawValue: rawValue) {
return ourValid
} else {
let logFlag:DDLogFlag = self
if logFlag.contains(.Verbose) {
return .Verbose
} else if logFlag.contains(.Debug) {
return .Debug
} else if logFlag.contains(.Info) {
return .Info
} else if logFlag.contains(.Warning) {
return .Warning
} else if logFlag.contains(.Error) {
return .Error
if contains(.verbose) {
return .verbose
} else if contains(.debug) {
return .debug
} else if contains(.info) {
return .info
} else if contains(.warning) {
return .warning
} else if contains(.error) {
return .error
} else {
return .Off
return .off
}
}
}
}
public var defaultDebugLevel = DDLogLevel.Verbose
public var defaultDebugLevel = DDLogLevel.verbose
public func resetDefaultDebugLevel() {
defaultDebugLevel = DDLogLevel.Verbose
defaultDebugLevel = DDLogLevel.verbose
}
public func SwiftLogMacro(isAsynchronous: Bool, level: DDLogLevel, flag flg: DDLogFlag, context: Int = 0, file: StaticString = __FILE__, function: StaticString = __FUNCTION__, line: UInt = __LINE__, tag: AnyObject? = nil, @autoclosure string: () -> String) {
if level.rawValue & flg.rawValue != 0 {
public func _DDLogMessage(_ message: @autoclosure () -> String, level: DDLogLevel, flag: DDLogFlag, context: Int, file: StaticString, function: StaticString, line: UInt, tag: Any?, asynchronous: Bool, ddlog: DDLog) {
if level.rawValue & flag.rawValue != 0 {
// Tell the DDLogMessage constructor to copy the C strings that get passed to it.
// Using string interpolation to prevent integer overflow warning when using StaticString.stringValue
let logMessage = DDLogMessage(message: string(), level: level, flag: flg, context: context, file: "\(file)", function: "\(function)", line: line, tag: tag, options: [.CopyFile, .CopyFunction], timestamp: nil)
DDLog.log(isAsynchronous, message: logMessage)
let logMessage = DDLogMessage(message: message(), level: level, flag: flag, context: context, file: String(describing: file), function: String(describing: function), line: line, tag: tag, options: [.copyFile, .copyFunction], timestamp: nil)
ddlog.log(asynchronous: asynchronous, message: logMessage)
}
}
public func DDLogDebug(@autoclosure logText: () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = __FILE__, function: StaticString = __FUNCTION__, line: UInt = __LINE__, tag: AnyObject? = nil, asynchronous async: Bool = true) {
SwiftLogMacro(async, level: level, flag: .Debug, context: context, file: file, function: function, line: line, tag: tag, string: logText)
public func DDLogDebug(_ message: @autoclosure () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = true, ddlog: DDLog = DDLog.sharedInstance) {
_DDLogMessage(message, level: level, flag: .debug, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
}
public func DDLogInfo(@autoclosure logText: () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = __FILE__, function: StaticString = __FUNCTION__, line: UInt = __LINE__, tag: AnyObject? = nil, asynchronous async: Bool = true) {
SwiftLogMacro(async, level: level, flag: .Info, context: context, file: file, function: function, line: line, tag: tag, string: logText)
public func DDLogInfo(_ message: @autoclosure () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = true, ddlog: DDLog = DDLog.sharedInstance) {
_DDLogMessage(message, level: level, flag: .info, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
}
public func DDLogWarn(@autoclosure logText: () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = __FILE__, function: StaticString = __FUNCTION__, line: UInt = __LINE__, tag: AnyObject? = nil, asynchronous async: Bool = true) {
SwiftLogMacro(async, level: level, flag: .Warning, context: context, file: file, function: function, line: line, tag: tag, string: logText)
public func DDLogWarn(_ message: @autoclosure () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = true, ddlog: DDLog = DDLog.sharedInstance) {
_DDLogMessage(message, level: level, flag: .warning, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
}
public func DDLogVerbose(@autoclosure logText: () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = __FILE__, function: StaticString = __FUNCTION__, line: UInt = __LINE__, tag: AnyObject? = nil, asynchronous async: Bool = true) {
SwiftLogMacro(async, level: level, flag: .Verbose, context: context, file: file, function: function, line: line, tag: tag, string: logText)
public func DDLogVerbose(_ message: @autoclosure () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = true, ddlog: DDLog = DDLog.sharedInstance) {
_DDLogMessage(message, level: level, flag: .verbose, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
}
public func DDLogError(@autoclosure logText: () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = __FILE__, function: StaticString = __FUNCTION__, line: UInt = __LINE__, tag: AnyObject? = nil, asynchronous async: Bool = false) {
SwiftLogMacro(async, level: level, flag: .Error, context: context, file: file, function: function, line: line, tag: tag, string: logText)
public func DDLogError(_ message: @autoclosure () -> String, level: DDLogLevel = defaultDebugLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = false, ddlog: DDLog = DDLog.sharedInstance) {
_DDLogMessage(message, level: level, flag: .error, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog)
}
/// Returns a String of the current filename, without full path or extension.
///
/// Analogous to the C preprocessor macro `THIS_FILE`.
public func CurrentFileName(fileName: StaticString = __FILE__) -> String {
// Using string interpolation to prevent integer overflow warning when using StaticString.stringValue
// This double-casting to NSString is necessary as changes to how Swift handles NSPathUtilities requres the string to be an NSString
return (("\(fileName)" as NSString).lastPathComponent as NSString).stringByDeletingPathExtension
public func CurrentFileName(_ fileName: StaticString = #file) -> String {
var str = String(describing: fileName)
if let idx = str.range(of: "/", options: .backwards)?.upperBound {
str = str.substring(from: idx)
}
if let idx = str.range(of: ".", options: .backwards)?.lowerBound {
str = str.substring(to: idx)
}
return str
}

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -33,16 +33,9 @@
+ (void)stop;
/**
* Returns the current capture level.
* The current capture level.
* @note Default log level: DDLogLevelVerbose (i.e. capture all ASL messages).
*/
+ (DDLogLevel)captureLevel;
/**
* Set the capture level
*
* @param level new level
*/
+ (void)setCaptureLevel:(DDLogLevel)level;
@property (class) DDLogLevel captureLevel;
@end

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -48,7 +48,7 @@ extern const char* const kDDASLDDLogValue;
*
* @return the shared instance
*/
+ (instancetype)sharedInstance;
@property (class, readonly, strong) DDASLLogger *sharedInstance;
// Inherited from DDAbstractLogger

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -68,7 +68,7 @@ static DDASLLogger *sharedInstance;
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
if (logMessage) {
if (message) {
const char *msg = [message UTF8String];
size_t aslLogLevel;
@ -90,7 +90,7 @@ static DDASLLogger *sharedInstance;
char readUIDString[16];
#ifndef NS_BLOCK_ASSERTIONS
int l = snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
size_t l = snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
#else
snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
#endif

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -126,10 +126,10 @@
- (void)updateAndResumeSaveTimer {
if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0.0)) {
uint64_t interval = (uint64_t)(_saveInterval * NSEC_PER_SEC);
uint64_t interval = (uint64_t)(_saveInterval * (NSTimeInterval) NSEC_PER_SEC);
dispatch_time_t startTime = dispatch_time(_unsavedTime, interval);
dispatch_source_set_timer(_saveTimer, startTime, interval, 1.0);
dispatch_source_set_timer(_saveTimer, startTime, interval, 1ull * NSEC_PER_SEC);
if (_saveTimerSuspended) {
dispatch_resume(_saveTimer);
@ -162,7 +162,7 @@
- (void)updateDeleteTimer {
if ((_deleteTimer != NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) {
uint64_t interval = (uint64_t)(_deleteInterval * NSEC_PER_SEC);
uint64_t interval = (uint64_t)(_deleteInterval * (NSTimeInterval) NSEC_PER_SEC);
dispatch_time_t startTime;
if (_lastDeleteTime > 0) {
@ -171,7 +171,7 @@
startTime = dispatch_time(DISPATCH_TIME_NOW, interval);
}
dispatch_source_set_timer(_deleteTimer, startTime, interval, 1.0);
dispatch_source_set_timer(_deleteTimer, startTime, interval, 1ull * NSEC_PER_SEC);
}
}

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -97,47 +97,47 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
/**
* Returns the logs directory (path)
*/
- (NSString *)logsDirectory;
@property (nonatomic, readonly, copy) NSString *logsDirectory;
/**
* Returns an array of `NSString` objects,
* each of which is the filePath to an existing log file on disk.
**/
- (NSArray *)unsortedLogFilePaths;
@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFilePaths;
/**
* Returns an array of `NSString` objects,
* each of which is the fileName of an existing log file on disk.
**/
- (NSArray *)unsortedLogFileNames;
@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFileNames;
/**
* Returns an array of `DDLogFileInfo` objects,
* each representing an existing log file on disk,
* and containing important information about the log file such as it's modification date and size.
**/
- (NSArray *)unsortedLogFileInfos;
@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *unsortedLogFileInfos;
/**
* Just like the `unsortedLogFilePaths` method, but sorts the array.
* The items in the array are sorted by creation date.
* The first item in the array will be the most recently created log file.
**/
- (NSArray *)sortedLogFilePaths;
@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFilePaths;
/**
* Just like the `unsortedLogFileNames` method, but sorts the array.
* The items in the array are sorted by creation date.
* The first item in the array will be the most recently created log file.
**/
- (NSArray *)sortedLogFileNames;
@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFileNames;
/**
* Just like the `unsortedLogFileInfos` method, but sorts the array.
* The items in the array are sorted by creation date.
* The first item in the array will be the most recently created log file.
**/
- (NSArray *)sortedLogFileInfos;
@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *sortedLogFileInfos;
// Private methods (only to be used by DDFileLogger)
@ -153,12 +153,12 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
/**
* Called when a log file was archieved
*/
- (void)didArchiveLogFile:(NSString *)logFilePath;
- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:));
/**
* Called when the roll action was executed and the log was archieved
*/
- (void)didRollAndArchiveLogFile:(NSString *)logFilePath;
- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:));
@end
@ -203,7 +203,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
* null
* cy#
**/
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString *)fileProtectionLevel;
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel;
#endif
/*
@ -246,7 +246,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
*
* You can change it by overriding `newLogFileName` and `isLogFile:` methods.
**/
- (BOOL)isLogFile:(NSString *)fileName;
- (BOOL)isLogFile:(NSString *)fileName NS_SWIFT_NAME(isLogFile(withName:));
/* Inherited from DDLogFileManager protocol:
@ -302,7 +302,9 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
/**
* The standard implementation for a file logger
*/
@interface DDFileLogger : DDAbstractLogger <DDLogger>
@interface DDFileLogger : DDAbstractLogger <DDLogger> {
DDLogFileInfo *_currentLogFileInfo;
}
/**
* Default initializer
@ -314,11 +316,27 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
*/
- (instancetype)initWithLogFileManager:(id <DDLogFileManager>)logFileManager NS_DESIGNATED_INITIALIZER;
/**
* Called when the logger is about to write message. Call super before your implementation.
*/
- (void)willLogMessage NS_REQUIRES_SUPER;
/**
* Called when the logger wrote message. Call super after your implementation.
*/
- (void)didLogMessage NS_REQUIRES_SUPER;
/**
* Called when the logger checks archive or not current log file.
* Override this method to exdend standart behavior. By default returns NO.
*/
- (BOOL)shouldArchiveRecentLogFileInfo:(DDLogFileInfo *)recentLogFileInfo;
/**
* Log File Rolling:
*
* `maximumFileSize`:
* The approximate maximum size to allow log files to grow.
* The approximate maximum size (in bytes) to allow log files to grow.
* If a log file is larger than this value after a log statement is appended,
* then the log file is rolled.
*
@ -327,6 +345,9 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
* The frequency is given as an `NSTimeInterval`, which is a double that specifies the interval in seconds.
* Once the log file gets to be this old, it is rolled.
*
* `doNotReuseLogFiles`
* When set, will always create a new log file at application launch.
*
* Both the `maximumFileSize` and the `rollingFrequency` are used to manage rolling.
* Whichever occurs first will cause the log file to be rolled.
*
@ -376,7 +397,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
* You can optionally force the current log file to be rolled with this method.
* CompletionBlock will be called on main queue.
*/
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock;
- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
/**
* Method is deprecated.
@ -396,7 +417,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
*
* Otherwise a new file is created and returned.
**/
- (DDLogFileInfo *)currentLogFileInfo;
@property (nonatomic, readonly, strong) DDLogFileInfo *currentLogFileInfo;
@end
@ -423,7 +444,11 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
@property (strong, nonatomic, readonly) NSString *filePath;
@property (strong, nonatomic, readonly) NSString *fileName;
@property (strong, nonatomic, readonly) NSDictionary *fileAttributes;
#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)
@property (strong, nonatomic, readonly) NSDictionary<NSFileAttributeKey, id> *fileAttributes;
#else
@property (strong, nonatomic, readonly) NSDictionary<NSString *, id> *fileAttributes;
#endif
@property (strong, nonatomic, readonly) NSDate *creationDate;
@property (strong, nonatomic, readonly) NSDate *modificationDate;
@ -434,13 +459,13 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
@property (nonatomic, readwrite) BOOL isArchived;
+ (instancetype)logFileWithPath:(NSString *)filePath;
+ (instancetype)logFileWithPath:(NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)");
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER;
- (void)reset;
- (void)renameFile:(NSString *)newFileName;
- (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:));
#if TARGET_IPHONE_SIMULATOR

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -60,7 +60,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
unsigned long long _logFilesDiskQuota;
NSString *_logsDirectory;
#if TARGET_OS_IPHONE
NSString *_defaultFileProtectionLevel;
NSFileProtectionType _defaultFileProtectionLevel;
#endif
}
@ -115,7 +115,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
}
#if TARGET_OS_IPHONE
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString *)fileProtectionLevel {
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel {
if ((self = [self initWithLogsDirectory:logsDirectory])) {
if ([fileProtectionLevel isEqualToString:NSFileProtectionNone] ||
[fileProtectionLevel isEqualToString:NSFileProtectionComplete] ||
@ -281,45 +281,15 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
BOOL hasProperPrefix = [fileName hasPrefix:appName];
BOOL hasProperSuffix = [fileName hasSuffix:@".log"];
BOOL hasProperDate = NO;
if (hasProperPrefix && hasProperSuffix) {
NSUInteger lengthOfMiddle = fileName.length - appName.length - @".log".length;
// Date string should have at least 16 characters - " 2013-12-03 17-14"
if (lengthOfMiddle >= 17) {
NSRange range = NSMakeRange(appName.length, lengthOfMiddle);
NSString *middle = [fileName substringWithRange:range];
NSArray *components = [middle componentsSeparatedByString:@" "];
// When creating logfile if there is existing file with the same name, we append attemp number at the end.
// Thats why here we can have three or four components. For details see createNewLogFile method.
//
// Components:
// "", "2013-12-03", "17-14"
// or
// "", "2013-12-03", "17-14", "1"
if (components.count == 3 || components.count == 4) {
NSString *dateString = [NSString stringWithFormat:@"%@ %@", components[1], components[2]];
NSDateFormatter *dateFormatter = [self logFileDateFormatter];
NSDate *date = [dateFormatter dateFromString:dateString];
if (date) {
hasProperDate = YES;
}
}
}
}
return (hasProperPrefix && hasProperDate && hasProperSuffix);
return (hasProperPrefix && hasProperSuffix);
}
//if you change formater , then change sortedLogFileInfos method also accordingly
- (NSDateFormatter *)logFileDateFormatter {
NSMutableDictionary *dictionary = [[NSThread currentThread]
threadDictionary];
NSString *dateFormat = @"yyyy'-'MM'-'dd' 'HH'-'mm'";
NSString *dateFormat = @"yyyy'-'MM'-'dd'--'HH'-'mm'-'ss'-'SSS'";
NSString *key = [NSString stringWithFormat:@"logFileDateFormatter.%@", dateFormat];
NSDateFormatter *dateFormatter = dictionary[key];
@ -417,13 +387,35 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
}
- (NSArray *)sortedLogFileInfos {
return [[self unsortedLogFileInfos] sortedArrayUsingSelector:@selector(reverseCompareByCreationDate:)];
return [[self unsortedLogFileInfos] sortedArrayUsingComparator:^NSComparisonResult(DDLogFileInfo * _Nonnull obj1, DDLogFileInfo * _Nonnull obj2) {
NSDate *date1 = [NSDate new];
NSDate *date2 = [NSDate new];
NSArray<NSString *> *arrayComponent = [[obj1 fileName] componentsSeparatedByString:@" "];
if (arrayComponent.count > 0) {
NSString *stringDate = arrayComponent.lastObject;
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""];
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""];
date1 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj1 creationDate];
}
arrayComponent = [[obj2 fileName] componentsSeparatedByString:@" "];
if (arrayComponent.count > 0) {
NSString *stringDate = arrayComponent.lastObject;
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""];
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""];
date2 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj2 creationDate];
}
return [date2 compare:date1];
}];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Creation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//if you change newLogFileName , then change isLogFile method also accordingly
- (NSString *)newLogFileName {
NSString *appName = [self applicationName];
@ -467,7 +459,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
// want (even if device is locked). Thats why that attribute have to be changed to
// NSFileProtectionCompleteUntilFirstUserAuthentication.
NSString *key = _defaultFileProtectionLevel ? :
NSFileProtectionType key = _defaultFileProtectionLevel ? :
(doesAppRunInBackground() ? NSFileProtectionCompleteUntilFirstUserAuthentication : NSFileProtectionCompleteUnlessOpen);
attributes = @{
@ -557,7 +549,6 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
@interface DDFileLogger () {
__strong id <DDLogFileManager> _logFileManager;
DDLogFileInfo *_currentLogFileInfo;
NSFileHandle *_currentLogFileHandle;
dispatch_source_t _currentLogFileVnode;
@ -769,10 +760,10 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
});
#endif
uint64_t delay = (uint64_t)([logFileRollingDate timeIntervalSinceNow] * NSEC_PER_SEC);
uint64_t delay = (uint64_t)([logFileRollingDate timeIntervalSinceNow] * (NSTimeInterval) NSEC_PER_SEC);
dispatch_time_t fireTime = dispatch_time(DISPATCH_TIME_NOW, delay);
dispatch_source_set_timer(_rollingTimer, fireTime, DISPATCH_TIME_FOREVER, 1.0);
dispatch_source_set_timer(_rollingTimer, fireTime, DISPATCH_TIME_FOREVER, 1ull * NSEC_PER_SEC);
dispatch_resume(_rollingTimer);
}
@ -780,7 +771,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
[self rollLogFileWithCompletionBlock:nil];
}
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock {
- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock {
// This method is public.
// We need to execute the rolling on our logging thread/queue.
@ -891,7 +882,9 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
if (mostRecentLogFileInfo.isArchived) {
shouldArchiveMostRecent = NO;
} else if (_maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= _maximumFileSize) {
} else if ([self shouldArchiveRecentLogFileInfo:mostRecentLogFileInfo]) {
shouldArchiveMostRecent = YES;
} else if (_maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= _maximumFileSize) {
shouldArchiveMostRecent = YES;
} else if (_rollingFrequency > 0.0 && mostRecentLogFileInfo.age >= _rollingFrequency) {
shouldArchiveMostRecent = YES;
@ -907,10 +900,10 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
// If previous log was created when app wasn't running in background, but now it is - we archive it and create
// a new one.
//
// If user has owerwritten to NSFileProtectionNone there is no neeed to create a new one.
// If user has overwritten to NSFileProtectionNone there is no neeed to create a new one.
if (!_doNotReuseLogFiles && doesAppRunInBackground()) {
NSString *key = mostRecentLogFileInfo.fileAttributes[NSFileProtectionKey];
NSFileProtectionType key = mostRecentLogFileInfo.fileAttributes[NSFileProtectionKey];
if ([key length] > 0 && !([key isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication] || [key isEqualToString:NSFileProtectionNone])) {
shouldArchiveMostRecent = YES;
@ -1005,9 +998,11 @@ static int exception_count = 0;
NSData *logData = [message dataUsingEncoding:NSUTF8StringEncoding];
@try {
[self willLogMessage];
[[self currentLogFileHandle] writeData:logData];
[self maybeRollLogFileDueToSize];
[self didLogMessage];
} @catch (NSException *exception) {
exception_count++;
@ -1022,6 +1017,18 @@ static int exception_count = 0;
}
}
- (void)willLogMessage {
}
- (void)didLogMessage {
[self maybeRollLogFileDueToSize];
}
- (BOOL)shouldArchiveRecentLogFileInfo:(DDLogFileInfo *)recentLogFileInfo {
return NO;
}
- (void)willRemoveLogger {
// If you override me be sure to invoke [super willRemoveLogger];
@ -1092,7 +1099,7 @@ static int exception_count = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (NSDictionary *)fileAttributes {
if (_fileAttributes == nil) {
if (_fileAttributes == nil && filePath != nil) {
_fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
}
@ -1422,6 +1429,10 @@ static int exception_count = 0;
return NO;
}
-(NSUInteger)hash {
return [filePath hash];
}
- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another {
NSDate *us = [self creationDate];
NSDate *them = [another creationDate];

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -29,6 +29,7 @@
#endif
@class DDLogMessage;
@class DDLoggerInformation;
@protocol DDLogger;
@protocol DDLogFormatter;
@ -101,27 +102,27 @@
*/
typedef NS_OPTIONS(NSUInteger, DDLogFlag){
/**
* 0...00000 DDLogFlagError
* 0...00001 DDLogFlagError
*/
DDLogFlagError = (1 << 0),
/**
* 0...00001 DDLogFlagWarning
* 0...00010 DDLogFlagWarning
*/
DDLogFlagWarning = (1 << 1),
/**
* 0...00010 DDLogFlagInfo
* 0...00100 DDLogFlagInfo
*/
DDLogFlagInfo = (1 << 2),
/**
* 0...00100 DDLogFlagDebug
* 0...01000 DDLogFlagDebug
*/
DDLogFlagDebug = (1 << 3),
/**
* 0...01000 DDLogFlagVerbose
* 0...10000 DDLogFlagVerbose
*/
DDLogFlagVerbose = (1 << 4)
};
@ -166,6 +167,8 @@ typedef NS_ENUM(NSUInteger, DDLogLevel){
DDLogLevelAll = NSUIntegerMax
};
NS_ASSUME_NONNULL_BEGIN
/**
* Extracts just the file name, no path or extension
*
@ -174,7 +177,7 @@ typedef NS_ENUM(NSUInteger, DDLogLevel){
*
* @return the file name
*/
NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
/**
* The THIS_FILE macro gives you an NSString of the file name.
@ -205,11 +208,17 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
*/
@interface DDLog : NSObject
/**
* Returns the singleton `DDLog`.
* The instance is used by `DDLog` class methods.
*/
@property (class, nonatomic, strong, readonly) DDLog *sharedInstance;
/**
* Provides access to the underlying logging queue.
* This may be helpful to Logger classes for things like thread synchronization.
**/
+ (dispatch_queue_t)loggingQueue;
@property (class, nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE, readonly) dispatch_queue_t loggingQueue;
/**
* Logging Primitive.
@ -234,7 +243,33 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag
tag:(id __nullable)tag
format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
/**
* Logging Primitive.
*
* This method is used by the macros or logging functions.
* It is suggested you stick with the macros as they're easier to use.
*
* @param asynchronous YES if the logging is done async, NO if you want to force sync
* @param level the log level
* @param flag the log flag
* @param context the context (if any is defined)
* @param file the current file
* @param function the current function
* @param line the current code line
* @param tag potential tag
* @param format the log format
*/
- (void)log:(BOOL)asynchronous
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id __nullable)tag
format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
/**
@ -261,15 +296,17 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag
tag:(id __nullable)tag
format:(NSString *)format
args:(va_list)argList;
args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
/**
* Logging Primitive.
* Logging Primitive.
*
* This method can be used if you have a prepared va_list.
* Similar to `log:level:flag:context:file:function:line:tag:format:...`
*
* @param asynchronous YES if the logging is done async, NO if you want to force sync
* @param message the message
* @param level the log level
* @param flag the log flag
* @param context the context (if any is defined)
@ -277,16 +314,19 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
* @param function the current function
* @param line the current code line
* @param tag potential tag
* @param format the log format
* @param argList the arguments list as a va_list
*/
+ (void)log:(BOOL)asynchronous
message:(NSString *)message
- (void)log:(BOOL)asynchronous
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag;
tag:(id __nullable)tag
format:(NSString *)format
args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
/**
* Logging Primitive.
@ -297,7 +337,18 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
* @param logMessage the log message stored in a `DDLogMessage` model object
*/
+ (void)log:(BOOL)asynchronous
message:(DDLogMessage *)logMessage;
message:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(asynchronous:message:));
/**
* Logging Primitive.
*
* This method can be used if you manualy prepared DDLogMessage.
*
* @param asynchronous YES if the logging is done async, NO if you want to force sync
* @param logMessage the log message stored in a `DDLogMessage` model object
*/
- (void)log:(BOOL)asynchronous
message:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(asynchronous:message:));
/**
* Since logging can be asynchronous, there may be times when you want to flush the logs.
@ -305,6 +356,12 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
**/
+ (void)flushLog;
/**
* Since logging can be asynchronous, there may be times when you want to flush the logs.
* The framework invokes this automatically when the application quits.
**/
- (void)flushLog;
/**
* Loggers
*
@ -322,6 +379,13 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
**/
+ (void)addLogger:(id <DDLogger>)logger;
/**
* Adds the logger to the system.
*
* This is equivalent to invoking `[DDLog addLogger:logger withLogLevel:DDLogLevelAll]`.
**/
- (void)addLogger:(id <DDLogger>)logger;
/**
* Adds the logger to the system.
*
@ -360,20 +424,83 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
**/
+ (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
/**
* Adds the logger to the system.
*
* The level that you provide here is a preemptive filter (for performance).
* That is, the level specified here will be used to filter out logMessages so that
* the logger is never even invoked for the messages.
*
* More information:
* When you issue a log statement, the logging framework iterates over each logger,
* and checks to see if it should forward the logMessage to the logger.
* This check is done using the level parameter passed to this method.
*
* For example:
*
* `[DDLog addLogger:consoleLogger withLogLevel:DDLogLevelVerbose];`
* `[DDLog addLogger:fileLogger withLogLevel:DDLogLevelWarning];`
*
* `DDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
* `DDLogInfo(@"hi");` => gets forwarded to consoleLogger only
*
* It is important to remember that Lumberjack uses a BITMASK.
* Many developers & third party frameworks may define extra log levels & flags.
* For example:
*
* `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
*
* So if you specify `DDLogLevelVerbose` to this method, you won't see the framework's trace messages.
*
* `(SOME_FRAMEWORK_LOG_FLAG_TRACE & DDLogLevelVerbose) => (01000000 & 00011111) => NO`
*
* Consider passing `DDLogLevelAll` to this method, which has all bits set.
* You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
* except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
*
* `((DDLogLevelAll ^ DDLogLevelVerbose) | DDLogLevelInfo)`
**/
- (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level;
/**
* Remove the logger from the system
*/
+ (void)removeLogger:(id <DDLogger>)logger;
/**
* Remove the logger from the system
*/
- (void)removeLogger:(id <DDLogger>)logger;
/**
* Remove all the current loggers
*/
+ (void)removeAllLoggers;
/**
* Remove all the current loggers
*/
- (void)removeAllLoggers;
/**
* Return all the current loggers
*/
+ (NSArray *)allLoggers;
@property (class, nonatomic, copy, readonly) NSArray<id<DDLogger>> *allLoggers;
/**
* Return all the current loggers
*/
@property (nonatomic, copy, readonly) NSArray<id<DDLogger>> *allLoggers;
/**
* Return all the current loggers with their level (aka DDLoggerInformation).
*/
@property (class, nonatomic, copy, readonly) NSArray<DDLoggerInformation *> *allLoggersWithLevel;
/**
* Return all the current loggers with their level (aka DDLoggerInformation).
*/
@property (nonatomic, copy, readonly) NSArray<DDLoggerInformation *> *allLoggersWithLevel;
/**
* Registered Dynamic Logging
@ -385,12 +512,12 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
/**
* Returns an array with the classes that are using registered dynamic logging
*/
+ (NSArray *)registeredClasses;
@property (class, nonatomic, copy, readonly) NSArray<Class> *registeredClasses;
/**
* Returns an array with the classes names that are using registered dynamic logging
*/
+ (NSArray *)registeredClassNames;
@property (class, nonatomic, copy, readonly) NSArray<NSString*> *registeredClassNames;
/**
* Returns the current log level for a certain class
@ -440,7 +567,7 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
*
* @param logMessage the message (model)
*/
- (void)logMessage:(DDLogMessage *)logMessage;
- (void)logMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(message:));
/**
* Formatters may optionally be added to any logger.
@ -465,6 +592,19 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
**/
- (void)didAddLogger;
/**
* Since logging is asynchronous, adding and removing loggers is also asynchronous.
* In other words, the loggers are added and removed at appropriate times with regards to log messages.
*
* - Loggers will not receive log messages that were executed prior to when they were added.
* - Loggers will not receive log messages that were executed after they were removed.
*
* These methods are executed in the logging thread/queue given in parameter.
* This is the same thread/queue that will execute every logMessage: invocation.
* Loggers may use the queue parameter to set specific values on the queue with dispatch_set_specific() function.
**/
- (void)didAddLoggerInQueue:(dispatch_queue_t)queue;
/**
* See the above description for `didAddLoger`
*/
@ -520,7 +660,7 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
* The formatter may also optionally filter the log message by returning nil,
* in which case the logger will not log the message.
**/
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
- (NSString * __nullable)formatLogMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(format(message:));
@optional
@ -535,6 +675,18 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
**/
- (void)didAddToLogger:(id <DDLogger>)logger;
/**
* A single formatter instance can be added to multiple loggers.
* These methods provides hooks to notify the formatter of when it's added/removed.
*
* This is primarily for thread-safety.
* If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
* Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
* it could possibly use these hooks to switch to thread-safe versions of the code or use dispatch_set_specific()
.* to add its own specific values.
**/
- (void)didAddToLogger:(id <DDLogger>)logger inQueue:(dispatch_queue_t)queue;
/**
* See the above description for `didAddToLogger:`
*/
@ -574,12 +726,7 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
* }
* ```
**/
+ (DDLogLevel)ddLogLevel;
/**
* See the above description for `ddLogLevel`
*/
+ (void)ddSetLogLevel:(DDLogLevel)level;
@property (class, nonatomic, readwrite, setter=ddSetLogLevel:) DDLogLevel ddLogLevel;
@end
@ -598,11 +745,15 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
/**
* Use this to use a copy of the file path
*/
DDLogMessageCopyFile = 1 << 0,
DDLogMessageCopyFile = 1 << 0,
/**
* Use this to use a copy of the function name
*/
DDLogMessageCopyFunction = 1 << 1
DDLogMessageCopyFunction = 1 << 1,
/**
* Use this to use avoid a copy of the message
*/
DDLogMessageDontCopyMessage = 1 << 2
};
/**
@ -630,9 +781,9 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
}
/**
* Default `init` is not available
* Default `init` for empty messages.
*/
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
/**
* Standard init method for a log message object.
@ -666,11 +817,11 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(NSString *)file
function:(NSString *)function
function:(NSString * __nullable)function
line:(NSUInteger)line
tag:(id)tag
tag:(id __nullable)tag
options:(DDLogMessageOptions)options
timestamp:(NSDate *)timestamp NS_DESIGNATED_INITIALIZER;
timestamp:(NSDate * __nullable)timestamp NS_DESIGNATED_INITIALIZER;
/**
* Read-only properties
@ -685,9 +836,9 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
@property (readonly, nonatomic) NSInteger context;
@property (readonly, nonatomic) NSString *file;
@property (readonly, nonatomic) NSString *fileName;
@property (readonly, nonatomic) NSString *function;
@property (readonly, nonatomic) NSString * __nullable function;
@property (readonly, nonatomic) NSUInteger line;
@property (readonly, nonatomic) id tag;
@property (readonly, nonatomic) id __nullable tag;
@property (readonly, nonatomic) DDLogMessageOptions options;
@property (readonly, nonatomic) NSDate *timestamp;
@property (readonly, nonatomic) NSString *threadID; // ID as it appears in NSLog calculated from the machThreadID
@ -724,7 +875,7 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
dispatch_queue_t _loggerQueue;
}
@property (nonatomic, strong) id <DDLogFormatter> logFormatter;
@property (nonatomic, strong, nullable) id <DDLogFormatter> logFormatter;
@property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE) dispatch_queue_t loggerQueue;
// For thread-safety assertions
@ -741,3 +892,18 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface DDLoggerInformation : NSObject
@property (nonatomic, readonly) id <DDLogger> logger;
@property (nonatomic, readonly) DDLogLevel level;
+ (DDLoggerInformation *)informationWithLogger:(id <DDLogger>)logger
andLevel:(DDLogLevel)level;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -21,6 +21,7 @@
#import "DDLog.h"
#import <pthread.h>
#import <dispatch/dispatch.h>
#import <objc/runtime.h>
#import <mach/mach_host.h>
#import <mach/host_info.h>
@ -59,7 +60,9 @@
// If a thread attempts to issue a log statement when the queue is already maxed out,
// the issuing thread will block until the queue size drops below the max again.
#define LOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX
#ifndef DDLOG_MAX_QUEUE_SIZE
#define DDLOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX
#endif
// The "global logging queue" refers to [DDLog loggingQueue].
// It is the queue that all log statements go through.
@ -93,11 +96,15 @@ static void *const GlobalLoggingQueueIdentityKey = (void *)&GlobalLoggingQueueId
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation DDLog
@interface DDLog ()
// An array used to manage all the individual loggers.
// The array is only modified on the loggingQueue/loggingThread.
static NSMutableArray *_loggers;
@property (nonatomic, strong) NSMutableArray *_loggers;
@end
@implementation DDLog
// All logging statements are added to the same queue to ensure FIFO operation.
static dispatch_queue_t _loggingQueue;
@ -107,12 +114,29 @@ static dispatch_queue_t _loggingQueue;
static dispatch_group_t _loggingGroup;
// In order to prevent to queue from growing infinitely large,
// a maximum size is enforced (LOG_MAX_QUEUE_SIZE).
// a maximum size is enforced (DDLOG_MAX_QUEUE_SIZE).
static dispatch_semaphore_t _queueSemaphore;
// Minor optimization for uniprocessor machines
static NSUInteger _numProcessors;
/**
* Returns the singleton `DDLog`.
* The instance is used by `DDLog` class methods.
*
* @return The singleton `DDLog`.
*/
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
/**
* The runtime sends initialize to each class in a program exactly one time just before the class,
* or any class that inherits from it, is sent its first message from within the program. (Thus the
@ -123,42 +147,53 @@ static NSUInteger _numProcessors;
**/
+ (void)initialize {
static dispatch_once_t DDLogOnceToken;
dispatch_once(&DDLogOnceToken, ^{
_loggers = [[NSMutableArray alloc] initWithCapacity:4];
NSLogDebug(@"DDLog: Using grand central dispatch");
_loggingQueue = dispatch_queue_create("cocoa.lumberjack", NULL);
_loggingGroup = dispatch_group_create();
void *nonNullValue = GlobalLoggingQueueIdentityKey; // Whatever, just not null
dispatch_queue_set_specific(_loggingQueue, GlobalLoggingQueueIdentityKey, nonNullValue, NULL);
_queueSemaphore = dispatch_semaphore_create(LOG_MAX_QUEUE_SIZE);
_queueSemaphore = dispatch_semaphore_create(DDLOG_MAX_QUEUE_SIZE);
// Figure out how many processors are available.
// This may be used later for an optimization on uniprocessor machines.
_numProcessors = MAX([NSProcessInfo processInfo].processorCount, 1);
_numProcessors = MAX([NSProcessInfo processInfo].processorCount, (NSUInteger) 1);
NSLogDebug(@"DDLog: numProcessors = %@", @(_numProcessors));
});
}
/**
* The `DDLog` initializer.
* Static variables are set only once.
*
* @return An initialized `DDLog` instance.
*/
- (id)init {
self = [super init];
if (self) {
self._loggers = [[NSMutableArray alloc] initWithCapacity:4];
#if TARGET_OS_IOS
NSString *notificationName = @"UIApplicationWillTerminateNotification";
#else
NSString *notificationName = nil;
// On Command Line Tool apps AppKit may not be avaliable
#ifdef NSAppKitVersionNumber10_0
if (NSApp) {
notificationName = @"NSApplicationWillTerminateNotification";
}
#endif
if (!notificationName) {
// If there is no NSApp -> we are running Command Line Tool app.
// In this case terminate notification wouldn't be fired, so we use workaround.
@ -166,16 +201,18 @@ static NSUInteger _numProcessors;
[self applicationWillTerminate:nil];
});
}
#endif /* if TARGET_OS_IOS */
if (notificationName) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillTerminate:)
name:notificationName
object:nil];
}
});
}
return self;
}
/**
@ -189,7 +226,7 @@ static NSUInteger _numProcessors;
#pragma mark Notifications
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ (void)applicationWillTerminate:(NSNotification * __attribute__((unused)))notification {
- (void)applicationWillTerminate:(NSNotification * __attribute__((unused)))notification {
[self flushLog];
}
@ -198,50 +235,84 @@ static NSUInteger _numProcessors;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ (void)addLogger:(id <DDLogger>)logger {
[self.sharedInstance addLogger:logger];
}
- (void)addLogger:(id <DDLogger>)logger {
[self addLogger:logger withLevel:DDLogLevelAll]; // DDLogLevelAll has all bits set
}
+ (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level {
[self.sharedInstance addLogger:logger withLevel:level];
}
- (void)addLogger:(id <DDLogger>)logger withLevel:(DDLogLevel)level {
if (!logger) {
return;
}
dispatch_async(_loggingQueue, ^{ @autoreleasepool {
[self lt_addLogger:logger level:level];
} });
[self lt_addLogger:logger level:level];
} });
}
+ (void)removeLogger:(id <DDLogger>)logger {
[self.sharedInstance removeLogger:logger];
}
- (void)removeLogger:(id <DDLogger>)logger {
if (!logger) {
return;
}
dispatch_async(_loggingQueue, ^{ @autoreleasepool {
[self lt_removeLogger:logger];
} });
[self lt_removeLogger:logger];
} });
}
+ (void)removeAllLoggers {
dispatch_async(_loggingQueue, ^{ @autoreleasepool {
[self lt_removeAllLoggers];
} });
[self.sharedInstance removeAllLoggers];
}
+ (NSArray *)allLoggers {
- (void)removeAllLoggers {
dispatch_async(_loggingQueue, ^{ @autoreleasepool {
[self lt_removeAllLoggers];
} });
}
+ (NSArray<id<DDLogger>> *)allLoggers {
return [self.sharedInstance allLoggers];
}
- (NSArray<id<DDLogger>> *)allLoggers {
__block NSArray *theLoggers;
dispatch_sync(_loggingQueue, ^{ @autoreleasepool {
theLoggers = [self lt_allLoggers];
} });
theLoggers = [self lt_allLoggers];
} });
return theLoggers;
}
+ (NSArray<DDLoggerInformation *> *)allLoggersWithLevel {
return [self.sharedInstance allLoggersWithLevel];
}
- (NSArray<DDLoggerInformation *> *)allLoggersWithLevel {
__block NSArray *theLoggersWithLevel;
dispatch_sync(_loggingQueue, ^{ @autoreleasepool {
theLoggersWithLevel = [self lt_allLoggersWithLevel];
} });
return theLoggersWithLevel;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Master Logging
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ (void)queueLogMessage:(DDLogMessage *)logMessage asynchronously:(BOOL)asyncFlag {
- (void)queueLogMessage:(DDLogMessage *)logMessage asynchronously:(BOOL)asyncFlag {
// We have a tricky situation here...
//
// In the common case, when the queueSize is below the maximumQueueSize,
@ -271,7 +342,7 @@ static NSUInteger _numProcessors;
// We are using a counting semaphore provided by GCD.
// The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value.
// The semaphore is initialized with our DDLOG_MAX_QUEUE_SIZE value.
// Everytime we want to queue a log message we decrement this value.
// If the resulting value is less than zero,
// the semaphore function waits in FIFO order for a signal to occur before returning.
@ -313,6 +384,11 @@ static NSUInteger _numProcessors;
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
va_start(args, format);
[self log:asynchronous
message:message
level:level
@ -322,7 +398,41 @@ static NSUInteger _numProcessors;
function:function
line:line
tag:tag];
va_end(args);
}
}
- (void)log:(BOOL)asynchronous
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag
format:(NSString *)format, ... {
va_list args;
if (format) {
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
va_start(args, format);
[self log:asynchronous
message:message
level:level
flag:flag
context:context
file:file
function:function
line:line
tag:tag];
va_end(args);
}
}
@ -337,7 +447,19 @@ static NSUInteger _numProcessors;
tag:(id)tag
format:(NSString *)format
args:(va_list)args {
[self.sharedInstance log:asynchronous level:level flag:flag context:context file:file function:function line:line tag:tag format:format args:args];
}
- (void)log:(BOOL)asynchronous
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag
format:(NSString *)format
args:(va_list)args {
if (format) {
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
[self log:asynchronous
@ -361,7 +483,18 @@ static NSUInteger _numProcessors;
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag {
[self.sharedInstance log:asynchronous message:message level:level flag:flag context:context file:file function:function line:line tag:tag];
}
- (void)log:(BOOL)asynchronous
message:(NSString *)message
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag {
DDLogMessage *logMessage = [[DDLogMessage alloc] initWithMessage:message
level:level
flag:flag
@ -377,14 +510,23 @@ static NSUInteger _numProcessors;
}
+ (void)log:(BOOL)asynchronous
message:(DDLogMessage *)logMessage {
[self.sharedInstance log:asynchronous message:logMessage];
}
- (void)log:(BOOL)asynchronous
message:(DDLogMessage *)logMessage {
[self queueLogMessage:logMessage asynchronously:asynchronous];
}
+ (void)flushLog {
[self.sharedInstance flushLog];
}
- (void)flushLog {
dispatch_sync(_loggingQueue, ^{ @autoreleasepool {
[self lt_flush];
} });
[self lt_flush];
} });
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -480,7 +622,7 @@ static NSUInteger _numProcessors;
classes = numClasses ? (Class *)malloc(sizeof(Class) * bufferSize) : NULL;
if (classes == NULL) {
return nil; //no memory or classes?
return @[]; //no memory or classes?
}
numClasses = (NSUInteger)MAX(objc_getClassList(classes, (int)bufferSize),0);
@ -547,10 +689,18 @@ static NSUInteger _numProcessors;
#pragma mark Logging Thread
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ (void)lt_addLogger:(id <DDLogger>)logger level:(DDLogLevel)level {
- (void)lt_addLogger:(id <DDLogger>)logger level:(DDLogLevel)level {
// Add to loggers array.
// Need to create loggerQueue if loggerNode doesn't provide one.
for (DDLoggerNode* node in self._loggers) {
if (node->_logger == logger
&& node->_level == level) {
// Exactly same logger already added, exit
return;
}
}
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@"This method should only be run on the logging thread/queue");
@ -576,16 +726,20 @@ static NSUInteger _numProcessors;
}
DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue level:level];
[_loggers addObject:loggerNode];
[self._loggers addObject:loggerNode];
if ([logger respondsToSelector:@selector(didAddLogger)]) {
if ([logger respondsToSelector:@selector(didAddLoggerInQueue:)]) {
dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool {
[logger didAddLoggerInQueue:loggerNode->_loggerQueue];
} });
} else if ([logger respondsToSelector:@selector(didAddLogger)]) {
dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool {
[logger didAddLogger];
} });
}
}
+ (void)lt_removeLogger:(id <DDLogger>)logger {
- (void)lt_removeLogger:(id <DDLogger>)logger {
// Find associated loggerNode in list of added loggers
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@ -593,7 +747,7 @@ static NSUInteger _numProcessors;
DDLoggerNode *loggerNode = nil;
for (DDLoggerNode *node in _loggers) {
for (DDLoggerNode *node in self._loggers) {
if (node->_logger == logger) {
loggerNode = node;
break;
@ -613,15 +767,15 @@ static NSUInteger _numProcessors;
}
// Remove from loggers array
[_loggers removeObject:loggerNode];
[self._loggers removeObject:loggerNode];
}
+ (void)lt_removeAllLoggers {
- (void)lt_removeAllLoggers {
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@"This method should only be run on the logging thread/queue");
// Notify all loggers
for (DDLoggerNode *loggerNode in _loggers) {
for (DDLoggerNode *loggerNode in self._loggers) {
if ([loggerNode->_logger respondsToSelector:@selector(willRemoveLogger)]) {
dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool {
[loggerNode->_logger willRemoveLogger];
@ -631,23 +785,37 @@ static NSUInteger _numProcessors;
// Remove all loggers from array
[_loggers removeAllObjects];
[self._loggers removeAllObjects];
}
+ (NSArray *)lt_allLoggers {
- (NSArray *)lt_allLoggers {
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@"This method should only be run on the logging thread/queue");
NSMutableArray *theLoggers = [NSMutableArray new];
for (DDLoggerNode *loggerNode in _loggers) {
for (DDLoggerNode *loggerNode in self._loggers) {
[theLoggers addObject:loggerNode->_logger];
}
return [theLoggers copy];
}
+ (void)lt_log:(DDLogMessage *)logMessage {
- (NSArray *)lt_allLoggersWithLevel {
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@"This method should only be run on the logging thread/queue");
NSMutableArray *theLoggersWithLevel = [NSMutableArray new];
for (DDLoggerNode *loggerNode in self._loggers) {
[theLoggersWithLevel addObject:[DDLoggerInformation informationWithLogger:loggerNode->_logger
andLevel:loggerNode->_level]];
}
return [theLoggersWithLevel copy];
}
- (void)lt_log:(DDLogMessage *)logMessage {
// Execute the given log message on each of our loggers.
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@ -661,7 +829,7 @@ static NSUInteger _numProcessors;
// The waiting ensures that a slow logger doesn't end up with a large queue of pending log messages.
// This would defeat the purpose of the efforts we made earlier to restrict the max queue size.
for (DDLoggerNode *loggerNode in _loggers) {
for (DDLoggerNode *loggerNode in self._loggers) {
// skip the loggers that shouldn't write this message based on the log level
if (!(logMessage->_flag & loggerNode->_level)) {
@ -677,7 +845,7 @@ static NSUInteger _numProcessors;
} else {
// Execute each logger serialy, each within its own queue.
for (DDLoggerNode *loggerNode in _loggers) {
for (DDLoggerNode *loggerNode in self._loggers) {
// skip the loggers that shouldn't write this message based on the log level
if (!(logMessage->_flag & loggerNode->_level)) {
@ -694,7 +862,7 @@ static NSUInteger _numProcessors;
// Since we've now dequeued an item from the log, we may need to unblock the next thread.
// We are using a counting semaphore provided by GCD.
// The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value.
// The semaphore is initialized with our DDLOG_MAX_QUEUE_SIZE value.
// When a log message is queued this value is decremented.
// When a log message is dequeued this value is incremented.
// If the value ever drops below zero,
@ -707,7 +875,7 @@ static NSUInteger _numProcessors;
dispatch_semaphore_signal(_queueSemaphore);
}
+ (void)lt_flush {
- (void)lt_flush {
// All log statements issued before the flush method was invoked have now been executed.
//
// Now we need to propogate the flush request to any loggers that implement the flush method.
@ -716,7 +884,7 @@ static NSUInteger _numProcessors;
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@"This method should only be run on the logging thread/queue");
for (DDLoggerNode *loggerNode in _loggers) {
for (DDLoggerNode *loggerNode in self._loggers) {
if ([loggerNode->_logger respondsToSelector:@selector(flush)]) {
dispatch_group_async(_loggingGroup, loggerNode->_loggerQueue, ^{ @autoreleasepool {
[loggerNode->_logger flush];
@ -731,7 +899,7 @@ static NSUInteger _numProcessors;
#pragma mark Utilities
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
if (filePath == NULL) {
return nil;
}
@ -851,15 +1019,30 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
// Compiling for iOS
#define USE_DISPATCH_CURRENT_QUEUE_LABEL ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
#define USE_DISPATCH_GET_CURRENT_QUEUE ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.1)
static BOOL _use_dispatch_current_queue_label;
static BOOL _use_dispatch_get_current_queue;
static void _dispatch_queue_label_init_once(void * __attribute__((unused)) context)
{
_use_dispatch_current_queue_label = (UIDevice.currentDevice.systemVersion.floatValue >= 7.0f);
_use_dispatch_get_current_queue = (!_use_dispatch_current_queue_label && UIDevice.currentDevice.systemVersion.floatValue >= 6.1f);
}
static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_init()
{
static dispatch_once_t onceToken;
dispatch_once_f(&onceToken, NULL, _dispatch_queue_label_init_once);
}
#define USE_DISPATCH_CURRENT_QUEUE_LABEL (_dispatch_queue_label_init(), _use_dispatch_current_queue_label)
#define USE_DISPATCH_GET_CURRENT_QUEUE (_dispatch_queue_label_init(), _use_dispatch_get_current_queue)
#elif TARGET_OS_WATCH || TARGET_OS_TV
// Compiling for watchOS, tvOS
#define USE_DISPATCH_CURRENT_QUEUE_LABEL YES
#define USE_DISPATCH_GET_CURRENT_QUEUE YES
#define USE_DISPATCH_CURRENT_QUEUE_LABEL YES
#define USE_DISPATCH_GET_CURRENT_QUEUE NO
#else
@ -876,8 +1059,23 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
#else
#define USE_DISPATCH_CURRENT_QUEUE_LABEL ([NSTimer instancesRespondToSelector : @selector(tolerance)]) // OS X 10.9+
#define USE_DISPATCH_GET_CURRENT_QUEUE (![NSTimer instancesRespondToSelector : @selector(tolerance)]) // < OS X 10.9
static BOOL _use_dispatch_current_queue_label;
static BOOL _use_dispatch_get_current_queue;
static void _dispatch_queue_label_init_once(void * __attribute__((unused)) context)
{
_use_dispatch_current_queue_label = [NSTimer instancesRespondToSelector : @selector(tolerance)]; // OS X 10.9+
_use_dispatch_get_current_queue = !_use_dispatch_current_queue_label; // < OS X 10.9
}
static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_init()
{
static dispatch_once_t onceToken;
dispatch_once_f(&onceToken, NULL, _dispatch_queue_label_init_once);
}
#define USE_DISPATCH_CURRENT_QUEUE_LABEL (_dispatch_queue_label_init(), _use_dispatch_current_queue_label)
#define USE_DISPATCH_GET_CURRENT_QUEUE (_dispatch_queue_label_init(), _use_dispatch_get_current_queue)
#endif
@ -894,13 +1092,13 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
#define kCFCoreFoundationVersionNumber_iOS_8_0 1140.10
#endif
#define USE_PTHREAD_THREADID_NP (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0)
#define USE_PTHREAD_THREADID_NP (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0)
#elif TARGET_OS_WATCH || TARGET_OS_TV
// Compiling for watchOS, tvOS
#define USE_PTHREAD_THREADID_NP YES
#define USE_PTHREAD_THREADID_NP YES
#else
@ -910,10 +1108,15 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
#define kCFCoreFoundationVersionNumber10_10 1151.16
#endif
#define USE_PTHREAD_THREADID_NP (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_10)
#define USE_PTHREAD_THREADID_NP (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_10)
#endif /* if TARGET_OS_IOS */
- (instancetype)init {
self = [super init];
return self;
}
- (instancetype)initWithMessage:(NSString *)message
level:(DDLogLevel)level
flag:(DDLogFlag)flag
@ -925,15 +1128,16 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
options:(DDLogMessageOptions)options
timestamp:(NSDate *)timestamp {
if ((self = [super init])) {
_message = [message copy];
BOOL copyMessage = (options & DDLogMessageDontCopyMessage) == 0;
_message = copyMessage ? [message copy] : message;
_level = level;
_flag = flag;
_context = context;
BOOL copyFile = (options & DDLogMessageCopyFile) == DDLogMessageCopyFile;
BOOL copyFile = (options & DDLogMessageCopyFile) != 0;
_file = copyFile ? [file copy] : file;
BOOL copyFunction = (options & DDLogMessageCopyFunction) == DDLogMessageCopyFunction;
BOOL copyFunction = (options & DDLogMessageCopyFunction) != 0;
_function = copyFunction ? [function copy] : function;
_line = line;
@ -1131,8 +1335,10 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
}
_logFormatter = logFormatter;
if ([_logFormatter respondsToSelector:@selector(didAddToLogger:)]) {
if ([_logFormatter respondsToSelector:@selector(didAddToLogger:inQueue:)]) {
[_logFormatter didAddToLogger:self inQueue:_loggerQueue];
} else if ([_logFormatter respondsToSelector:@selector(didAddToLogger:)]) {
[_logFormatter didAddToLogger:self];
}
}
@ -1165,3 +1371,33 @@ NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface DDLoggerInformation()
{
// Direct accessors to be used only for performance
@public
id <DDLogger> _logger;
DDLogLevel _level;
}
@end
@implementation DDLoggerInformation
- (instancetype)initWithLogger:(id <DDLogger>)logger andLevel:(DDLogLevel)level {
if ((self = [super init])) {
_logger = logger;
_level = level;
}
return self;
}
+ (DDLoggerInformation *)informationWithLogger:(id <DDLogger>)logger andLevel:(DDLogLevel)level {
return [[DDLoggerInformation alloc] initWithLogger:logger andLevel:level];
}
@end

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -35,8 +35,8 @@
#endif
/**
* This is the single macro that all other macros below compile into.
* This big multiline macro makes all the other macros easier to read.
* These are the two macros that all other macros below compile into.
* These big multiline macros makes all the other macros easier to read.
**/
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
[DDLog log : isAsynchronous \
@ -49,6 +49,17 @@
tag : atag \
format : (frmt), ## __VA_ARGS__]
#define LOG_MACRO_TO_DDLOG(ddlog, isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
[ddlog log : isAsynchronous \
level : lvl \
flag : flg \
context : ctx \
file : __FILE__ \
function : fnct \
line : __LINE__ \
tag : atag \
format : (frmt), ## __VA_ARGS__]
/**
* Define version of the macro that only execute if the log level is above the threshold.
* The compiled versions essentially look like this:
@ -71,6 +82,9 @@
#define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
#define LOG_MAYBE_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ...) \
do { if(lvl & flg) LOG_MACRO_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
/**
* Ready to use log macros with no context or tag.
**/
@ -80,3 +94,8 @@
#define DDLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define DDLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define DDLogErrorToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, NO, LOG_LEVEL_DEF, DDLogFlagError, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define DDLogWarnToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define DDLogInfoToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define DDLogDebugToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define DDLogVerboseToDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_DDLOG(ddlog, LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)

View File

@ -0,0 +1,38 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
// with or without modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Neither the name of Deusty nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission of Deusty, LLC.
#import <Foundation/Foundation.h>
// Disable legacy macros
#ifndef DD_LEGACY_MACROS
#define DD_LEGACY_MACROS 0
#endif
#import "DDLog.h"
/**
* This class provides a logger for the Apple os_log facility.
**/
API_AVAILABLE(ios(10.0), macos(10.12), tvos(10.0), watchos(3.0))
@interface DDOSLogger : DDAbstractLogger <DDLogger>
/**
* Singleton method
*
* @return the shared instance
*/
@property (class, readonly, strong) DDOSLogger *sharedInstance;
@end

View File

@ -0,0 +1,77 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
// with or without modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Neither the name of Deusty nor the names of its contributors may be used
// to endorse or promote products derived from this software without specific
// prior written permission of Deusty, LLC.
#import "DDOSLogger.h"
#import <os/log.h>
static DDOSLogger *sharedInstance;
@implementation DDOSLogger
+ (instancetype)sharedInstance {
static dispatch_once_t DDOSLoggerOnceToken;
dispatch_once(&DDOSLoggerOnceToken, ^{
sharedInstance = [[[self class] alloc] init];
});
return sharedInstance;
}
- (instancetype)init {
if (sharedInstance != nil) {
return nil;
}
if (self = [super init]) {
return self;
}
return nil;
}
- (void)logMessage:(DDLogMessage *)logMessage {
// Skip captured log messages
if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) {
return;
}
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
if (message) {
const char *msg = [message UTF8String];
switch (logMessage->_flag) {
case DDLogFlagError :
os_log_error(OS_LOG_DEFAULT, "%{public}s", msg);
break;
case DDLogFlagWarning :
case DDLogFlagInfo :
os_log_info(OS_LOG_DEFAULT, "%{public}s", msg);
break;
case DDLogFlagDebug :
case DDLogFlagVerbose :
default :
os_log_debug(OS_LOG_DEFAULT, "%{public}s", msg);
break;
}
}
}
- (NSString *)loggerName {
return @"cocoa.lumberjack.osLogger";
}
@end

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -24,8 +24,8 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#if TARGET_OS_IPHONE
// iOS
#if !(TARGET_OS_OSX)
// iOS or tvOS or watchOS
#import <UIKit/UIColor.h>
typedef UIColor DDColor;
static inline DDColor* DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
@ -62,7 +62,7 @@
/**
* Singleton method
*/
+ (instancetype)sharedInstance;
@property (class, readonly, strong) DDTTYLogger *sharedInstance;
/* Inherited from the DDLogger protocol:
*

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -118,8 +118,6 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface DDTTYLogger () {
NSUInteger _calendarUnitFlags;
NSString *_appName;
char *_app;
size_t _appLen;
@ -821,13 +819,6 @@ static DDTTYLogger *sharedInstance;
}
if ((self = [super init])) {
_calendarUnitFlags = (NSCalendarUnitYear |
NSCalendarUnitMonth |
NSCalendarUnitDay |
NSCalendarUnitHour |
NSCalendarUnitMinute |
NSCalendarUnitSecond);
// Initialze 'app' variable (char *)
_appName = [[NSProcessInfo processInfo] processName];
@ -1268,18 +1259,19 @@ static DDTTYLogger *sharedInstance;
// Calculate timestamp.
// The technique below is faster than using NSDateFormatter.
if (logMessage->_timestamp) {
NSDateComponents *components = [[NSCalendar autoupdatingCurrentCalendar] components:_calendarUnitFlags fromDate:logMessage->_timestamp];
NSTimeInterval epoch = [logMessage->_timestamp timeIntervalSince1970];
struct tm tm;
time_t time = (time_t)epoch;
(void)localtime_r(&time, &tm);
int milliseconds = (int)((epoch - floor(epoch)) * 1000.0);
NSTimeInterval epoch = [logMessage->_timestamp timeIntervalSinceReferenceDate];
int milliseconds = (int)((epoch - floor(epoch)) * 1000);
len = snprintf(ts, 24, "%04ld-%02ld-%02ld %02ld:%02ld:%02ld:%03d", // yyyy-MM-dd HH:mm:ss:SSS
(long)components.year,
(long)components.month,
(long)components.day,
(long)components.hour,
(long)components.minute,
(long)components.second, milliseconds);
len = snprintf(ts, 24, "%04d-%02d-%02d %02d:%02d:%02d:%03d", // yyyy-MM-dd HH:mm:ss:SSS
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec, milliseconds);
tsLen = (NSUInteger)MAX(MIN(24 - 1, len), 0);
}

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -65,7 +65,7 @@
/**
* Return the whitelist
*/
@property (readonly, copy) NSArray *whitelist;
@property (readonly, copy) NSArray<NSNumber *> *whitelist;
/**
* Check if a context is on the whitelist
@ -104,7 +104,7 @@
/**
* Return the blacklist
*/
@property (readonly, copy) NSArray *blacklist;
@property (readonly, copy) NSArray<NSNumber *> *blacklist;
/**

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -143,6 +143,7 @@
- (instancetype)init {
if ((self = [super init])) {
_set = [[NSMutableSet alloc] init];
_lock = OS_SPINLOCK_INIT;
}
return self;

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -63,6 +63,7 @@
_minQueueLength = 0;
_maxQueueLength = 0;
_lock = OS_SPINLOCK_INIT;
_replacements = [[NSMutableDictionary alloc] init];
// Set default replacements:

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -31,22 +31,22 @@
/**
* Array of chained formatters
*/
@property (readonly) NSArray *formatters;
@property (readonly) NSArray<id<DDLogFormatter>> *formatters;
/**
* Add a new formatter
*/
- (void)addFormatter:(id<DDLogFormatter>)formatter;
- (void)addFormatter:(id<DDLogFormatter>)formatter NS_SWIFT_NAME(add(_:));
/**
* Remove a formatter
*/
- (void)removeFormatter:(id<DDLogFormatter>)formatter;
- (void)removeFormatter:(id<DDLogFormatter>)formatter NS_SWIFT_NAME(remove(_:));
/**
* Remove all existing formatters
*/
- (void)removeAllFormatters;
- (void)removeAllFormatters NS_SWIFT_NAME(removeAll());
/**
* Check if a certain formatter is used

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2015, Deusty, LLC
// Copyright (c) 2010-2016, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,

View File

@ -1,6 +1,6 @@
Software License Agreement (BSD License)
Copyright (c) 2010-2015, Deusty, LLC
Copyright (c) 2010-2016, Deusty, LLC
All rights reserved.
Redistribution and use of this software in source and binary forms,

View File

@ -10,6 +10,7 @@ CocoaLumberjack
[![Pod Platform](http://img.shields.io/cocoapods/p/CocoaLumberjack.svg?style=flat)](http://cocoadocs.org/docsets/CocoaLumberjack/)
[![Pod License](http://img.shields.io/cocoapods/l/CocoaLumberjack.svg?style=flat)](http://opensource.org/licenses/BSD-3-Clause)
[![Reference Status](https://www.versioneye.com/objective-c/cocoalumberjack/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/cocoalumberjack/references)
[![codecov](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack/branch/master/graph/badge.svg)](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack)
**CocoaLumberjack** is a fast & simple, yet powerful & flexible logging framework for Mac and iOS.
@ -19,11 +20,15 @@ CocoaLumberjack
##### Swift version via CocoaPods
```ruby
platform :ios, '8.0'
pod 'CocoaLumberjack/Swift'
use_frameworks!
# You need to set target when you use CocoaPods 1.0.0 or later.
target 'SampleTarget' do
use_frameworks!
pod 'CocoaLumberjack/Swift'
end
```
Note: `Swift` is a subspec which will include all the Obj-C code plus the Swift one, so this is sufficient.
For more details about how to use Swift with Lumberjack, see [this converation](https://github.com/CocoaLumberjack/CocoaLumberjack/issues/405).
For more details about how to use Swift with Lumberjack, see [this conversation](https://github.com/CocoaLumberjack/CocoaLumberjack/issues/405).
##### Swift Usage
@ -33,13 +38,13 @@ import CocoaLumberjack
```
```swift
DDLog.addLogger(DDTTYLogger.sharedInstance()) // TTY = Xcode console
DDLog.addLogger(DDASLLogger.sharedInstance()) // ASL = Apple System Logs
DDLog.add(DDTTYLogger.sharedInstance) // TTY = Xcode console
DDLog.add(DDASLLogger.sharedInstance) // ASL = Apple System Logs
let fileLogger: DDFileLogger = DDFileLogger() // File Logger
fileLogger.rollingFrequency = 60*60*24 // 24 hours
fileLogger.rollingFrequency = TimeInterval(60*60*24) // 24 hours
fileLogger.logFileManager.maximumNumberOfLogFiles = 7
DDLog.addLogger(fileLogger)
DDLog.add(fileLogger)
...
@ -57,7 +62,7 @@ platform :ios, '7.0'
pod 'CocoaLumberjack'
```
##### Objc-C usage
##### Obj-C usage
If you're using Lumberjack as a framework, you can `@import CocoaLumberjack`.
Otherwise, `#import <CocoaLumberjack/CocoaLumberjack.h>`
@ -96,38 +101,11 @@ github "CocoaLumberjack/CocoaLumberjack"
- if you find issues or want to suggest improvements, create an issue or a pull request
- for all kinds of questions involving CocoaLumberjack, use the [Google group](http://groups.google.com/group/cocoalumberjack) or StackOverflow (use [#lumberjack](http://stackoverflow.com/questions/tagged/lumberjack)).
### CocoaLumberjack 2
### CocoaLumberjack 3
#### Migrating to 2.x
#### Migrating to 3.x
* Replace `DDLog.h` imports by `#import <CocoaLumberjack/CocoaLumberjack.h>`.
Advanced users, third party libraries:
* Replace all `DDLogC` macros for regular `DDLog` macros.
* Replace log level (`LOG_LEVEL_*`) macros with `DDLogLevel` enum values
* Replace log flag (`LOG_FLAG_*`) macros with `DDLogFlag` enum values
* Replace `DDLogMessage` ivars and method calls to the new ivars and methods
* `logMsg` with `_message`
* `logLevel` with `_level`
* `logFlag` with `_flag`
* `logContext` with `_context`
* `lineNumber` with `_line` (type changed from `int` to `NSUInteger`)
* `file` with `_file` (`filename` contains just the file name, without the extension and the full path)
* `timestamp` with `_timestamp`
* `methodName` with `function`
* Replace `DDAbstractLogger` `formatter` to `logFormatter`
* `YSSingleFileLogger` ivars are no longer accesible, use the methods instead
* Replace `[DDLog addLogger:withLogLevel:]` with `[DDLog addLogger:withLevel:]`
#### Forcing 1.x
If an included library requires it, you can force CocoaLumberjack 1.x by setting the version before the conflicting library:
```ruby
pod 'CocoaLumberjack', '~> 1.9'
pod 'ConflictingLibrary'
```
* To be determined
### Features
@ -173,17 +151,29 @@ Configure your logging however you want. Change log levels per file (perfect for
### Requirements
The current version of Lumberjack requires:
- Xcode 7.1 or later
- Xcode 8 or later
- Swift 3.0 or later
- iOS 5 or later
- OS X 10.7 or later
- WatchOS 2 or later
- TVOS 9 or later
#### Backwards compability
- for Xcode 7.3 and Swift 2.3, use the 2.4.0 version
- for Xcode 7.3 and Swift 2.2, use the 2.3.0 version
- for Xcode 7.2 and 7.1, use the 2.2.0 version
- for Xcode 7.0 or earlier, use the 2.1.0 version
- for Xcode 6 or earlier, use the 2.0.x version
- for OS X < 10.7 support, use the 1.6.0 version
### Communication
- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/lumberjack). (Tag 'lumberjack')
- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/lumberjack).
- If you **found a bug**, open an issue.
- If you **have a feature request**, open an issue.
- If you **want to contribute**, submit a pull request.
### Author
- [Robbie Hanson](https://github.com/robbiehanson)
- Love the project? Wanna buy me a coffee? (or a beer :D) [![donation](http://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UZRA26JPJB3DA)
@ -192,6 +182,13 @@ The current version of Lumberjack requires:
- [Ernesto Rivera](https://github.com/rivera-ernesto)
- [Dmitry Vorobyov](https://github.com/dvor)
- [Bogdan Poplauschi](https://github.com/bpoplauschi)
- [C.W. Betts](https://github.com/MaddTheSane)
### License
- CocoaLumberjack is available under the BSD license. See the [LICENSE file](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/LICENSE.txt).
### Architecture
<p align="center" >
<img src="Documentation/CocoaLumberjackClassDiagram.png" title="CocoaLumberjack class diagram">
</p>

View File

@ -0,0 +1 @@
../../../CocoaLumberjack/Classes/DDOSLogger.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Internal/YapDatabaseAtomic.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCore.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCoreConnection.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Execution/YapDatabaseCloudCoreGraph.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Operations/YapDatabaseCloudCoreOperation.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Internal/YapDatabaseCloudCoreOperationPrivate.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCoreOptions.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Execution/YapDatabaseCloudCorePipeline.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Execution/YapDatabaseCloudCorePipelineDelegate.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Internal/YapDatabaseCloudCorePipelinePrivate.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Internal/YapDatabaseCloudCorePrivate.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCoreTransaction.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Utilities/YapDatabaseConnectionConfig.h

View File

@ -1 +0,0 @@
../../../../../../YapDatabase/Internal/YapDatabaseConnectionDefaults.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/YapManyToManyCache.h

View File

@ -0,0 +1 @@
../../../CocoaLumberjack/Classes/DDOSLogger.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCore.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCoreConnection.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Execution/YapDatabaseCloudCoreGraph.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Operations/YapDatabaseCloudCoreOperation.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCoreOptions.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Execution/YapDatabaseCloudCorePipeline.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/Execution/YapDatabaseCloudCorePipelineDelegate.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/YapDatabaseCloudCoreTransaction.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Utilities/YapDatabaseConnectionConfig.h

View File

@ -0,0 +1 @@
../../../../../../YapDatabase/Extensions/CloudCore/Utilities/YapManyToManyCache.h

View File

@ -1,6 +1,6 @@
{
"name": "YapDatabase",
"version": "2.9.3",
"version": "3.0.1",
"summary": "A key/value store built atop sqlite for iOS & Mac.",
"homepage": "https://github.com/yapstudios/YapDatabase",
"license": "MIT",
@ -9,7 +9,7 @@
},
"source": {
"git": "https://github.com/yapstudios/YapDatabase.git",
"tag": "2.9.3"
"tag": "3.0.1"
},
"platforms": {
"osx": "10.9",
@ -31,7 +31,7 @@
"libraries": "sqlite3",
"dependencies": {
"CocoaLumberjack": [
"~> 2"
]
},
"source_files": [
@ -127,11 +127,6 @@
},
{
"name": "CloudKit",
"platforms": {
"osx": "10.8",
"ios": "6.0",
"tvos": "9.0"
},
"source_files": "YapDatabase/Extensions/CloudKit/**/*.{h,m,mm,c}",
"private_header_files": "YapDatabase/Extensions/CloudKit/Internal/*.h"
},
@ -156,12 +151,17 @@
"frameworks": "SystemConfiguration"
},
"dependencies": {
"YapDatabase/Standard/Extensions/View": [
"YapDatabase/Standard/Extensions/AutoView": [
]
},
"source_files": "YapDatabase/Extensions/ActionManager/**/*.{h,m,mm,c}",
"private_header_files": "YapDatabase/Extensions/ActionManager/Internal/*.h"
},
{
"name": "CloudCore",
"source_files": "YapDatabase/Extensions/CloudCore/**/*.{h,m,mm,c}",
"private_header_files": "YapDatabase/Extensions/CloudCore/Internal/*.h"
}
]
}
@ -180,7 +180,7 @@
">= 3.4.0"
],
"CocoaLumberjack": [
"~> 2"
]
},
"source_files": [
@ -276,11 +276,6 @@
},
{
"name": "CloudKit",
"platforms": {
"osx": "10.8",
"ios": "6.0",
"tvos": "9.0"
},
"source_files": "YapDatabase/Extensions/CloudKit/**/*.{h,m,mm,c}",
"private_header_files": "YapDatabase/Extensions/CloudKit/Internal/*.h"
},
@ -305,12 +300,17 @@
"frameworks": "SystemConfiguration"
},
"dependencies": {
"YapDatabase/SQLCipher/Extensions/View": [
"YapDatabase/SQLCipher/Extensions/AutoView": [
]
},
"source_files": "YapDatabase/Extensions/ActionManager/**/*.{h,m,mm,c}",
"private_header_files": "YapDatabase/Extensions/ActionManager/Internal/*.h"
},
{
"name": "CloudCore",
"source_files": "YapDatabase/Extensions/CloudCore/**/*.{h,m,mm,c}",
"private_header_files": "YapDatabase/Extensions/CloudCore/Internal/*.h"
}
]
}

View File

@ -1,69 +1,70 @@
PODS:
- CocoaLumberjack (2.2.0):
- CocoaLumberjack/Default (= 2.2.0)
- CocoaLumberjack/Extensions (= 2.2.0)
- CocoaLumberjack/Core (2.2.0)
- CocoaLumberjack/Default (2.2.0):
- CocoaLumberjack/Core
- CocoaLumberjack/Extensions (2.2.0):
- CocoaLumberjack (3.2.1):
- CocoaLumberjack/Default (= 3.2.1)
- CocoaLumberjack/Extensions (= 3.2.1)
- CocoaLumberjack/Default (3.2.1)
- CocoaLumberjack/Extensions (3.2.1):
- CocoaLumberjack/Default
- Reachability (3.2)
- YapDatabase (2.9.3):
- YapDatabase/Standard (= 2.9.3)
- YapDatabase/Standard (2.9.3):
- YapDatabase/Standard/Core (= 2.9.3)
- YapDatabase/Standard/Extensions (= 2.9.3)
- YapDatabase/Standard/Core (2.9.3):
- CocoaLumberjack (~> 2)
- YapDatabase/Standard/Extensions (2.9.3):
- YapDatabase (3.0.1):
- YapDatabase/Standard (= 3.0.1)
- YapDatabase/Standard (3.0.1):
- YapDatabase/Standard/Core (= 3.0.1)
- YapDatabase/Standard/Extensions (= 3.0.1)
- YapDatabase/Standard/Core (3.0.1):
- CocoaLumberjack
- YapDatabase/Standard/Extensions (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ActionManager (= 2.9.3)
- YapDatabase/Standard/Extensions/AutoView (= 2.9.3)
- YapDatabase/Standard/Extensions/CloudKit (= 2.9.3)
- YapDatabase/Standard/Extensions/ConnectionProxy (= 2.9.3)
- YapDatabase/Standard/Extensions/CrossProcessNotification (= 2.9.3)
- YapDatabase/Standard/Extensions/FilteredView (= 2.9.3)
- YapDatabase/Standard/Extensions/FullTextSearch (= 2.9.3)
- YapDatabase/Standard/Extensions/Hooks (= 2.9.3)
- YapDatabase/Standard/Extensions/ManualView (= 2.9.3)
- YapDatabase/Standard/Extensions/Relationships (= 2.9.3)
- YapDatabase/Standard/Extensions/RTreeIndex (= 2.9.3)
- YapDatabase/Standard/Extensions/SearchResultsView (= 2.9.3)
- YapDatabase/Standard/Extensions/SecondaryIndex (= 2.9.3)
- YapDatabase/Standard/Extensions/View (= 2.9.3)
- YapDatabase/Standard/Extensions/ActionManager (2.9.3):
- YapDatabase/Standard/Extensions/ActionManager (= 3.0.1)
- YapDatabase/Standard/Extensions/AutoView (= 3.0.1)
- YapDatabase/Standard/Extensions/CloudCore (= 3.0.1)
- YapDatabase/Standard/Extensions/CloudKit (= 3.0.1)
- YapDatabase/Standard/Extensions/ConnectionProxy (= 3.0.1)
- YapDatabase/Standard/Extensions/CrossProcessNotification (= 3.0.1)
- YapDatabase/Standard/Extensions/FilteredView (= 3.0.1)
- YapDatabase/Standard/Extensions/FullTextSearch (= 3.0.1)
- YapDatabase/Standard/Extensions/Hooks (= 3.0.1)
- YapDatabase/Standard/Extensions/ManualView (= 3.0.1)
- YapDatabase/Standard/Extensions/Relationships (= 3.0.1)
- YapDatabase/Standard/Extensions/RTreeIndex (= 3.0.1)
- YapDatabase/Standard/Extensions/SearchResultsView (= 3.0.1)
- YapDatabase/Standard/Extensions/SecondaryIndex (= 3.0.1)
- YapDatabase/Standard/Extensions/View (= 3.0.1)
- YapDatabase/Standard/Extensions/ActionManager (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/AutoView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/AutoView (2.9.3):
- YapDatabase/Standard/Extensions/CloudCore (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CloudKit (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ConnectionProxy (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CrossProcessNotification (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/CloudKit (2.9.3):
- YapDatabase/Standard/Extensions/FullTextSearch (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ConnectionProxy (2.9.3):
- YapDatabase/Standard/Extensions/Hooks (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CrossProcessNotification (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (2.9.3):
- YapDatabase/Standard/Extensions/ManualView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/FullTextSearch (2.9.3):
- YapDatabase/Standard/Extensions/Relationships (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/Hooks (2.9.3):
- YapDatabase/Standard/Extensions/RTreeIndex (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ManualView (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/Relationships (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/RTreeIndex (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/SearchResultsView (2.9.3):
- YapDatabase/Standard/Extensions/SearchResultsView (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/FullTextSearch
- YapDatabase/Standard/Extensions/SecondaryIndex (2.9.3):
- YapDatabase/Standard/Extensions/SecondaryIndex (3.0.1):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View (2.9.3):
- YapDatabase/Standard/Extensions/View (3.0.1):
- YapDatabase/Standard/Core
DEPENDENCIES:
@ -75,10 +76,10 @@ EXTERNAL SOURCES:
:path: ../../
SPEC CHECKSUMS:
CocoaLumberjack: 17fe8581f84914d5d7e6360f7c70022b173c3ae0
CocoaLumberjack: 2800c03334042fe80589423c8d80e582dcaec482
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
YapDatabase: cf1907a45a8e033d8205381e096dd73b5d4d261e
YapDatabase: 69ca88a2dfee305fde4412cf670c76f75aa7ccd0
PODFILE CHECKSUM: f638f9f64b041c51ac6d2f50f15969b4ed017571
PODFILE CHECKSUM: 39de1b3e71c8e5fd8a2fd5205a886ee12a55be4a
COCOAPODS: 1.1.1
COCOAPODS: 1.3.1

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -4,5 +4,6 @@ HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Priva
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/CocoaLumberjack
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES

View File

@ -5,7 +5,7 @@ This application makes use of the following third party libraries:
Software License Agreement (BSD License)
Copyright (c) 2010-2015, Deusty, LLC
Copyright (c) 2010-2016, Deusty, LLC
All rights reserved.
Redistribution and use of this software in source and binary forms,

View File

@ -16,7 +16,7 @@
<key>FooterText</key>
<string>Software License Agreement (BSD License)
Copyright (c) 2010-2015, Deusty, LLC
Copyright (c) 2010-2016, Deusty, LLC
All rights reserved.
Redistribution and use of this software in source and binary forms,

View File

@ -6,6 +6,10 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
@ -23,9 +27,9 @@ install_framework()
source="$(readlink "${source}")"
fi
# use filter instead of exclude so missing patterns dont' throw errors
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@ -54,13 +58,27 @@ install_framework()
fi
}
# Copies the dSYM of a vendored framework
install_dsym() {
local source="$1"
if [ -r "$source" ]; then
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}"
fi
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identitiy
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\""
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
@ -71,7 +89,7 @@ strip_invalid_archs() {
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
@ -82,3 +100,6 @@ strip_invalid_archs() {
fi
}
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi

View File

@ -8,6 +8,10 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
XCASSET_FILES=()
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
case "${TARGETED_DEVICE_FAMILY}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
@ -18,6 +22,12 @@ case "${TARGETED_DEVICE_FAMILY}" in
2)
TARGET_DEVICE_ARGS="--target-device ipad"
;;
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
4)
TARGET_DEVICE_ARGS="--target-device watch"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
@ -38,29 +48,29 @@ EOM
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
@ -68,7 +78,7 @@ EOM
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" || true
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac

View File

@ -1,4 +1,3 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/Reachability" "${PODS_ROOT}/Headers/Public/YapDatabase"
LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/CocoaLumberjack" "$PODS_CONFIGURATION_BUILD_DIR/Reachability" "$PODS_CONFIGURATION_BUILD_DIR/YapDatabase"
@ -6,4 +5,5 @@ OTHER_CFLAGS = $(inherited) -DYAP_STANDARD_SQLITE $(inherited) -isystem "${PODS_
OTHER_LDFLAGS = $(inherited) -ObjC -l"CocoaLumberjack" -l"Reachability" -l"YapDatabase" -l"c++" -l"sqlite3" -framework "SystemConfiguration"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods

View File

@ -1,4 +1,3 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/Reachability" "${PODS_ROOT}/Headers/Public/YapDatabase"
LIBRARY_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/CocoaLumberjack" "$PODS_CONFIGURATION_BUILD_DIR/Reachability" "$PODS_CONFIGURATION_BUILD_DIR/YapDatabase"
@ -6,4 +5,5 @@ OTHER_CFLAGS = $(inherited) -DYAP_STANDARD_SQLITE $(inherited) -isystem "${PODS_
OTHER_LDFLAGS = $(inherited) -ObjC -l"CocoaLumberjack" -l"Reachability" -l"YapDatabase" -l"c++" -l"sqlite3" -framework "SystemConfiguration"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods

View File

@ -1,4 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -5,5 +5,6 @@ OTHER_LDFLAGS = -framework "SystemConfiguration"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Reachability
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES

View File

@ -1,4 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -7,5 +7,6 @@ OTHER_LDFLAGS = -l"c++" -l"sqlite3" -framework "SystemConfiguration"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../..
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES

View File

@ -10,8 +10,10 @@ framework module YapDatabase {
header "YapDatabaseExtensionTypes.h"
module Utilities {
header "YapBidirectionalCache.h"
header "YapCache.h"
header "YapCollectionKey.h"
header "YapDatabaseConnectionConfig.h"
header "YapDatabaseQuery.h"
header "YapMurmurHash.h"
header "YapProxyObject.h"
@ -21,10 +23,9 @@ framework module YapDatabase {
}
// Extension: View
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -32,7 +33,18 @@ framework module YapDatabase {
header "YapDatabaseViewChange.h"
header "YapDatabaseViewRangeOptions.h"
}
// Extension: AutoView
explicit module YapDatabaseAutoView {
header "YapDatabaseViewTypes.h"
header "YapDatabaseAutoView.h"
header "YapDatabaseAutoViewConnection.h"
header "YapDatabaseAutoViewTransaction.h"
export YapDatabaseView
}
// Extension: FilteredView
explicit module YapDatabaseFilteredView {
@ -128,6 +140,12 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -146,4 +164,18 @@ framework module YapDatabase {
header "YapDatabaseCrossProcessNotificationConnection.h"
header "YapDatabaseCrossProcessNotificationTransaction.h"
}
// Extension: CloudCore
explicit module YapDatabaseCloudCore {
header "YapDatabaseCloudCore.h"
header "YapDatabaseCloudCoreOptions.h"
header "YapDatabaseCloudCoreConnection.h"
header "YapDatabaseCloudCoreTransaction.h"
header "YapManyToManyCache.h"
header "YapDatabaseCloudCoreOperation.h"
header "YapDatabaseCloudCorePipelineDelegate.h"
header "YapDatabaseCloudCorePipeline.h"
header "YapDatabaseCloudCoreGraph.h"
}
}

View File

@ -16,6 +16,7 @@
@import YapDatabase.YapDatabaseHooks;
@import YapDatabase.YapDatabaseRTreeIndex;
@import YapDatabase.YapDatabaseConnectionProxy;
@import YapDatabase.YapDatabaseConnectionPool;
@import YapDatabase.YapDatabaseActionManager;
#if !TARGET_OS_WATCH
@import YapDatabase.YapDatabaseCloudKit;

View File

@ -10,8 +10,10 @@ framework module YapDatabase {
header "YapDatabaseExtensionTypes.h"
module Utilities {
header "YapBidirectionalCache.h"
header "YapCache.h"
header "YapCollectionKey.h"
header "YapDatabaseConnectionConfig.h"
header "YapDatabaseQuery.h"
header "YapMurmurHash.h"
header "YapProxyObject.h"
@ -24,7 +26,6 @@ framework module YapDatabase {
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -32,7 +33,18 @@ framework module YapDatabase {
header "YapDatabaseViewChange.h"
header "YapDatabaseViewRangeOptions.h"
}
// Extension: AutoView
explicit module YapDatabaseAutoView {
header "YapDatabaseViewTypes.h"
header "YapDatabaseAutoView.h"
header "YapDatabaseAutoViewConnection.h"
header "YapDatabaseAutoViewTransaction.h"
export YapDatabaseView
}
// Extension: FilteredView
explicit module YapDatabaseFilteredView {
@ -56,7 +68,7 @@ framework module YapDatabase {
}
// Extension: SecondaryIndex
explicit module YapDatabaseSecondaryIndex {
header "YapDatabaseSecondaryIndex.h"
header "YapDatabaseSecondaryIndexSetup.h"
@ -128,6 +140,12 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -146,4 +164,18 @@ framework module YapDatabase {
header "YapDatabaseCrossProcessNotificationConnection.h"
header "YapDatabaseCrossProcessNotificationTransaction.h"
}
// Extension: CloudCore
explicit module YapDatabaseCloudCore {
header "YapDatabaseCloudCore.h"
header "YapDatabaseCloudCoreOptions.h"
header "YapDatabaseCloudCoreConnection.h"
header "YapDatabaseCloudCoreTransaction.h"
header "YapManyToManyCache.h"
header "YapDatabaseCloudCoreOperation.h"
header "YapDatabaseCloudCorePipelineDelegate.h"
header "YapDatabaseCloudCorePipeline.h"
header "YapDatabaseCloudCoreGraph.h"
}
}

View File

@ -10,8 +10,10 @@ framework module YapDatabase {
header "YapDatabaseExtensionTypes.h"
module Utilities {
header "YapBidirectionalCache.h"
header "YapCache.h"
header "YapCollectionKey.h"
header "YapDatabaseConnectionConfig.h"
header "YapDatabaseQuery.h"
header "YapMurmurHash.h"
header "YapProxyObject.h"
@ -21,10 +23,9 @@ framework module YapDatabase {
}
// Extension: View
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -32,7 +33,18 @@ framework module YapDatabase {
header "YapDatabaseViewChange.h"
header "YapDatabaseViewRangeOptions.h"
}
// Extension: AutoView
explicit module YapDatabaseAutoView {
header "YapDatabaseViewTypes.h"
header "YapDatabaseAutoView.h"
header "YapDatabaseAutoViewConnection.h"
header "YapDatabaseAutoViewTransaction.h"
export YapDatabaseView
}
// Extension: FilteredView
explicit module YapDatabaseFilteredView {
@ -128,6 +140,12 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -146,4 +164,18 @@ framework module YapDatabase {
header "YapDatabaseCrossProcessNotificationConnection.h"
header "YapDatabaseCrossProcessNotificationTransaction.h"
}
// Extension: CloudCore
explicit module YapDatabaseCloudCore {
header "YapDatabaseCloudCore.h"
header "YapDatabaseCloudCoreOptions.h"
header "YapDatabaseCloudCoreConnection.h"
header "YapDatabaseCloudCoreTransaction.h"
header "YapManyToManyCache.h"
header "YapDatabaseCloudCoreOperation.h"
header "YapDatabaseCloudCorePipelineDelegate.h"
header "YapDatabaseCloudCorePipeline.h"
header "YapDatabaseCloudCoreGraph.h"
}
}

View File

@ -10,8 +10,10 @@ framework module YapDatabase {
header "YapDatabaseExtensionTypes.h"
module Utilities {
header "YapBidirectionalCache.h"
header "YapCache.h"
header "YapCollectionKey.h"
header "YapDatabaseConnectionConfig.h"
header "YapDatabaseQuery.h"
header "YapMurmurHash.h"
header "YapProxyObject.h"
@ -21,10 +23,9 @@ framework module YapDatabase {
}
// Extension: View
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -32,6 +33,17 @@ framework module YapDatabase {
header "YapDatabaseViewChange.h"
header "YapDatabaseViewRangeOptions.h"
}
// Extension: AutoView
explicit module YapDatabaseAutoView {
header "YapDatabaseViewTypes.h"
header "YapDatabaseAutoView.h"
header "YapDatabaseAutoViewConnection.h"
header "YapDatabaseAutoViewTransaction.h"
export YapDatabaseView
}
// Extension: FilteredView
@ -128,6 +140,12 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -146,4 +164,18 @@ framework module YapDatabase {
header "YapDatabaseCrossProcessNotificationConnection.h"
header "YapDatabaseCrossProcessNotificationTransaction.h"
}
// Extension: CloudCore
explicit module YapDatabaseCloudCore {
header "YapDatabaseCloudCore.h"
header "YapDatabaseCloudCoreOptions.h"
header "YapDatabaseCloudCoreConnection.h"
header "YapDatabaseCloudCoreTransaction.h"
header "YapManyToManyCache.h"
header "YapDatabaseCloudCoreOperation.h"
header "YapDatabaseCloudCorePipelineDelegate.h"
header "YapDatabaseCloudCorePipeline.h"
header "YapDatabaseCloudCoreGraph.h"
}
}

View File

@ -1,6 +1,4 @@
YapDatabase
===========
![YapDatabaseLogo](https://user-images.githubusercontent.com/449168/27611211-2570fbb6-5b46-11e7-85e9-f3378a5bebce.gif)
[![Build Status](https://travis-ci.org/yapstudios/YapDatabase.svg?branch=master)](https://travis-ci.org/yapstudios/YapDatabase)
[![Pod Version](https://img.shields.io/cocoapods/v/YapDatabase.svg?style=flat)](https://cocoapods.org/pods/YapDatabase)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
@ -30,8 +28,6 @@ It has the following features:
* **Performance**. Fetch thousands of objects on the main thread without dropping a frame.
* **Objective-C**. A simple to use Objective-C API means you'll be up and running in no time.
<br/>
**[See what the API looks like in "hello world" for YapDatabase](https://github.com/yapstudios/YapDatabase/wiki/Hello-World)**<br/>

View File

@ -21,6 +21,9 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Standard inverse relationship: (child)->(parent)
@ -36,6 +39,10 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Retain count relationship: (retainer)->(retained)
* nodeDeleteRule = YDB_DeleteDestinationIfAllSourcesDeleted
@ -51,6 +58,10 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Inverse retain count relationship: (retained)->(retainer)
* nodeDeleteRule = YDB_DeleteSourceIfAllDestinationsDeleted
@ -66,6 +77,10 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Standard file relationship: (parent)->(file)
* nodeDeleteRule = YDB_DeleteDestinationIfSourceDeleted
@ -80,6 +95,10 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Retain count file relationship: (parent)->(file)
* nodeDeleteRule = YDB_DeleteDestinationIfAllSourcesDeleted
@ -94,3 +113,30 @@
@property (nonatomic, copy, readwrite) NSURL *fileURL;
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Notify & Delete relationship: (parent)->(child)
* nodeDeleteRule = YDB_DeleteDestinationIfSourceDeleted | YDB_NotifyIfSourceDeleted
*
* So the parent node creates the edge which points to the child node.
* And the child should get deleted if the parent is deleted.
* But the child node also needs to get notified first.
**/
@interface Node_Notify : NSObject <NSCoding, YapDatabaseRelationshipNode>
@property (nonatomic, strong, readonly) NSString *key;
@property (nonatomic, strong, readwrite) NSString *child;
@end
@interface Node_NotifyCount : NSObject <NSCoding, YapDatabaseRelationshipNode>
@property (nonatomic, strong, readonly) NSString *key;
+ (NSUInteger)notifyCount;
@end

View File

@ -319,4 +319,105 @@
return @[ edge ];
}
@end
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation Node_Notify
@synthesize key = key;
@synthesize child = child;
- (id)init
{
if ((self = [super init]))
{
key = [[NSUUID UUID] UUIDString];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [super init]))
{
key = [decoder decodeObjectForKey:@"key"];
child = [decoder decodeObjectForKey:@"child"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:key forKey:@"key"];
[coder encodeObject:child forKey:@"child"];
}
- (NSArray *)yapDatabaseRelationshipEdges
{
if (child == nil) return nil;
YapDatabaseRelationshipEdge *edge =
[YapDatabaseRelationshipEdge edgeWithName:@"child"
destinationKey:child
collection:nil
nodeDeleteRules:(YDB_DeleteDestinationIfSourceDeleted | YDB_NotifyIfSourceDeleted)];
return @[ edge ];
}
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@implementation Node_NotifyCount
static NSUInteger notifyCount = 0;
@synthesize key = key;
- (id)init
{
if ((self = [super init]))
{
key = [[NSUUID UUID] UUIDString];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder
{
if ((self = [super init]))
{
key = [decoder decodeObjectForKey:@"key"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:key forKey:@"key"];
}
- (NSArray<YapDatabaseRelationshipEdge *> *)yapDatabaseRelationshipEdges
{
return nil;
}
- (id)yapDatabaseRelationshipEdgeDeleted:(YapDatabaseRelationshipEdge *)edge
withReason:(YDB_NotifyReason)reason
{
notifyCount++;
return nil;
}
+ (NSUInteger)notifyCount
{
return notifyCount;
}
@end

View File

@ -50,7 +50,7 @@
YapDatabaseConnection *connection = [database newConnection];
YapDatabaseFullTextSearchHandler *handler = [YapDatabaseFullTextSearchHandler withObjectBlock:
^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
^(YapDatabaseReadTransaction *transaction, NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
[dict setObject:object forKey:@"content"];
}];
@ -169,7 +169,7 @@
YapDatabaseConnection *connection = [database newConnection];
YapDatabaseFullTextSearchHandler *handler = [YapDatabaseFullTextSearchHandler withObjectBlock:
^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
^(YapDatabaseReadTransaction *transaction, NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
[dict setObject:object forKey:@"content"];
}];

View File

@ -4217,4 +4217,184 @@
XCTAssert(count == 4);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Issue #399 - https://github.com/yapstudios/YapDatabase/pull/399
**/
- (void)testIssue399
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
[[NSFileManager defaultManager] removeItemAtPath:databasePath error:NULL];
YapDatabase *database = [[YapDatabase alloc] initWithPath:databasePath];
XCTAssertNotNil(database);
YapDatabaseConnection *connection = [database newConnection];
YapDatabaseRelationship *relationship = [[YapDatabaseRelationship alloc] init];
BOOL registered = [database registerExtension:relationship withName:@"relationship"];
XCTAssertTrue(registered, @"Error registering extension");
[connection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
NSString *srcWithMissingDst = @"src1";
NSString *dstWithMissingSrc = @"dst2";
// NSString *missingPath = [self databasePath:@"phoney_baloney"];
// NSURL *missingURL = [NSURL fileURLWithPath:missingPath isDirectory:NO];
// We're ensuring we don't get an assertion in [YapDatabaseRelationshipTransaction deleteEdge:]
[transaction setObject:srcWithMissingDst forKey:srcWithMissingDst inCollection:nil];
[transaction setObject:dstWithMissingSrc forKey:dstWithMissingSrc inCollection:nil];
YapDatabaseRelationshipEdge *e1 =
[YapDatabaseRelationshipEdge edgeWithName:@"test1"
sourceKey:srcWithMissingDst
collection:nil
destinationKey:@"missing"
collection:nil
nodeDeleteRules:YDB_DeleteDestinationIfSourceDeleted];
YapDatabaseRelationshipEdge *e2 =
[YapDatabaseRelationshipEdge edgeWithName:@"test3"
sourceKey:@"missing"
collection:nil
destinationKey:dstWithMissingSrc
collection:nil
nodeDeleteRules:YDB_DeleteSourceIfDestinationDeleted];
YapDatabaseRelationshipEdge *e3 =
[YapDatabaseRelationshipEdge edgeWithName:@"test4"
sourceKey:@"missing"
collection:nil
destinationKey:@"missing"
collection:nil
nodeDeleteRules:YDB_DeleteSourceIfDestinationDeleted];
// YapDatabaseRelationshipEdge *e4 =
// [YapDatabaseRelationshipEdge edgeWithName:@"test2"
// sourceKey:@"missing"
// collection:nil
// destinationFileURL:missingURL
// nodeDeleteRules:YDB_DeleteDestinationIfSourceDeleted];
[[transaction ext:@"relationship"] addEdge:e1];
[[transaction ext:@"relationship"] addEdge:e2];
[[transaction ext:@"relationship"] addEdge:e3];
// [[transaction ext:@"relationship"] addEdge:e4];
}];
}
/**
* Issue #399 refers to a crash when:
* - manual edges are being used
* - an edge is being immediately deleted
* - but the NotInDatabase flag wasn't being set
*
* We discovered a similar crash when using protocolEdges.
**/
- (void)testIssue399_protocol
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
[[NSFileManager defaultManager] removeItemAtPath:databasePath error:NULL];
YapDatabase *database = [[YapDatabase alloc] initWithPath:databasePath];
XCTAssertNotNil(database);
YapDatabaseConnection *connection = [database newConnection];
YapDatabaseRelationship *relationship = [[YapDatabaseRelationship alloc] init];
BOOL registered = [database registerExtension:relationship withName:@"relationship"];
XCTAssertTrue(registered, @"Error registering extension");
__block Node_Standard *node = nil;
[connection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction setObject:@"string" forKey:@"valid" inCollection:nil];
node = [[Node_Standard alloc] init];
node.childKeys = @[@"valid", @"invalid-1"];
// The node.childKeys has 2 items,
// and so it will attempt to create 2 edges.
// - The first is valid
// - The second is invalid
//
// The invalid edge should be deleted during [YapDBRelationshipTransaction flush].
//
// Note:
// In this case, 'node' is a newly inserted item in the database.
// Which means the code path taken is different from a modified item.
// So we need another unit test to achieve proper unit test coverage for this issue.
//
[transaction setObject:node forKey:node.key inCollection:nil];
}];
[connection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) {
node = [transaction objectForKey:node.key inCollection:nil];
node.childKeys = @[@"valid", @"invalid-2"];
// In this case, 'node' is a modified item in the database.
// Which means the code path taken is different from an inserted item.
//
[transaction setObject:node forKey:node.key inCollection:nil];
}];
}
/**
* Issue #426 - https://github.com/yapstudios/YapDatabase/issues/426
**/
- (void)testDeleteAndNotify
{
NSString *databasePath = [self databasePath:NSStringFromSelector(_cmd)];
[[NSFileManager defaultManager] removeItemAtPath:databasePath error:NULL];
YapDatabase *database = [[YapDatabase alloc] initWithPath:databasePath];
XCTAssertNotNil(database);
YapDatabaseConnection *connection = [database newConnection];
YapDatabaseRelationship *relationship = [[YapDatabaseRelationship alloc] init];
BOOL registered = [database registerExtension:relationship withName:@"relationship"];
XCTAssertTrue(registered, @"Error registering extension");
__block NSString *parentKey = nil;
[connection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
Node_NotifyCount *child = [[Node_NotifyCount alloc] init];
Node_Notify *parent = [[Node_Notify alloc] init];
parent.child = child.key;
parentKey = parent.key;
[transaction setObject:parent forKey:parent.key inCollection:nil];
[transaction setObject:child forKey:child.key inCollection:nil];
}];
XCTAssert([Node_NotifyCount notifyCount] == 0);
[connection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction removeObjectForKey:parentKey inCollection:nil];
}];
XCTAssert([Node_NotifyCount notifyCount] == 1);
}
@end

View File

@ -169,7 +169,7 @@
// Setup FTS
YapDatabaseFullTextSearchHandler *handler = [YapDatabaseFullTextSearchHandler withObjectBlock:
^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
^(YapDatabaseReadTransaction *transaction, NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
[dict setObject:object forKey:@"content"];
}];
@ -259,7 +259,7 @@
// Setup FTS
YapDatabaseFullTextSearchHandler *handler = [YapDatabaseFullTextSearchHandler withObjectBlock:
^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
^(YapDatabaseReadTransaction *transaction, NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
[dict setObject:object forKey:@"content"];
}];

View File

@ -1,5 +1,5 @@
project 'YapDatabaseTesting.xcodeproj'
platform :osx, '10.10'
platform :osx, '10.12'
target 'YapDatabase' do
pod "YapDatabase", path: '../../'

View File

@ -1,66 +1,72 @@
PODS:
- CocoaLumberjack (3.2.0):
- CocoaLumberjack/Default (= 3.2.0)
- CocoaLumberjack/Extensions (= 3.2.0)
- CocoaLumberjack/Default (3.2.0)
- CocoaLumberjack/Extensions (3.2.0):
- CocoaLumberjack (3.4.1):
- CocoaLumberjack/Default (= 3.4.1)
- CocoaLumberjack/Extensions (= 3.4.1)
- CocoaLumberjack/Default (3.4.1)
- CocoaLumberjack/Extensions (3.4.1):
- CocoaLumberjack/Default
- YapDatabase (2.9.3):
- YapDatabase/Standard (= 2.9.3)
- YapDatabase/Standard (2.9.3):
- YapDatabase/Standard/Core (= 2.9.3)
- YapDatabase/Standard/Extensions (= 2.9.3)
- YapDatabase/Standard/Core (2.9.3):
- YapDatabase (3.0.2):
- YapDatabase/Standard (= 3.0.2)
- YapDatabase/Standard (3.0.2):
- YapDatabase/Standard/Core (= 3.0.2)
- YapDatabase/Standard/Extensions (= 3.0.2)
- YapDatabase/Standard/Core (3.0.2):
- CocoaLumberjack
- YapDatabase/Standard/Extensions (2.9.3):
- YapDatabase/Standard/Extensions (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ActionManager (= 2.9.3)
- YapDatabase/Standard/Extensions/AutoView (= 2.9.3)
- YapDatabase/Standard/Extensions/CloudKit (= 2.9.3)
- YapDatabase/Standard/Extensions/ConnectionProxy (= 2.9.3)
- YapDatabase/Standard/Extensions/CrossProcessNotification (= 2.9.3)
- YapDatabase/Standard/Extensions/FilteredView (= 2.9.3)
- YapDatabase/Standard/Extensions/FullTextSearch (= 2.9.3)
- YapDatabase/Standard/Extensions/Hooks (= 2.9.3)
- YapDatabase/Standard/Extensions/ManualView (= 2.9.3)
- YapDatabase/Standard/Extensions/Relationships (= 2.9.3)
- YapDatabase/Standard/Extensions/RTreeIndex (= 2.9.3)
- YapDatabase/Standard/Extensions/SearchResultsView (= 2.9.3)
- YapDatabase/Standard/Extensions/SecondaryIndex (= 2.9.3)
- YapDatabase/Standard/Extensions/View (= 2.9.3)
- YapDatabase/Standard/Extensions/ActionManager (2.9.3):
- YapDatabase/Standard/Extensions/ActionManager (= 3.0.2)
- YapDatabase/Standard/Extensions/AutoView (= 3.0.2)
- YapDatabase/Standard/Extensions/CloudCore (= 3.0.2)
- YapDatabase/Standard/Extensions/CloudKit (= 3.0.2)
- YapDatabase/Standard/Extensions/ConnectionPool (= 3.0.2)
- YapDatabase/Standard/Extensions/ConnectionProxy (= 3.0.2)
- YapDatabase/Standard/Extensions/CrossProcessNotification (= 3.0.2)
- YapDatabase/Standard/Extensions/FilteredView (= 3.0.2)
- YapDatabase/Standard/Extensions/FullTextSearch (= 3.0.2)
- YapDatabase/Standard/Extensions/Hooks (= 3.0.2)
- YapDatabase/Standard/Extensions/ManualView (= 3.0.2)
- YapDatabase/Standard/Extensions/Relationships (= 3.0.2)
- YapDatabase/Standard/Extensions/RTreeIndex (= 3.0.2)
- YapDatabase/Standard/Extensions/SearchResultsView (= 3.0.2)
- YapDatabase/Standard/Extensions/SecondaryIndex (= 3.0.2)
- YapDatabase/Standard/Extensions/View (= 3.0.2)
- YapDatabase/Standard/Extensions/ActionManager (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/AutoView (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/AutoView (2.9.3):
- YapDatabase/Standard/Extensions/CloudCore (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CloudKit (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ConnectionPool (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ConnectionProxy (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CrossProcessNotification (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/CloudKit (2.9.3):
- YapDatabase/Standard/Extensions/FullTextSearch (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ConnectionProxy (2.9.3):
- YapDatabase/Standard/Extensions/Hooks (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/CrossProcessNotification (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (2.9.3):
- YapDatabase/Standard/Extensions/ManualView (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/FullTextSearch (2.9.3):
- YapDatabase/Standard/Extensions/Relationships (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/Hooks (2.9.3):
- YapDatabase/Standard/Extensions/RTreeIndex (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ManualView (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/Relationships (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/RTreeIndex (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/SearchResultsView (2.9.3):
- YapDatabase/Standard/Extensions/SearchResultsView (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/FullTextSearch
- YapDatabase/Standard/Extensions/SecondaryIndex (2.9.3):
- YapDatabase/Standard/Extensions/SecondaryIndex (3.0.2):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View (2.9.3):
- YapDatabase/Standard/Extensions/View (3.0.2):
- YapDatabase/Standard/Core
DEPENDENCIES:
@ -71,9 +77,9 @@ EXTERNAL SOURCES:
:path: ../../
SPEC CHECKSUMS:
CocoaLumberjack: 9b4aed7073d242f29cc2f62068d995faf67f703a
YapDatabase: 0828f878acea7624718899cd5250734e2dc224f9
CocoaLumberjack: 2e258a064cacc8eb9a2aca318e24d02a0a7fd56d
YapDatabase: 972eccb0c997d0dafe8192dccf7f58351914baf1
PODFILE CHECKSUM: 27f2264941859e807f069adfc2aa0a50167ae03d
PODFILE CHECKSUM: 8dceb5c937bc6e9558d8d75103d141eef959b637
COCOAPODS: 1.2.0
COCOAPODS: 1.4.0

View File

@ -86,10 +86,10 @@ public func DDLogError(_ message: @autoclosure () -> String, level: DDLogLevel =
public func CurrentFileName(_ fileName: StaticString = #file) -> String {
var str = String(describing: fileName)
if let idx = str.range(of: "/", options: .backwards)?.upperBound {
str = str.substring(from: idx)
str = String(str[idx...])
}
if let idx = str.range(of: ".", options: .backwards)?.lowerBound {
str = str.substring(to: idx)
str = String(str[..<idx])
}
return str
}

View File

@ -397,7 +397,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
* You can optionally force the current log file to be rolled with this method.
* CompletionBlock will be called on main queue.
*/
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
/**
* Method is deprecated.

View File

@ -279,47 +279,18 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
- (BOOL)isLogFile:(NSString *)fileName {
NSString *appName = [self applicationName];
BOOL hasProperPrefix = [fileName hasPrefix:appName];
// We need to add a space to the name as otherwise we could match applications that have the name prefix.
BOOL hasProperPrefix = [fileName hasPrefix:[appName stringByAppendingString:@" "]];
BOOL hasProperSuffix = [fileName hasSuffix:@".log"];
BOOL hasProperDate = NO;
if (hasProperPrefix && hasProperSuffix) {
NSUInteger lengthOfMiddle = fileName.length - appName.length - @".log".length;
// Date string should have at least 16 characters - " 2013-12-03 17-14"
if (lengthOfMiddle >= 17) {
NSRange range = NSMakeRange(appName.length, lengthOfMiddle);
NSString *middle = [fileName substringWithRange:range];
NSArray *components = [middle componentsSeparatedByString:@" "];
// When creating logfile if there is existing file with the same name, we append attemp number at the end.
// Thats why here we can have three or four components. For details see createNewLogFile method.
//
// Components:
// "", "2013-12-03", "17-14"
// or
// "", "2013-12-03", "17-14", "1"
if (components.count == 3 || components.count == 4) {
NSString *dateString = [NSString stringWithFormat:@"%@ %@", components[1], components[2]];
NSDateFormatter *dateFormatter = [self logFileDateFormatter];
NSDate *date = [dateFormatter dateFromString:dateString];
if (date) {
hasProperDate = YES;
}
}
}
}
return (hasProperPrefix && hasProperDate && hasProperSuffix);
return (hasProperPrefix && hasProperSuffix);
}
// if you change formatter, then change sortedLogFileInfos method also accordingly
- (NSDateFormatter *)logFileDateFormatter {
NSMutableDictionary *dictionary = [[NSThread currentThread]
threadDictionary];
NSString *dateFormat = @"yyyy'-'MM'-'dd' 'HH'-'mm'";
NSString *dateFormat = @"yyyy'-'MM'-'dd'--'HH'-'mm'-'ss'-'SSS'";
NSString *key = [NSString stringWithFormat:@"logFileDateFormatter.%@", dateFormat];
NSDateFormatter *dateFormatter = dictionary[key];
@ -417,13 +388,35 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
}
- (NSArray *)sortedLogFileInfos {
return [[self unsortedLogFileInfos] sortedArrayUsingSelector:@selector(reverseCompareByCreationDate:)];
return [[self unsortedLogFileInfos] sortedArrayUsingComparator:^NSComparisonResult(DDLogFileInfo * _Nonnull obj1, DDLogFileInfo * _Nonnull obj2) {
NSDate *date1 = [NSDate new];
NSDate *date2 = [NSDate new];
NSArray<NSString *> *arrayComponent = [[obj1 fileName] componentsSeparatedByString:@" "];
if (arrayComponent.count > 0) {
NSString *stringDate = arrayComponent.lastObject;
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""];
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""];
date1 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj1 creationDate];
}
arrayComponent = [[obj2 fileName] componentsSeparatedByString:@" "];
if (arrayComponent.count > 0) {
NSString *stringDate = arrayComponent.lastObject;
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""];
stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""];
date2 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj2 creationDate];
}
return [date2 compare:date1 ?: [NSDate new]];
}];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Creation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//if you change newLogFileName , then change isLogFile method also accordingly
- (NSString *)newLogFileName {
NSString *appName = [self applicationName];
@ -779,7 +772,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
[self rollLogFileWithCompletionBlock:nil];
}
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock {
- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock {
// This method is public.
// We need to execute the rolling on our logging thread/queue.

View File

@ -351,17 +351,16 @@ static NSUInteger _numProcessors;
// Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked.
// If the calling semaphore does not need to block, no kernel call is made.
dispatch_semaphore_wait(_queueSemaphore, DISPATCH_TIME_FOREVER);
// We've now sure we won't overflow the queue.
// It is time to queue our log message.
dispatch_block_t logBlock = ^{
dispatch_semaphore_wait(_queueSemaphore, DISPATCH_TIME_FOREVER);
@autoreleasepool {
[self lt_log:logMessage];
}
};
// We've now sure we won't overflow the queue.
// It is time to queue our log message.
if (asyncFlag) {
dispatch_async(_loggingQueue, logBlock);
} else {

View File

@ -25,7 +25,6 @@
/**
* This class provides a logger for the Apple os_log facility.
**/
API_AVAILABLE(ios(10.0), macos(10.12), tvos(10.0), watchos(3.0))
@interface DDOSLogger : DDAbstractLogger <DDLogger>
/**

View File

@ -48,26 +48,30 @@ static DDOSLogger *sharedInstance;
return;
}
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
if (message) {
const char *msg = [message UTF8String];
if(@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
switch (logMessage->_flag) {
case DDLogFlagError :
os_log_error(OS_LOG_DEFAULT, msg);
break;
case DDLogFlagWarning :
case DDLogFlagInfo :
os_log_info(OS_LOG_DEFAULT, msg);
break;
case DDLogFlagDebug :
case DDLogFlagVerbose :
default :
os_log_debug(OS_LOG_DEFAULT, msg);
break;
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
if (message) {
const char *msg = [message UTF8String];
switch (logMessage->_flag) {
case DDLogFlagError :
os_log_error(OS_LOG_DEFAULT, "%{public}s", msg);
break;
case DDLogFlagWarning :
case DDLogFlagInfo :
os_log_info(OS_LOG_DEFAULT, "%{public}s", msg);
break;
case DDLogFlagDebug :
case DDLogFlagVerbose :
default :
os_log_debug(OS_LOG_DEFAULT, "%{public}s", msg);
break;
}
}
}
}
- (NSString *)loggerName {

Some files were not shown because too many files have changed in this diff Show More