Compare commits

..

No commits in common. "master" and "v3.0" have entirely different histories.
master ... v3.0

387 changed files with 13107 additions and 18116 deletions

View File

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

View File

@ -1 +1 @@
github "CocoaLumberjack/CocoaLumberjack" "3.3.0"
github "CocoaLumberjack/CocoaLumberjack" "2.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 = (
DC212CE11F6D98F600C11BF0 /* CloudKit.framework in Frameworks */,
DC9A34D61BB5CA650067AD13 /* CloudKit.framework in Frameworks */,
DCDE78831A302B46001D8FCE /* libsqlite3.dylib in Frameworks */,
51EE553F951BF40945032BD5 /* libPods-CloudKitTodo.a in Frameworks */,
);
@ -129,7 +129,7 @@
DCDE776B1A3028EA001D8FCE /* Frameworks */ = {
isa = PBXGroup;
children = (
DC212CE01F6D98F600C11BF0 /* CloudKit.framework */,
DC9A34D51BB5CA650067AD13 /* CloudKit.framework */,
DCDE78821A302B46001D8FCE /* libsqlite3.dylib */,
ABB1832E9FCC349F48EB4C9C /* libPods-CloudKitTodo.a */,
);
@ -207,7 +207,7 @@
DCDE77131A3023E9001D8FCE /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = "Deusty LLC";
TargetAttributes = {
DCDE771A1A3023E9001D8FCE = {
@ -217,9 +217,6 @@
com.apple.BackgroundModes = {
enabled = 1;
};
com.apple.Push = {
enabled = 1;
};
com.apple.iCloud = {
enabled = 1;
};
@ -267,16 +264,13 @@
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_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";
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";
showEnvVarsInLog = 0;
};
A7E36A79EF95353C65F5D2B6 /* [CP] Embed Pods Frameworks */ = {
@ -359,20 +353,14 @@
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;
@ -395,7 +383,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@ -411,20 +399,14 @@
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;
@ -440,7 +422,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
@ -465,6 +447,7 @@
"\"${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)";
@ -489,6 +472,7 @@
"\"${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,10 +1,11 @@
#import <UIKit/UIKit.h>
#import <Reachability/Reachability.h>
#import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseCloudKit.h>
#import "YapDatabase.h"
#import "YapDatabaseCloudKit.h"
@class AppDelegate;
extern AppDelegate *MyAppDelegate;
@ -15,3 +16,4 @@ extern AppDelegate *MyAppDelegate;
@property (nonatomic, strong, readonly) Reachability *reachability;
@end

View File

@ -1,15 +1,16 @@
#import "AppDelegate.h"
#import "CloudKitManager.h"
#import "DatabaseManager.h"
#import "CloudKitManager.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;
@ -75,21 +76,10 @@ AppDelegate *MyAppDelegate;
// Register for push notifications
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];
});
}];
UIUserNotificationSettings *notificationSettings =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[application registerUserNotificationSettings:notificationSettings];
// Start reachability
@ -128,6 +118,14 @@ 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,23 +197,14 @@ 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.";
UIAlertController* alert =
[UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertView *alertView =
[[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Oops", nil];
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];
[alertView show];
};
if ([NSThread isMainThread])
@ -229,23 +220,14 @@ 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 ???";
UIAlertController* alert =
[UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertView *alertView =
[[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:@"Of Course", nil];
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];
[alertView show];
};
if ([NSThread isMainThread])
@ -367,14 +349,10 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
}
CKRecordZoneID *recordZoneID =
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKCurrentUserDefaultName];
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKOwnerDefaultName];
CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.shouldSendContentAvailable = YES;
CKRecordZoneSubscription *subscription =
[[CKRecordZoneSubscription alloc] initWithZoneID:recordZoneID subscriptionID:CloudKitZoneName];
subscription.notificationInfo = notificationInfo;
CKSubscription *subscription =
[[CKSubscription alloc] initWithZoneID:recordZoneID subscriptionID:CloudKitZoneName options:0];
CKModifySubscriptionsOperation *modifySubscriptionsOperation =
[[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:@[ subscription ]
@ -485,20 +463,16 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
(void (^)(UIBackgroundFetchResult result, BOOL moreComing))completionHandler
{
CKRecordZoneID *recordZoneID =
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKCurrentUserDefaultName];
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKOwnerDefaultName];
CKFetchRecordZoneChangesOptions *zoneOptions = [CKFetchRecordZoneChangesOptions new];
zoneOptions.previousServerChangeToken = prevServerChangeToken;
CKFetchRecordZoneChangesOperation *operation =
[[CKFetchRecordZoneChangesOperation alloc] initWithRecordZoneIDs:@[recordZoneID]
optionsByRecordZoneID:@{recordZoneID: zoneOptions}];
operation.fetchAllChanges = NO;
CKFetchRecordChangesOperation *operation =
[[CKFetchRecordChangesOperation alloc] initWithRecordZoneID:recordZoneID
previousServerChangeToken:prevServerChangeToken];
__block NSMutableArray *deletedRecordIDs = nil;
__block NSMutableArray *changedRecords = nil;
operation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID, NSString *recordType){
operation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID){
if (deletedRecordIDs == nil)
deletedRecordIDs = [[NSMutableArray alloc] init];
@ -514,14 +488,14 @@ static NSString *const Key_ServerChangeToken = @"serverChangeToken";
[changedRecords addObject:record];
};
operation.recordZoneFetchCompletionBlock =
^(CKRecordZoneID *recordZoneID, CKServerChangeToken *newServerChangeToken,
NSData *clientChangeTokenData, BOOL moreComing, NSError *operationError)
{
DDLogVerbose(@"CKFetchRecordZoneChangesOperation.recordZoneFetchCompletionBlock");
__weak CKFetchRecordChangesOperation *weakOperation = operation;
operation.fetchRecordChangesCompletionBlock =
^(CKServerChangeToken *newServerChangeToken, NSData *clientChangeTokenData, NSError *operationError){
DDLogVerbose(@"CKFetchRecordZoneChangesOperation: serverChangeToken: %@", newServerChangeToken);
DDLogVerbose(@"CKFetchRecordZoneChangesOperation: clientChangeTokenData: %@", clientChangeTokenData);
DDLogVerbose(@"CKFetchRecordChangesOperation.fetchRecordChangesCompletionBlock");
DDLogVerbose(@"CKFetchRecordChangesOperation: serverChangeToken: %@", newServerChangeToken);
DDLogVerbose(@"CKFetchRecordChangesOperation: clientChangeTokenData: %@", clientChangeTokenData);
// Edge Case:
//
@ -538,6 +512,8 @@ 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,8 +2,6 @@
<!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,6 +6,7 @@
#import "MyTodo.h"
#import <CocoaLumberjack/CocoaLumberjack.h>
#import <Reachability/Reachability.h>
// Log Levels: off, error, warn, info, verbose
// Log Flags : trace
@ -290,7 +291,7 @@ DatabaseManager *MyDatabaseManager;
if (record == nil)
{
CKRecordZoneID *zoneID =
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKCurrentUserDefaultName];
[[CKRecordZoneID alloc] initWithZoneName:CloudKitZoneName ownerName:CKOwnerDefaultName];
CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:todo.uuid zoneID:zoneID];

View File

@ -1,15 +1,5 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
@ -40,16 +30,6 @@
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
@ -79,16 +59,6 @@
"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, '10.0'
platform :ios, '8.0'
target 'CloudKitTodo' do
pod 'Reachability', '3.2'
pod "YapDatabase", path: '../../'
end
end

View File

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

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// Copyright (c) 2010-2015, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -78,9 +78,4 @@
#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-2016, Deusty, LLC
// Copyright (c) 2014-2015, 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 from(_ logLevel: DDLogLevel) -> DDLogFlag {
public static func fromLogLevel(logLevel: DDLogLevel) -> DDLogFlag {
return DDLogFlag(rawValue: logLevel.rawValue)
}
@ -26,70 +26,66 @@ extension DDLogFlag {
///returns the log level, or the lowest equivalant.
public func toLogLevel() -> DDLogLevel {
if let ourValid = DDLogLevel(rawValue: rawValue) {
if let ourValid = DDLogLevel(rawValue: self.rawValue) {
return ourValid
} else {
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
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
} 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 _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 {
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 {
// Tell the DDLogMessage constructor to copy the C strings that get passed to it.
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)
// 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)
}
}
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 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 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 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 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 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 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 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 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)
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)
}
/// 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 {
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
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
}

View File

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

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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
*/
@property (class, readonly, strong) DDASLLogger *sharedInstance;
+ (instancetype)sharedInstance;
// Inherited from DDAbstractLogger

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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 (message) {
if (logMessage) {
const char *msg = [message UTF8String];
size_t aslLogLevel;
@ -90,7 +90,7 @@ static DDASLLogger *sharedInstance;
char readUIDString[16];
#ifndef NS_BLOCK_ASSERTIONS
size_t l = snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
int 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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 * (NSTimeInterval) NSEC_PER_SEC);
uint64_t interval = (uint64_t)(_saveInterval * NSEC_PER_SEC);
dispatch_time_t startTime = dispatch_time(_unsavedTime, interval);
dispatch_source_set_timer(_saveTimer, startTime, interval, 1ull * NSEC_PER_SEC);
dispatch_source_set_timer(_saveTimer, startTime, interval, 1.0);
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 * (NSTimeInterval) NSEC_PER_SEC);
uint64_t interval = (uint64_t)(_deleteInterval * 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, 1ull * NSEC_PER_SEC);
dispatch_source_set_timer(_deleteTimer, startTime, interval, 1.0);
}
}

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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)
*/
@property (nonatomic, readonly, copy) NSString *logsDirectory;
- (NSString *)logsDirectory;
/**
* Returns an array of `NSString` objects,
* each of which is the filePath to an existing log file on disk.
**/
@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFilePaths;
- (NSArray *)unsortedLogFilePaths;
/**
* Returns an array of `NSString` objects,
* each of which is the fileName of an existing log file on disk.
**/
@property (nonatomic, readonly, strong) NSArray<NSString *> *unsortedLogFileNames;
- (NSArray *)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.
**/
@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *unsortedLogFileInfos;
- (NSArray *)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.
**/
@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFilePaths;
- (NSArray *)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.
**/
@property (nonatomic, readonly, strong) NSArray<NSString *> *sortedLogFileNames;
- (NSArray *)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.
**/
@property (nonatomic, readonly, strong) NSArray<DDLogFileInfo *> *sortedLogFileInfos;
- (NSArray *)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 NS_SWIFT_NAME(didArchiveLogFile(atPath:));
- (void)didArchiveLogFile:(NSString *)logFilePath;
/**
* Called when the roll action was executed and the log was archieved
*/
- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:));
- (void)didRollAndArchiveLogFile:(NSString *)logFilePath;
@end
@ -203,7 +203,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
* null
* cy#
**/
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel;
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString *)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 NS_SWIFT_NAME(isLogFile(withName:));
- (BOOL)isLogFile:(NSString *)fileName;
/* Inherited from DDLogFileManager protocol:
@ -302,9 +302,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
/**
* The standard implementation for a file logger
*/
@interface DDFileLogger : DDAbstractLogger <DDLogger> {
DDLogFileInfo *_currentLogFileInfo;
}
@interface DDFileLogger : DDAbstractLogger <DDLogger>
/**
* Default initializer
@ -316,27 +314,11 @@ 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 (in bytes) to allow log files to grow.
* The approximate maximum size to allow log files to grow.
* If a log file is larger than this value after a log statement is appended,
* then the log file is rolled.
*
@ -345,9 +327,6 @@ 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.
*
@ -397,7 +376,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 (^)(void))completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock;
/**
* Method is deprecated.
@ -417,7 +396,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
*
* Otherwise a new file is created and returned.
**/
@property (nonatomic, readonly, strong) DDLogFileInfo *currentLogFileInfo;
- (DDLogFileInfo *)currentLogFileInfo;
@end
@ -444,11 +423,7 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
@property (strong, nonatomic, readonly) NSString *filePath;
@property (strong, nonatomic, readonly) NSString *fileName;
#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) NSDictionary *fileAttributes;
@property (strong, nonatomic, readonly) NSDate *creationDate;
@property (strong, nonatomic, readonly) NSDate *modificationDate;
@ -459,13 +434,13 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
@property (nonatomic, readwrite) BOOL isArchived;
+ (instancetype)logFileWithPath:(NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)");
+ (instancetype)logFileWithPath:(NSString *)filePath;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER;
- (void)reset;
- (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:));
- (void)renameFile:(NSString *)newFileName;
#if TARGET_IPHONE_SIMULATOR

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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
NSFileProtectionType _defaultFileProtectionLevel;
NSString *_defaultFileProtectionLevel;
#endif
}
@ -115,7 +115,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
}
#if TARGET_OS_IPHONE
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel {
- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString *)fileProtectionLevel {
if ((self = [self initWithLogsDirectory:logsDirectory])) {
if ([fileProtectionLevel isEqualToString:NSFileProtectionNone] ||
[fileProtectionLevel isEqualToString:NSFileProtectionComplete] ||
@ -281,15 +281,45 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
BOOL hasProperPrefix = [fileName hasPrefix:appName];
BOOL hasProperSuffix = [fileName hasSuffix:@".log"];
return (hasProperPrefix && hasProperSuffix);
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);
}
//if you change formater , then change sortedLogFileInfos method also accordingly
- (NSDateFormatter *)logFileDateFormatter {
NSMutableDictionary *dictionary = [[NSThread currentThread]
threadDictionary];
NSString *dateFormat = @"yyyy'-'MM'-'dd'--'HH'-'mm'-'ss'-'SSS'";
NSString *dateFormat = @"yyyy'-'MM'-'dd' 'HH'-'mm'";
NSString *key = [NSString stringWithFormat:@"logFileDateFormatter.%@", dateFormat];
NSDateFormatter *dateFormatter = dictionary[key];
@ -387,35 +417,13 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
}
- (NSArray *)sortedLogFileInfos {
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];
}];
return [[self unsortedLogFileInfos] sortedArrayUsingSelector:@selector(reverseCompareByCreationDate:)];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Creation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//if you change newLogFileName , then change isLogFile method also accordingly
- (NSString *)newLogFileName {
NSString *appName = [self applicationName];
@ -459,7 +467,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.
NSFileProtectionType key = _defaultFileProtectionLevel ? :
NSString *key = _defaultFileProtectionLevel ? :
(doesAppRunInBackground() ? NSFileProtectionCompleteUntilFirstUserAuthentication : NSFileProtectionCompleteUnlessOpen);
attributes = @{
@ -549,6 +557,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
@interface DDFileLogger () {
__strong id <DDLogFileManager> _logFileManager;
DDLogFileInfo *_currentLogFileInfo;
NSFileHandle *_currentLogFileHandle;
dispatch_source_t _currentLogFileVnode;
@ -760,10 +769,10 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
});
#endif
uint64_t delay = (uint64_t)([logFileRollingDate timeIntervalSinceNow] * (NSTimeInterval) NSEC_PER_SEC);
uint64_t delay = (uint64_t)([logFileRollingDate timeIntervalSinceNow] * NSEC_PER_SEC);
dispatch_time_t fireTime = dispatch_time(DISPATCH_TIME_NOW, delay);
dispatch_source_set_timer(_rollingTimer, fireTime, DISPATCH_TIME_FOREVER, 1ull * NSEC_PER_SEC);
dispatch_source_set_timer(_rollingTimer, fireTime, DISPATCH_TIME_FOREVER, 1.0);
dispatch_resume(_rollingTimer);
}
@ -771,7 +780,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
[self rollLogFileWithCompletionBlock:nil];
}
- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock {
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock {
// This method is public.
// We need to execute the rolling on our logging thread/queue.
@ -882,9 +891,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
if (mostRecentLogFileInfo.isArchived) {
shouldArchiveMostRecent = NO;
} else if ([self shouldArchiveRecentLogFileInfo:mostRecentLogFileInfo]) {
shouldArchiveMostRecent = YES;
} else if (_maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= _maximumFileSize) {
} else if (_maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= _maximumFileSize) {
shouldArchiveMostRecent = YES;
} else if (_rollingFrequency > 0.0 && mostRecentLogFileInfo.age >= _rollingFrequency) {
shouldArchiveMostRecent = YES;
@ -900,10 +907,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 overwritten to NSFileProtectionNone there is no neeed to create a new one.
// If user has owerwritten to NSFileProtectionNone there is no neeed to create a new one.
if (!_doNotReuseLogFiles && doesAppRunInBackground()) {
NSFileProtectionType key = mostRecentLogFileInfo.fileAttributes[NSFileProtectionKey];
NSString *key = mostRecentLogFileInfo.fileAttributes[NSFileProtectionKey];
if ([key length] > 0 && !([key isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication] || [key isEqualToString:NSFileProtectionNone])) {
shouldArchiveMostRecent = YES;
@ -998,11 +1005,9 @@ static int exception_count = 0;
NSData *logData = [message dataUsingEncoding:NSUTF8StringEncoding];
@try {
[self willLogMessage];
[[self currentLogFileHandle] writeData:logData];
[self didLogMessage];
[self maybeRollLogFileDueToSize];
} @catch (NSException *exception) {
exception_count++;
@ -1017,18 +1022,6 @@ 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];
@ -1099,7 +1092,7 @@ static int exception_count = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (NSDictionary *)fileAttributes {
if (_fileAttributes == nil && filePath != nil) {
if (_fileAttributes == nil) {
_fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
}
@ -1429,10 +1422,6 @@ 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -29,7 +29,6 @@
#endif
@class DDLogMessage;
@class DDLoggerInformation;
@protocol DDLogger;
@protocol DDLogFormatter;
@ -102,27 +101,27 @@
*/
typedef NS_OPTIONS(NSUInteger, DDLogFlag){
/**
* 0...00001 DDLogFlagError
* 0...00000 DDLogFlagError
*/
DDLogFlagError = (1 << 0),
/**
* 0...00010 DDLogFlagWarning
* 0...00001 DDLogFlagWarning
*/
DDLogFlagWarning = (1 << 1),
/**
* 0...00100 DDLogFlagInfo
* 0...00010 DDLogFlagInfo
*/
DDLogFlagInfo = (1 << 2),
/**
* 0...01000 DDLogFlagDebug
* 0...00100 DDLogFlagDebug
*/
DDLogFlagDebug = (1 << 3),
/**
* 0...10000 DDLogFlagVerbose
* 0...01000 DDLogFlagVerbose
*/
DDLogFlagVerbose = (1 << 4)
};
@ -167,8 +166,6 @@ typedef NS_ENUM(NSUInteger, DDLogLevel){
DDLogLevelAll = NSUIntegerMax
};
NS_ASSUME_NONNULL_BEGIN
/**
* Extracts just the file name, no path or extension
*
@ -177,7 +174,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return the file name
*/
NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
/**
* The THIS_FILE macro gives you an NSString of the file name.
@ -208,17 +205,11 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
*/
@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.
**/
@property (class, nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE, readonly) dispatch_queue_t loggingQueue;
+ (dispatch_queue_t)loggingQueue;
/**
* Logging Primitive.
@ -243,33 +234,7 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
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
tag:(id)tag
format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
/**
@ -296,17 +261,15 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
file:(const char *)file
function:(const char *)function
line:(NSUInteger)line
tag:(id __nullable)tag
tag:(id)tag
format:(NSString *)format
args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
args:(va_list)argList;
/**
* 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:...`
* Logging Primitive.
*
* @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)
@ -314,19 +277,16 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
* @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
+ (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 __nullable)tag
format:(NSString *)format
args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
tag:(id)tag;
/**
* Logging Primitive.
@ -337,18 +297,7 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
* @param logMessage the log message stored in a `DDLogMessage` model object
*/
+ (void)log:(BOOL)asynchronous
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:));
message:(DDLogMessage *)logMessage;
/**
* Since logging can be asynchronous, there may be times when you want to flush the logs.
@ -356,12 +305,6 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
**/
+ (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
*
@ -379,13 +322,6 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
**/
+ (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.
*
@ -424,83 +360,20 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
**/
+ (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
*/
@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;
+ (NSArray *)allLoggers;
/**
* Registered Dynamic Logging
@ -512,12 +385,12 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
/**
* Returns an array with the classes that are using registered dynamic logging
*/
@property (class, nonatomic, copy, readonly) NSArray<Class> *registeredClasses;
+ (NSArray *)registeredClasses;
/**
* Returns an array with the classes names that are using registered dynamic logging
*/
@property (class, nonatomic, copy, readonly) NSArray<NSString*> *registeredClassNames;
+ (NSArray *)registeredClassNames;
/**
* Returns the current log level for a certain class
@ -567,7 +440,7 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
*
* @param logMessage the message (model)
*/
- (void)logMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(log(message:));
- (void)logMessage:(DDLogMessage *)logMessage;
/**
* Formatters may optionally be added to any logger.
@ -592,19 +465,6 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
**/
- (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`
*/
@ -660,7 +520,7 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
* The formatter may also optionally filter the log message by returning nil,
* in which case the logger will not log the message.
**/
- (NSString * __nullable)formatLogMessage:(DDLogMessage *)logMessage NS_SWIFT_NAME(format(message:));
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
@optional
@ -675,18 +535,6 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
**/
- (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:`
*/
@ -726,7 +574,12 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
* }
* ```
**/
@property (class, nonatomic, readwrite, setter=ddSetLogLevel:) DDLogLevel ddLogLevel;
+ (DDLogLevel)ddLogLevel;
/**
* See the above description for `ddLogLevel`
*/
+ (void)ddSetLogLevel:(DDLogLevel)level;
@end
@ -745,15 +598,11 @@ 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,
/**
* Use this to use avoid a copy of the message
*/
DDLogMessageDontCopyMessage = 1 << 2
DDLogMessageCopyFunction = 1 << 1
};
/**
@ -781,9 +630,9 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
}
/**
* Default `init` for empty messages.
* Default `init` is not available
*/
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
/**
* Standard init method for a log message object.
@ -817,11 +666,11 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(NSString *)file
function:(NSString * __nullable)function
function:(NSString *)function
line:(NSUInteger)line
tag:(id __nullable)tag
tag:(id)tag
options:(DDLogMessageOptions)options
timestamp:(NSDate * __nullable)timestamp NS_DESIGNATED_INITIALIZER;
timestamp:(NSDate *)timestamp NS_DESIGNATED_INITIALIZER;
/**
* Read-only properties
@ -836,9 +685,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 * __nullable function;
@property (readonly, nonatomic) NSString *function;
@property (readonly, nonatomic) NSUInteger line;
@property (readonly, nonatomic) id __nullable tag;
@property (readonly, nonatomic) id 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
@ -875,7 +724,7 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
dispatch_queue_t _loggerQueue;
}
@property (nonatomic, strong, nullable) id <DDLogFormatter> logFormatter;
@property (nonatomic, strong) id <DDLogFormatter> logFormatter;
@property (nonatomic, DISPATCH_QUEUE_REFERENCE_TYPE) dispatch_queue_t loggerQueue;
// For thread-safety assertions
@ -892,18 +741,3 @@ 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -21,7 +21,6 @@
#import "DDLog.h"
#import <pthread.h>
#import <dispatch/dispatch.h>
#import <objc/runtime.h>
#import <mach/mach_host.h>
#import <mach/host_info.h>
@ -60,9 +59,7 @@
// 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.
#ifndef DDLOG_MAX_QUEUE_SIZE
#define DDLOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX
#endif
#define LOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX
// The "global logging queue" refers to [DDLog loggingQueue].
// It is the queue that all log statements go through.
@ -96,15 +93,11 @@ static void *const GlobalLoggingQueueIdentityKey = (void *)&GlobalLoggingQueueId
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface DDLog ()
@implementation DDLog
// An array used to manage all the individual loggers.
// The array is only modified on the loggingQueue/loggingThread.
@property (nonatomic, strong) NSMutableArray *_loggers;
@end
@implementation DDLog
static NSMutableArray *_loggers;
// All logging statements are added to the same queue to ensure FIFO operation.
static dispatch_queue_t _loggingQueue;
@ -114,29 +107,12 @@ 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 (DDLOG_MAX_QUEUE_SIZE).
// a maximum size is enforced (LOG_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
@ -147,53 +123,42 @@ 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(DDLOG_MAX_QUEUE_SIZE);
_queueSemaphore = dispatch_semaphore_create(LOG_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, (NSUInteger) 1);
NSLogDebug(@"DDLog: numProcessors = %@", @(_numProcessors));
});
}
_numProcessors = MAX([NSProcessInfo processInfo].processorCount, 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.
@ -201,18 +166,16 @@ 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;
});
}
/**
@ -226,7 +189,7 @@ static NSUInteger _numProcessors;
#pragma mark Notifications
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)applicationWillTerminate:(NSNotification * __attribute__((unused)))notification {
+ (void)applicationWillTerminate:(NSNotification * __attribute__((unused)))notification {
[self flushLog];
}
@ -235,84 +198,50 @@ 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 {
[self.sharedInstance removeAllLoggers];
}
- (void)removeAllLoggers {
dispatch_async(_loggingQueue, ^{ @autoreleasepool {
[self lt_removeAllLoggers];
} });
[self lt_removeAllLoggers];
} });
}
+ (NSArray<id<DDLogger>> *)allLoggers {
return [self.sharedInstance allLoggers];
}
- (NSArray<id<DDLogger>> *)allLoggers {
+ (NSArray *)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,
@ -342,7 +271,7 @@ static NSUInteger _numProcessors;
// We are using a counting semaphore provided by GCD.
// The semaphore is initialized with our DDLOG_MAX_QUEUE_SIZE value.
// The semaphore is initialized with our LOG_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.
@ -384,11 +313,6 @@ 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
@ -398,12 +322,12 @@ static NSUInteger _numProcessors;
function:function
line:line
tag:tag];
va_end(args);
}
}
- (void)log:(BOOL)asynchronous
+ (void)log:(BOOL)asynchronous
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
@ -411,55 +335,9 @@ static NSUInteger _numProcessors;
function:(const char *)function
line:(NSUInteger)line
tag:(id)tag
format:(NSString *)format, ... {
va_list args;
format:(NSString *)format
args:(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);
}
}
+ (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 {
[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
@ -483,18 +361,7 @@ 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
@ -510,23 +377,14 @@ 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];
} });
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -622,7 +480,7 @@ static NSUInteger _numProcessors;
classes = numClasses ? (Class *)malloc(sizeof(Class) * bufferSize) : NULL;
if (classes == NULL) {
return @[]; //no memory or classes?
return nil; //no memory or classes?
}
numClasses = (NSUInteger)MAX(objc_getClassList(classes, (int)bufferSize),0);
@ -689,18 +547,10 @@ 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");
@ -726,20 +576,16 @@ static NSUInteger _numProcessors;
}
DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue level:level];
[self._loggers addObject:loggerNode];
[_loggers addObject:loggerNode];
if ([logger respondsToSelector:@selector(didAddLoggerInQueue:)]) {
dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool {
[logger didAddLoggerInQueue:loggerNode->_loggerQueue];
} });
} else if ([logger respondsToSelector:@selector(didAddLogger)]) {
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),
@ -747,7 +593,7 @@ static NSUInteger _numProcessors;
DDLoggerNode *loggerNode = nil;
for (DDLoggerNode *node in self._loggers) {
for (DDLoggerNode *node in _loggers) {
if (node->_logger == logger) {
loggerNode = node;
break;
@ -767,15 +613,15 @@ static NSUInteger _numProcessors;
}
// Remove from loggers array
[self._loggers removeObject:loggerNode];
[_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 self._loggers) {
for (DDLoggerNode *loggerNode in _loggers) {
if ([loggerNode->_logger respondsToSelector:@selector(willRemoveLogger)]) {
dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool {
[loggerNode->_logger willRemoveLogger];
@ -785,37 +631,23 @@ static NSUInteger _numProcessors;
// Remove all loggers from array
[self._loggers removeAllObjects];
[_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 self._loggers) {
for (DDLoggerNode *loggerNode in _loggers) {
[theLoggers addObject:loggerNode->_logger];
}
return [theLoggers copy];
}
- (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 {
+ (void)lt_log:(DDLogMessage *)logMessage {
// Execute the given log message on each of our loggers.
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@ -829,7 +661,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 self._loggers) {
for (DDLoggerNode *loggerNode in _loggers) {
// skip the loggers that shouldn't write this message based on the log level
if (!(logMessage->_flag & loggerNode->_level)) {
@ -845,7 +677,7 @@ static NSUInteger _numProcessors;
} else {
// Execute each logger serialy, each within its own queue.
for (DDLoggerNode *loggerNode in self._loggers) {
for (DDLoggerNode *loggerNode in _loggers) {
// skip the loggers that shouldn't write this message based on the log level
if (!(logMessage->_flag & loggerNode->_level)) {
@ -862,7 +694,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 DDLOG_MAX_QUEUE_SIZE value.
// The semaphore is initialized with our LOG_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,
@ -875,7 +707,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.
@ -884,7 +716,7 @@ static NSUInteger _numProcessors;
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
@"This method should only be run on the logging thread/queue");
for (DDLoggerNode *loggerNode in self._loggers) {
for (DDLoggerNode *loggerNode in _loggers) {
if ([loggerNode->_logger respondsToSelector:@selector(flush)]) {
dispatch_group_async(_loggingGroup, loggerNode->_loggerQueue, ^{ @autoreleasepool {
[loggerNode->_logger flush];
@ -899,7 +731,7 @@ static NSUInteger _numProcessors;
#pragma mark Utilities
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
NSString * DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) {
if (filePath == NULL) {
return nil;
}
@ -1019,30 +851,15 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
// Compiling for iOS
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)
#define USE_DISPATCH_CURRENT_QUEUE_LABEL ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
#define USE_DISPATCH_GET_CURRENT_QUEUE ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.1)
#elif TARGET_OS_WATCH || TARGET_OS_TV
// Compiling for watchOS, tvOS
#define USE_DISPATCH_CURRENT_QUEUE_LABEL YES
#define USE_DISPATCH_GET_CURRENT_QUEUE NO
#define USE_DISPATCH_CURRENT_QUEUE_LABEL YES
#define USE_DISPATCH_GET_CURRENT_QUEUE YES
#else
@ -1059,23 +876,8 @@ static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_
#else
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)
#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
#endif
@ -1092,13 +894,13 @@ static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_
#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
@ -1108,15 +910,10 @@ static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_
#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
@ -1128,16 +925,15 @@ static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_
options:(DDLogMessageOptions)options
timestamp:(NSDate *)timestamp {
if ((self = [super init])) {
BOOL copyMessage = (options & DDLogMessageDontCopyMessage) == 0;
_message = copyMessage ? [message copy] : message;
_message = [message copy];
_level = level;
_flag = flag;
_context = context;
BOOL copyFile = (options & DDLogMessageCopyFile) != 0;
BOOL copyFile = (options & DDLogMessageCopyFile) == DDLogMessageCopyFile;
_file = copyFile ? [file copy] : file;
BOOL copyFunction = (options & DDLogMessageCopyFunction) != 0;
BOOL copyFunction = (options & DDLogMessageCopyFunction) == DDLogMessageCopyFunction;
_function = copyFunction ? [function copy] : function;
_line = line;
@ -1335,10 +1131,8 @@ static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_
}
_logFormatter = logFormatter;
if ([_logFormatter respondsToSelector:@selector(didAddToLogger:inQueue:)]) {
[_logFormatter didAddToLogger:self inQueue:_loggerQueue];
} else if ([_logFormatter respondsToSelector:@selector(didAddToLogger:)]) {
if ([_logFormatter respondsToSelector:@selector(didAddToLogger:)]) {
[_logFormatter didAddToLogger:self];
}
}
@ -1371,33 +1165,3 @@ static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_
}
@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-2016, Deusty, LLC
// Copyright (c) 2010-2015, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -35,8 +35,8 @@
#endif
/**
* These are the two macros that all other macros below compile into.
* These big multiline macros makes all the other macros easier to read.
* This is the single macro that all other macros below compile into.
* This big multiline macro makes all the other macros easier to read.
**/
#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \
[DDLog log : isAsynchronous \
@ -49,17 +49,6 @@
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:
@ -82,9 +71,6 @@
#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.
**/
@ -94,8 +80,3 @@
#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

@ -1,38 +0,0 @@
// 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

@ -1,77 +0,0 @@
// 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-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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_OSX)
// iOS or tvOS or watchOS
#if TARGET_OS_IPHONE
// iOS
#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
*/
@property (class, readonly, strong) DDTTYLogger *sharedInstance;
+ (instancetype)sharedInstance;
/* Inherited from the DDLogger protocol:
*

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// Copyright (c) 2010-2015, Deusty, LLC
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
@ -118,6 +118,8 @@
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface DDTTYLogger () {
NSUInteger _calendarUnitFlags;
NSString *_appName;
char *_app;
size_t _appLen;
@ -819,6 +821,13 @@ static DDTTYLogger *sharedInstance;
}
if ((self = [super init])) {
_calendarUnitFlags = (NSCalendarUnitYear |
NSCalendarUnitMonth |
NSCalendarUnitDay |
NSCalendarUnitHour |
NSCalendarUnitMinute |
NSCalendarUnitSecond);
// Initialze 'app' variable (char *)
_appName = [[NSProcessInfo processInfo] processName];
@ -1259,19 +1268,18 @@ static DDTTYLogger *sharedInstance;
// Calculate timestamp.
// The technique below is faster than using NSDateFormatter.
if (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);
NSDateComponents *components = [[NSCalendar autoupdatingCurrentCalendar] components:_calendarUnitFlags fromDate:logMessage->_timestamp];
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);
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);
tsLen = (NSUInteger)MAX(MIN(24 - 1, len), 0);
}

View File

@ -1,6 +1,6 @@
// Software License Agreement (BSD License)
//
// Copyright (c) 2010-2016, Deusty, LLC
// Copyright (c) 2010-2015, 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<NSNumber *> *whitelist;
@property (readonly, copy) NSArray *whitelist;
/**
* Check if a context is on the whitelist
@ -104,7 +104,7 @@
/**
* Return the blacklist
*/
@property (readonly, copy) NSArray<NSNumber *> *blacklist;
@property (readonly, copy) NSArray *blacklist;
/**

View File

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

View File

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

View File

@ -10,7 +10,6 @@ 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.
@ -20,15 +19,11 @@ CocoaLumberjack
##### Swift version via CocoaPods
```ruby
platform :ios, '8.0'
# You need to set target when you use CocoaPods 1.0.0 or later.
target 'SampleTarget' do
use_frameworks!
pod 'CocoaLumberjack/Swift'
end
pod 'CocoaLumberjack/Swift'
use_frameworks!
```
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 conversation](https://github.com/CocoaLumberjack/CocoaLumberjack/issues/405).
For more details about how to use Swift with Lumberjack, see [this converation](https://github.com/CocoaLumberjack/CocoaLumberjack/issues/405).
##### Swift Usage
@ -38,13 +33,13 @@ import CocoaLumberjack
```
```swift
DDLog.add(DDTTYLogger.sharedInstance) // TTY = Xcode console
DDLog.add(DDASLLogger.sharedInstance) // ASL = Apple System Logs
DDLog.addLogger(DDTTYLogger.sharedInstance()) // TTY = Xcode console
DDLog.addLogger(DDASLLogger.sharedInstance()) // ASL = Apple System Logs
let fileLogger: DDFileLogger = DDFileLogger() // File Logger
fileLogger.rollingFrequency = TimeInterval(60*60*24) // 24 hours
fileLogger.rollingFrequency = 60*60*24 // 24 hours
fileLogger.logFileManager.maximumNumberOfLogFiles = 7
DDLog.add(fileLogger)
DDLog.addLogger(fileLogger)
...
@ -62,7 +57,7 @@ platform :ios, '7.0'
pod 'CocoaLumberjack'
```
##### Obj-C usage
##### Objc-C usage
If you're using Lumberjack as a framework, you can `@import CocoaLumberjack`.
Otherwise, `#import <CocoaLumberjack/CocoaLumberjack.h>`
@ -101,11 +96,38 @@ 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 3
### CocoaLumberjack 2
#### Migrating to 3.x
#### Migrating to 2.x
* To be determined
* 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'
```
### Features
@ -151,29 +173,17 @@ Configure your logging however you want. Change log levels per file (perfect for
### Requirements
The current version of Lumberjack requires:
- Xcode 8 or later
- Swift 3.0 or later
- Xcode 7.1 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)
@ -182,13 +192,6 @@ 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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "YapDatabase",
"version": "3.0.1",
"version": "2.9.3",
"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": "3.0.1"
"tag": "2.9.3"
},
"platforms": {
"osx": "10.9",
@ -31,7 +31,7 @@
"libraries": "sqlite3",
"dependencies": {
"CocoaLumberjack": [
"~> 2"
]
},
"source_files": [
@ -127,6 +127,11 @@
},
{
"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"
},
@ -151,17 +156,12 @@
"frameworks": "SystemConfiguration"
},
"dependencies": {
"YapDatabase/Standard/Extensions/AutoView": [
"YapDatabase/Standard/Extensions/View": [
]
},
"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,6 +276,11 @@
},
{
"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"
},
@ -300,17 +305,12 @@
"frameworks": "SystemConfiguration"
},
"dependencies": {
"YapDatabase/SQLCipher/Extensions/AutoView": [
"YapDatabase/SQLCipher/Extensions/View": [
]
},
"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,70 +1,69 @@
PODS:
- 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 (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/Default
- Reachability (3.2)
- 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 (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/Standard/Core
- 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/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/Core
- YapDatabase/Standard/Extensions/View
- 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/Extensions/AutoView (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/FullTextSearch (3.0.1):
- YapDatabase/Standard/Extensions/CloudKit (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/Hooks (3.0.1):
- YapDatabase/Standard/Extensions/ConnectionProxy (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ManualView (3.0.1):
- YapDatabase/Standard/Extensions/CrossProcessNotification (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/Relationships (3.0.1):
- YapDatabase/Standard/Extensions/FullTextSearch (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/RTreeIndex (3.0.1):
- YapDatabase/Standard/Extensions/Hooks (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/SearchResultsView (3.0.1):
- 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/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/FullTextSearch
- YapDatabase/Standard/Extensions/SecondaryIndex (3.0.1):
- YapDatabase/Standard/Extensions/SecondaryIndex (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View (3.0.1):
- YapDatabase/Standard/Extensions/View (2.9.3):
- YapDatabase/Standard/Core
DEPENDENCIES:
@ -76,10 +75,10 @@ EXTERNAL SOURCES:
:path: ../../
SPEC CHECKSUMS:
CocoaLumberjack: 2800c03334042fe80589423c8d80e582dcaec482
CocoaLumberjack: 17fe8581f84914d5d7e6360f7c70022b173c3ae0
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
YapDatabase: 69ca88a2dfee305fde4412cf670c76f75aa7ccd0
YapDatabase: cf1907a45a8e033d8205381e096dd73b5d4d261e
PODFILE CHECKSUM: 39de1b3e71c8e5fd8a2fd5205a886ee12a55be4a
PODFILE CHECKSUM: f638f9f64b041c51ac6d2f50f15969b4ed017571
COCOAPODS: 1.3.1
COCOAPODS: 1.1.1

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,4 @@
#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,6 +4,5 @@ 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-2016, Deusty, LLC
Copyright (c) 2010-2015, 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-2016, Deusty, LLC
Copyright (c) 2010-2015, Deusty, LLC
All rights reserved.
Redistribution and use of this software in source and binary forms,

View File

@ -6,10 +6,6 @@ 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
@ -27,9 +23,9 @@ install_framework()
source="$(readlink "${source}")"
fi
# 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}"
# 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}"
local basename
basename="$(basename -s .framework "$1")"
@ -58,27 +54,13 @@ 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}"
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"
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"
fi
}
@ -89,7 +71,7 @@ strip_invalid_archs() {
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
@ -100,6 +82,3 @@ strip_invalid_archs() {
fi
}
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi

View File

@ -8,10 +8,6 @@ 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"
@ -22,12 +18,6 @@ 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"
;;
@ -48,29 +38,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}" || true
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}"
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}" || true
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}"
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}" || true
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${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}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$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\"" || true
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
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\"" || true
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
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\"" || true
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
@ -78,7 +68,7 @@ EOM
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH" || true
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac

View File

@ -1,3 +1,4 @@
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"
@ -5,5 +6,4 @@ 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,3 +1,4 @@
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"
@ -5,5 +6,4 @@ 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,12 +1,4 @@
#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,6 +5,5 @@ 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,12 +1,4 @@
#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,6 +7,5 @@ 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,10 +10,8 @@ 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"
@ -23,9 +21,10 @@ framework module YapDatabase {
}
// Extension: View
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -33,18 +32,7 @@ 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 {
@ -140,12 +128,6 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -164,18 +146,4 @@ 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,7 +16,6 @@
@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,10 +10,8 @@ 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"
@ -26,6 +24,7 @@ framework module YapDatabase {
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -33,18 +32,7 @@ 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 {
@ -68,7 +56,7 @@ framework module YapDatabase {
}
// Extension: SecondaryIndex
explicit module YapDatabaseSecondaryIndex {
header "YapDatabaseSecondaryIndex.h"
header "YapDatabaseSecondaryIndexSetup.h"
@ -140,12 +128,6 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -164,18 +146,4 @@ 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,10 +10,8 @@ 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"
@ -23,9 +21,10 @@ framework module YapDatabase {
}
// Extension: View
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -33,18 +32,7 @@ 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 {
@ -140,12 +128,6 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -164,18 +146,4 @@ 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,10 +10,8 @@ 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"
@ -23,9 +21,10 @@ framework module YapDatabase {
}
// Extension: View
explicit module YapDatabaseView {
header "YapDatabaseView.h"
header "YapDatabaseViewTypes.h"
header "YapDatabaseViewOptions.h"
header "YapDatabaseViewConnection.h"
header "YapDatabaseViewTransaction.h"
@ -33,17 +32,6 @@ 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
@ -140,12 +128,6 @@ framework module YapDatabase {
header "YapDatabaseConnectionProxy.h"
}
// Extension: ConnectionPool
explicit module YapDatabaseConnectionPool {
header "YapDatabaseConnectionPool.h"
}
// Extension: ActionManager
explicit module YapDatabaseActionManager {
@ -164,18 +146,4 @@ 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,4 +1,6 @@
![YapDatabaseLogo](https://user-images.githubusercontent.com/449168/27611211-2570fbb6-5b46-11e7-85e9-f3378a5bebce.gif)
YapDatabase
===========
[![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)
@ -28,6 +30,8 @@ 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,9 +21,6 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Standard inverse relationship: (child)->(parent)
@ -39,10 +36,6 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Retain count relationship: (retainer)->(retained)
* nodeDeleteRule = YDB_DeleteDestinationIfAllSourcesDeleted
@ -58,10 +51,6 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Inverse retain count relationship: (retained)->(retainer)
* nodeDeleteRule = YDB_DeleteSourceIfAllDestinationsDeleted
@ -77,10 +66,6 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Standard file relationship: (parent)->(file)
* nodeDeleteRule = YDB_DeleteDestinationIfSourceDeleted
@ -95,10 +80,6 @@
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Retain count file relationship: (parent)->(file)
* nodeDeleteRule = YDB_DeleteDestinationIfAllSourcesDeleted
@ -113,30 +94,3 @@
@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,105 +319,4 @@
return @[ edge ];
}
@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
@end

View File

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

View File

@ -4217,184 +4217,4 @@
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:
^(YapDatabaseReadTransaction *transaction, NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
^(NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
[dict setObject:object forKey:@"content"];
}];
@ -259,7 +259,7 @@
// Setup FTS
YapDatabaseFullTextSearchHandler *handler = [YapDatabaseFullTextSearchHandler withObjectBlock:
^(YapDatabaseReadTransaction *transaction, NSMutableDictionary *dict, NSString *collection, NSString *key, id object){
^(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.12'
platform :osx, '10.10'
target 'YapDatabase' do
pod "YapDatabase", path: '../../'

View File

@ -1,72 +1,66 @@
PODS:
- 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 (3.2.0):
- CocoaLumberjack/Default (= 3.2.0)
- CocoaLumberjack/Extensions (= 3.2.0)
- CocoaLumberjack/Default (3.2.0)
- CocoaLumberjack/Extensions (3.2.0):
- CocoaLumberjack/Default
- 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):
- 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
- YapDatabase/Standard/Extensions (3.0.2):
- YapDatabase/Standard/Extensions (2.9.3):
- YapDatabase/Standard/Core
- 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/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/Core
- YapDatabase/Standard/Extensions/View
- 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/Extensions/AutoView (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/FullTextSearch (3.0.2):
- YapDatabase/Standard/Extensions/CloudKit (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/Hooks (3.0.2):
- YapDatabase/Standard/Extensions/ConnectionProxy (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/ManualView (3.0.2):
- YapDatabase/Standard/Extensions/CrossProcessNotification (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/FilteredView (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View
- YapDatabase/Standard/Extensions/Relationships (3.0.2):
- YapDatabase/Standard/Extensions/FullTextSearch (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/RTreeIndex (3.0.2):
- YapDatabase/Standard/Extensions/Hooks (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/SearchResultsView (3.0.2):
- 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/Core
- YapDatabase/Standard/Extensions/AutoView
- YapDatabase/Standard/Extensions/FullTextSearch
- YapDatabase/Standard/Extensions/SecondaryIndex (3.0.2):
- YapDatabase/Standard/Extensions/SecondaryIndex (2.9.3):
- YapDatabase/Standard/Core
- YapDatabase/Standard/Extensions/View (3.0.2):
- YapDatabase/Standard/Extensions/View (2.9.3):
- YapDatabase/Standard/Core
DEPENDENCIES:
@ -77,9 +71,9 @@ EXTERNAL SOURCES:
:path: ../../
SPEC CHECKSUMS:
CocoaLumberjack: 2e258a064cacc8eb9a2aca318e24d02a0a7fd56d
YapDatabase: 972eccb0c997d0dafe8192dccf7f58351914baf1
CocoaLumberjack: 9b4aed7073d242f29cc2f62068d995faf67f703a
YapDatabase: 0828f878acea7624718899cd5250734e2dc224f9
PODFILE CHECKSUM: 8dceb5c937bc6e9558d8d75103d141eef959b637
PODFILE CHECKSUM: 27f2264941859e807f069adfc2aa0a50167ae03d
COCOAPODS: 1.4.0
COCOAPODS: 1.2.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 = String(str[idx...])
str = str.substring(from: idx)
}
if let idx = str.range(of: ".", options: .backwards)?.lowerBound {
str = String(str[..<idx])
str = str.substring(to: 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 (^)(void))completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
/**
* Method is deprecated.

View File

@ -279,18 +279,47 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
- (BOOL)isLogFile:(NSString *)fileName {
NSString *appName = [self applicationName];
// 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 hasProperPrefix = [fileName hasPrefix:appName];
BOOL hasProperSuffix = [fileName hasSuffix:@".log"];
return (hasProperPrefix && hasProperSuffix);
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);
}
// if you change formatter, then change sortedLogFileInfos method also accordingly
- (NSDateFormatter *)logFileDateFormatter {
NSMutableDictionary *dictionary = [[NSThread currentThread]
threadDictionary];
NSString *dateFormat = @"yyyy'-'MM'-'dd'--'HH'-'mm'-'ss'-'SSS'";
NSString *dateFormat = @"yyyy'-'MM'-'dd' 'HH'-'mm'";
NSString *key = [NSString stringWithFormat:@"logFileDateFormatter.%@", dateFormat];
NSDateFormatter *dateFormatter = dictionary[key];
@ -388,35 +417,13 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
}
- (NSArray *)sortedLogFileInfos {
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]];
}];
return [[self unsortedLogFileInfos] sortedArrayUsingSelector:@selector(reverseCompareByCreationDate:)];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Creation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//if you change newLogFileName , then change isLogFile method also accordingly
- (NSString *)newLogFileName {
NSString *appName = [self applicationName];
@ -772,7 +779,7 @@ unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20
[self rollLogFileWithCompletionBlock:nil];
}
- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock {
- (void)rollLogFileWithCompletionBlock:(void (^)())completionBlock {
// This method is public.
// We need to execute the rolling on our logging thread/queue.

View File

@ -351,16 +351,17 @@ 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,6 +25,7 @@
/**
* 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,30 +48,26 @@ static DDOSLogger *sharedInstance;
return;
}
if(@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
if (message) {
const char *msg = [message UTF8String];
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;
}
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 *)loggerName {

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