优化RTMP播放器重连和稳定性

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
caleb
2026-04-16 14:42:54 +08:00
parent f78ca66860
commit 72bfbb5cdf
81 changed files with 4869 additions and 5461 deletions

View File

@@ -14,10 +14,10 @@ PODS:
- AFNetworking/Serialization (4.0.1) - AFNetworking/Serialization (4.0.1)
- AFNetworking/UIKit (4.0.1): - AFNetworking/UIKit (4.0.1):
- AFNetworking/NSURLSession - AFNetworking/NSURLSession
- CocoaLumberjack (3.7.4): - CocoaLumberjack (3.9.1):
- CocoaLumberjack/Core (= 3.7.4) - CocoaLumberjack/Core (= 3.9.1)
- CocoaLumberjack/Core (3.7.4) - CocoaLumberjack/Core (3.9.1)
- CocoaLumberjack/Swift (3.7.4): - CocoaLumberjack/Swift (3.9.1):
- CocoaLumberjack/Core - CocoaLumberjack/Core
- FBSnapshotTestCase (2.1.4): - FBSnapshotTestCase (2.1.4):
- FBSnapshotTestCase/SwiftSupport (= 2.1.4) - FBSnapshotTestCase/SwiftSupport (= 2.1.4)
@@ -29,7 +29,6 @@ PODS:
- FURenderKit - FURenderKit
- FUCommonUIComponent (1.0) - FUCommonUIComponent (1.0)
- FURenderKit (0.1.0) - FURenderKit (0.1.0)
- Logboard (2.5.0)
- Masonry (1.1.0) - Masonry (1.1.0)
- MBProgressHUD (1.2.0) - MBProgressHUD (1.2.0)
- Reachability (3.7.7) - Reachability (3.7.7)
@@ -38,9 +37,8 @@ PODS:
- SDWebImage/Core (= 5.21.3) - SDWebImage/Core (= 5.21.3)
- SDWebImage/Core (5.21.3) - SDWebImage/Core (5.21.3)
- SellyCloudSDK (0.1.0): - SellyCloudSDK (0.1.0):
- CocoaLumberjack (~> 3.7.2) - CocoaLumberjack
- CocoaLumberjack/Swift - CocoaLumberjack/Swift
- Logboard (~> 2.5.0)
- Reachability - Reachability
- ReactiveObjC - ReactiveObjC
- SocketRocket - SocketRocket
@@ -67,7 +65,6 @@ SPEC REPOS:
trunk: trunk:
- CocoaLumberjack - CocoaLumberjack
- FBSnapshotTestCase - FBSnapshotTestCase
- Logboard
- Masonry - Masonry
- MBProgressHUD - MBProgressHUD
- Reachability - Reachability
@@ -91,18 +88,17 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
AFNetworking: 5789ed1f9a480117fec1f7bb13011d2c0eca41af AFNetworking: 5789ed1f9a480117fec1f7bb13011d2c0eca41af
CocoaLumberjack: 543c79c114dadc3b1aba95641d8738b06b05b646 CocoaLumberjack: e4ba3b414dfca8c1916c6303d37f63b3a95134c6
FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a
FUBeautyComponent: 7625f5cddc9e023fb184a0971efd2dcbcfa75bd2 FUBeautyComponent: 7625f5cddc9e023fb184a0971efd2dcbcfa75bd2
FUCommonUIComponent: 73e969a7bf0eb1b1a4e6188ce85635688252d512 FUCommonUIComponent: 73e969a7bf0eb1b1a4e6188ce85635688252d512
FURenderKit: 4c7c207c0b71d965ceb17de26f9e2f4bd967c72f FURenderKit: 4c7c207c0b71d965ceb17de26f9e2f4bd967c72f
Logboard: 4674a3d86681539a0ad1fca528d888b90871e268
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406
Reachability: 8bf74b755b2993968c344b465c13e602db2b1044 Reachability: 8bf74b755b2993968c344b465c13e602db2b1044
ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040 ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
SellyCloudSDK: 2642641ff3562001f0852fe85fa284f0704f5a21 SellyCloudSDK: 5171ac4d860d6b15089bdbedabf7d613ce165da7
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30 YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30

View File

@@ -1,6 +1,6 @@
BSD 3-Clause License BSD 3-Clause License
Copyright (c) 2010-2021, Deusty, LLC Copyright (c) 2010-2026, Deusty, LLC
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

View File

@@ -4,26 +4,39 @@
CocoaLumberjack CocoaLumberjack
=============== ===============
![Unit Tests](https://github.com/CocoaLumberjack/CocoaLumberjack/workflows/Unit%20Tests/badge.svg) [![Version](https://img.shields.io/github/release/CocoaLumberjack/CocoaLumberjack.svg?display_name=tag&style=flat)](https://github.com/CocoaLumberjack/CocoaLumberjack/releases/latest)
[![Pod Version](http://img.shields.io/cocoapods/v/CocoaLumberjack.svg?style=flat)](http://cocoadocs.org/docsets/CocoaLumberjack/) [![License](https://img.shields.io/github/license/CocoaLumberjack/CocoaLumberjack.svg?style=flat)](https://opensource.org/licenses/BSD-3-Clause)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FCocoaLumberjack%2FCocoaLumberjack%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/CocoaLumberjack/CocoaLumberjack)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FCocoaLumberjack%2FCocoaLumberjack%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/CocoaLumberjack/CocoaLumberjack)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Pod Platform](http://img.shields.io/cocoapods/p/CocoaLumberjack.svg?style=flat)](http://cocoadocs.org/docsets/CocoaLumberjack/) ![Unit Tests](https://github.com/CocoaLumberjack/CocoaLumberjack/workflows/Unit%20Tests/badge.svg)
[![Pod License](http://img.shields.io/cocoapods/l/CocoaLumberjack.svg?style=flat)](http://opensource.org/licenses/BSD-3-Clause)
[![codecov](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack/branch/master/graph/badge.svg)](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack) [![codecov](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack/branch/master/graph/badge.svg)](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack)
[![codebeat badge](https://codebeat.co/badges/840b714a-c8f3-4936-ada4-363473cd4e6b)](https://codebeat.co/projects/github-com-cocoalumberjack-cocoalumberjack-master)
**CocoaLumberjack** is a fast & simple, yet powerful & flexible logging framework for macOS, iOS, tvOS and watchOS. **CocoaLumberjack** is a fast & simple, yet powerful & flexible logging framework for macOS, iOS, tvOS, watchOS and visionOS.
## How to get started ## How to get started
First, install CocoaLumberjack via [CocoaPods](https://cocoapods.org), [Carthage](https://github.com/Carthage/Carthage), [Swift Package Manager](https://swift.org/package-manager/) or manually. First, install CocoaLumberjack via [Swift Package Manager](https://swift.org/package-manager/), [CocoaPods](https://cocoapods.org), [Carthage](https://github.com/Carthage/Carthage) or manually.
Then use `DDOSLogger` for iOS 10 and later, or `DDTTYLogger` and `DDASLLogger` for earlier versions to begin logging messages. Then use `DDOSLogger` for iOS 10 and later, or `DDTTYLogger` and `DDASLLogger` for earlier versions to begin logging messages.
### Swift Package Manager
As of CocoaLumberjack 3.6.0, you can use the Swift Package Manager as integration method.
If you want to use the Swift Package Manager as integration method, either use Xcode to add the package dependency or add the following dependency to your Package.swift:
```swift
.package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack", from: "3.9.0"),
```
Note that you may need to add both products, `CocoaLumberjack` and `CocoaLumberjackSwift` to your target since SPM sometimes fails to detect that `CocoaLumberjackSwift` depends on `CocoaLumberjack`.
### CocoaPods ### CocoaPods
```ruby ```ruby
platform :ios, '9.0' platform :ios, '11.0'
target 'SampleTarget' do target 'SampleTarget' do
use_frameworks! use_frameworks!
@@ -35,7 +48,7 @@ For more details about how to use Swift with Lumberjack, see [this conversation]
For Objective-C use the following: For Objective-C use the following:
```ruby ```ruby
platform :ios, '9.0' platform :ios, '11.0'
target 'SampleTarget' do target 'SampleTarget' do
pod 'CocoaLumberjack' pod 'CocoaLumberjack'
@@ -53,18 +66,6 @@ Cartfile
github "CocoaLumberjack/CocoaLumberjack" github "CocoaLumberjack/CocoaLumberjack"
``` ```
### Swift Package Manager
As of CocoaLumberjack 3.6.0, you can use the Swift Package Manager as integration method.
If you want to use the Swift Package Manager as integration method, either use Xcode to add the package dependency or add the following dependency to your Package.swift:
```swift
.package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git", from: "3.7.0"),
```
Note that you may need to add both products, `CocoaLumberjack` and `CocoaLumberjackSwift` to your target since SPM sometimes fails to detect that `CocoaLumerjackSwift` depends on `CocoaLumberjack`.
### Install manually ### Install manually
If you want to install CocoaLumberjack manually, read the [manual installation](Documentation/GettingStarted.md#manual-installation) guide for more information. If you want to install CocoaLumberjack manually, read the [manual installation](Documentation/GettingStarted.md#manual-installation) guide for more information.
@@ -126,6 +127,18 @@ You can then use `DDLogHandler` as backend for swift-log, which will forward all
In your own log formatters, you can make use of the `swiftLogInfo` property on `DDLogMessage` to retrieve the details of a message that is logged via swift-log. In your own log formatters, you can make use of the `swiftLogInfo` property on `DDLogMessage` to retrieve the details of a message that is logged via swift-log.
To use swift-log with CocoaLumberjack, take a look the following code snippet to see how to get started.
```swift
import CocoaLumberjack
import CocoaLumberjackSwiftLogBackend
import Logging
// In your application's entry point (e.g. AppDelegate):
DDLog.add(DDOSLogger.sharedInstance) // Configure loggers
LoggingSystem.bootstrapWithCocoaLumberjack() // Use CocoaLumberjack as swift-log backend
```
## More information ## More information
@@ -184,14 +197,15 @@ Configure your logging however you want. Change log levels per file (perfect for
## Requirements ## Requirements
The current version of Lumberjack requires: The current version of Lumberjack requires:
- Xcode 12 or later - Xcode 14.1 or later
- Swift 5.3 or later - Swift 5.5 or later
- iOS 9 or later - macOS 10.13 or later
- macOS 10.10 or later - iOS 11 or later
- watchOS 3 or later - tvOS 11 or later
- tvOS 9 or later - watchOS 4 or later
### Backwards compatibility ### Backwards compatibility
- for iOS/tvOS up to 10, watchOS up to 3, macOS up to 10.12, Xcode up to 13 and Swift up to 5.4, use the 3.7.4 version
- for Xcode 11 and Swift up to 5.2, use the 3.6.2 version - for Xcode 11 and Swift up to 5.2, use the 3.6.2 version
- for Xcode 10 and Swift 4.2, use the 3.5.2 version - for Xcode 10 and Swift 4.2, use the 3.5.2 version
- for iOS 8, use the 3.6.1 version - for iOS 8, use the 3.6.1 version
@@ -257,7 +271,7 @@ _Example_: `DDLogInfo("User: \(myUser)")` will add the `myUser` info to the logs
## Author ## Author
- [Robbie Hanson](https://github.com/robbiehanson) - [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) - Love the project? Wanna buy me a coffee? (or a beer :D) [![donation](https://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)
## Collaborators ## Collaborators
- [Ernesto Rivera](https://github.com/rivera-ernesto) - [Ernesto Rivera](https://github.com/rivera-ernesto)
@@ -276,6 +290,8 @@ _Example_: `DDLogInfo("User: \(myUser)")` will add the `myUser` info to the logs
- CocoaLumberjack is available under the BSD 3 license. See the [LICENSE file](LICENSE). - CocoaLumberjack is available under the BSD 3 license. See the [LICENSE file](LICENSE).
## Extensions ## Extensions
- [Birch-Lumberjack](https://github.com/gruffins/birch-lumberjack) A remote logger for CocoaLumberjack
- [BugfenderSDK-CocoaLumberjack](https://github.com/bugfender/BugfenderSDK-CocoaLumberjack) A Bugfender logger for CocoaLumberjack
- [LogIO-CocoaLumberjack](https://github.com/s4nchez/LogIO-CocoaLumberjack) A log.io logger for CocoaLumberjack - [LogIO-CocoaLumberjack](https://github.com/s4nchez/LogIO-CocoaLumberjack) A log.io logger for CocoaLumberjack
- [XCDLumberjackNSLogger](https://github.com/0xced/XCDLumberjackNSLogger) CocoaLumberjack logger which sends logs to NSLogger - [XCDLumberjackNSLogger](https://github.com/0xced/XCDLumberjackNSLogger) CocoaLumberjack logger which sends logs to NSLogger

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -29,7 +29,7 @@
@implementation CLIColor @implementation CLIColor
+ (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { + (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {
CLIColor *color = [CLIColor new]; __auto_type color = [CLIColor new];
color->_red = red; color->_red = red;
color->_green = green; color->_green = green;
color->_blue = blue; color->_blue = blue;

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -29,8 +29,8 @@
#define DD_LEGACY_MACROS 0 #define DD_LEGACY_MACROS 0
#endif #endif
static BOOL _cancel = YES; static __auto_type _cancel = YES;
static DDLogLevel _captureLevel = DDLogLevelVerbose; static __auto_type _captureLevel = DDLogLevelVerbose;
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations" #pragma clang diagnostic ignored "-Wdeprecated-implementations"
@@ -73,7 +73,7 @@ static DDLogLevel _captureLevel = DDLogLevelVerbose;
asl_set_query(query, kDDASLKeyDDLog, kDDASLDDLogValue, ASL_QUERY_OP_NOT_EQUAL); asl_set_query(query, kDDASLKeyDDLog, kDDASLDDLogValue, ASL_QUERY_OP_NOT_EQUAL);
#if !TARGET_OS_IPHONE || (defined(TARGET_SIMULATOR) && TARGET_SIMULATOR) #if !TARGET_OS_IPHONE || (defined(TARGET_SIMULATOR) && TARGET_SIMULATOR)
int processId = [[NSProcessInfo processInfo] processIdentifier]; __auto_type processId = [[NSProcessInfo processInfo] processIdentifier];
char pid[16]; char pid[16];
snprintf(pid, sizeof(pid), "%d", processId); snprintf(pid, sizeof(pid), "%d", processId);
asl_set_query(query, ASL_KEY_PID, pid, ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_NUMERIC); asl_set_query(query, ASL_KEY_PID, pid, ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_NUMERIC);
@@ -81,14 +81,14 @@ static DDLogLevel _captureLevel = DDLogLevelVerbose;
} }
+ (void)aslMessageReceived:(aslmsg)msg { + (void)aslMessageReceived:(aslmsg)msg {
const char* messageCString = asl_get( msg, ASL_KEY_MSG ); __auto_type messageCString = asl_get(msg, ASL_KEY_MSG);
if ( messageCString == NULL ) if (messageCString == NULL)
return; return;
DDLogFlag flag; DDLogFlag flag;
BOOL async; BOOL async;
const char* levelCString = asl_get(msg, ASL_KEY_LEVEL); __auto_type levelCString = asl_get(msg, ASL_KEY_LEVEL);
switch (levelCString? atoi(levelCString) : 0) { switch (levelCString? atoi(levelCString) : 0) {
// By default all NSLog's with a ASL_LEVEL_WARNING level // By default all NSLog's with a ASL_LEVEL_WARNING level
case ASL_LEVEL_EMERG : case ASL_LEVEL_EMERG :
@@ -109,24 +109,24 @@ static DDLogLevel _captureLevel = DDLogLevelVerbose;
// NSString * sender = [NSString stringWithCString:asl_get(msg, ASL_KEY_SENDER) encoding:NSUTF8StringEncoding]; // NSString * sender = [NSString stringWithCString:asl_get(msg, ASL_KEY_SENDER) encoding:NSUTF8StringEncoding];
NSString *message = @(messageCString); NSString *message = @(messageCString);
const char* secondsCString = asl_get( msg, ASL_KEY_TIME ); __auto_type secondsCString = asl_get(msg, ASL_KEY_TIME);
const char* nanoCString = asl_get( msg, ASL_KEY_TIME_NSEC ); __auto_type nanoCString = asl_get(msg, ASL_KEY_TIME_NSEC);
NSTimeInterval seconds = secondsCString ? strtod(secondsCString, NULL) : [NSDate timeIntervalSinceReferenceDate] - NSTimeIntervalSince1970; __auto_type seconds = secondsCString ? strtod(secondsCString, NULL) : [NSDate timeIntervalSinceReferenceDate] - NSTimeIntervalSince1970;
double nanoSeconds = nanoCString? strtod(nanoCString, NULL) : 0; __auto_type nanoSeconds = nanoCString? strtod(nanoCString, NULL) : 0;
NSTimeInterval totalSeconds = seconds + (nanoSeconds / 1e9); __auto_type totalSeconds = seconds + (nanoSeconds / 1e9);
NSDate *timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds]; __auto_type timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds];
DDLogMessage *logMessage = [[DDLogMessage alloc] initWithMessage:message __auto_type logMessage = [[DDLogMessage alloc] initWithMessage:message
level:_captureLevel level:_captureLevel
flag:flag flag:flag
context:0 context:0
file:@"DDASLLogCapture" file:@"DDASLLogCapture"
function:nil function:nil
line:0 line:0
tag:nil tag:nil
options:0 options:DDLogMessageDontCopyMessage
timestamp:timeStamp]; timestamp:timeStamp];
[DDLog log:async message:logMessage]; [DDLog log:async message:logMessage];
} }
@@ -144,7 +144,7 @@ static DDLogLevel _captureLevel = DDLogLevelVerbose;
.tv_sec = 0 .tv_sec = 0
}; };
gettimeofday(&timeval, NULL); gettimeofday(&timeval, NULL);
unsigned long long startTime = (unsigned long long)timeval.tv_sec; __auto_type startTime = (unsigned long long)timeval.tv_sec;
__block unsigned long long lastSeenID = 0; __block unsigned long long lastSeenID = 0;
/* /*
@@ -163,7 +163,7 @@ static DDLogLevel _captureLevel = DDLogLevelVerbose;
// At least one message has been posted; build a search query. // At least one message has been posted; build a search query.
@autoreleasepool @autoreleasepool
{ {
aslmsg query = asl_new(ASL_TYPE_QUERY); __auto_type query = asl_new(ASL_TYPE_QUERY);
char stringValue[64]; char stringValue[64];
if (lastSeenID > 0) { if (lastSeenID > 0) {
@@ -178,7 +178,7 @@ static DDLogLevel _captureLevel = DDLogLevelVerbose;
// Iterate over new messages. // Iterate over new messages.
aslmsg msg; aslmsg msg;
aslresponse response = asl_search(NULL, query); __auto_type response = asl_search(NULL, query);
while ((msg = asl_next(response))) while ((msg = asl_next(response)))
{ {

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -80,10 +80,10 @@ static DDASLLogger *sharedInstance;
return; return;
} }
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message; __auto_type message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
if (message) { if (message) {
const char *msg = [message UTF8String]; __auto_type msg = [message UTF8String];
size_t aslLogLevel; size_t aslLogLevel;
switch (logMessage->_flag) { switch (logMessage->_flag) {
@@ -100,11 +100,11 @@ static DDASLLogger *sharedInstance;
static char const *const level_strings[] = { "0", "1", "2", "3", "4", "5", "6", "7" }; static char const *const level_strings[] = { "0", "1", "2", "3", "4", "5", "6", "7" };
// NSLog uses the current euid to set the ASL_KEY_READ_UID. // NSLog uses the current euid to set the ASL_KEY_READ_UID.
uid_t const readUID = geteuid(); const __auto_type readUID = geteuid();
char readUIDString[16]; char readUIDString[16];
#ifndef NS_BLOCK_ASSERTIONS #ifndef NS_BLOCK_ASSERTIONS
size_t l = (size_t)snprintf(readUIDString, sizeof(readUIDString), "%d", readUID); __auto_type l = (size_t)snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
#else #else
snprintf(readUIDString, sizeof(readUIDString), "%d", readUID); snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
#endif #endif
@@ -114,7 +114,7 @@ static DDASLLogger *sharedInstance;
NSAssert(aslLogLevel < (sizeof(level_strings) / sizeof(level_strings[0])), NSAssert(aslLogLevel < (sizeof(level_strings) / sizeof(level_strings[0])),
@"Unhandled ASL log level."); @"Unhandled ASL log level.");
aslmsg m = asl_new(ASL_TYPE_MSG); __auto_type m = asl_new(ASL_TYPE_MSG);
if (m != NULL) { if (m != NULL) {
if (asl_set(m, ASL_KEY_LEVEL, level_strings[aslLogLevel]) == 0 && if (asl_set(m, ASL_KEY_LEVEL, level_strings[aslLogLevel]) == 0 &&
asl_set(m, ASL_KEY_MSG, msg) == 0 && asl_set(m, ASL_KEY_MSG, msg) == 0 &&

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -114,21 +114,15 @@
dispatch_source_cancel(_saveTimer); dispatch_source_cancel(_saveTimer);
// Must activate a timer before releasing it (or it will crash) // Must activate a timer before releasing it (or it will crash)
if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { if (_saveTimerSuspended < 0) {
if (_saveTimerSuspended < 0) { dispatch_activate(_saveTimer);
dispatch_activate(_saveTimer); } else if (_saveTimerSuspended > 0) {
} else if (_saveTimerSuspended > 0) { dispatch_resume(_saveTimer);
dispatch_resume(_saveTimer);
}
} else {
if (_saveTimerSuspended != 0) {
dispatch_resume(_saveTimer);
}
} }
#if !OS_OBJECT_USE_OBJC #if !OS_OBJECT_USE_OBJC
dispatch_release(_saveTimer); dispatch_release(_saveTimer);
#endif #endif
_saveTimer = NULL; _saveTimer = NULL;
_saveTimerSuspended = 0; _saveTimerSuspended = 0;
} }
@@ -136,24 +130,17 @@
- (void)updateAndResumeSaveTimer { - (void)updateAndResumeSaveTimer {
if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0)) { if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0)) {
uint64_t interval = (uint64_t)(_saveInterval * (NSTimeInterval) NSEC_PER_SEC); __auto_type interval = (uint64_t)(_saveInterval * (NSTimeInterval) NSEC_PER_SEC);
dispatch_time_t startTime = dispatch_time(_unsavedTime, (int64_t)interval); __auto_type startTime = dispatch_time(_unsavedTime, (int64_t)interval);
dispatch_source_set_timer(_saveTimer, startTime, interval, 1ull * NSEC_PER_SEC); dispatch_source_set_timer(_saveTimer, startTime, interval, 1ull * NSEC_PER_SEC);
if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { if (_saveTimerSuspended < 0) {
if (_saveTimerSuspended < 0) { dispatch_activate(_saveTimer);
dispatch_activate(_saveTimer); _saveTimerSuspended = 0;
_saveTimerSuspended = 0; } else if (_saveTimerSuspended > 0) {
} else if (_saveTimerSuspended > 0) { dispatch_resume(_saveTimer);
dispatch_resume(_saveTimer); _saveTimerSuspended = 0;
_saveTimerSuspended = 0;
}
} else {
if (_saveTimerSuspended != 0) {
dispatch_resume(_saveTimer);
_saveTimerSuspended = 0;
}
} }
} }
} }
@@ -163,8 +150,8 @@
_saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue); _saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue);
dispatch_source_set_event_handler(_saveTimer, ^{ @autoreleasepool { dispatch_source_set_event_handler(_saveTimer, ^{ @autoreleasepool {
[self performSaveAndSuspendSaveTimer]; [self performSaveAndSuspendSaveTimer];
} }); } });
_saveTimerSuspended = -1; _saveTimerSuspended = -1;
} }
@@ -173,16 +160,16 @@
- (void)destroyDeleteTimer { - (void)destroyDeleteTimer {
if (_deleteTimer != NULL) { if (_deleteTimer != NULL) {
dispatch_source_cancel(_deleteTimer); dispatch_source_cancel(_deleteTimer);
#if !OS_OBJECT_USE_OBJC #if !OS_OBJECT_USE_OBJC
dispatch_release(_deleteTimer); dispatch_release(_deleteTimer);
#endif #endif
_deleteTimer = NULL; _deleteTimer = NULL;
} }
} }
- (void)updateDeleteTimer { - (void)updateDeleteTimer {
if ((_deleteTimer != NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) { if ((_deleteTimer != NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) {
int64_t interval = (int64_t)(_deleteInterval * (NSTimeInterval) NSEC_PER_SEC); __auto_type interval = (int64_t)(_deleteInterval * (NSTimeInterval) NSEC_PER_SEC);
dispatch_time_t startTime; dispatch_time_t startTime;
if (_lastDeleteTime > 0) { if (_lastDeleteTime > 0) {
@@ -201,17 +188,14 @@
if (_deleteTimer != NULL) { if (_deleteTimer != NULL) {
dispatch_source_set_event_handler(_deleteTimer, ^{ @autoreleasepool { dispatch_source_set_event_handler(_deleteTimer, ^{ @autoreleasepool {
[self performDelete]; [self performDelete];
} }); } });
[self updateDeleteTimer]; [self updateDeleteTimer];
// We are sure that -updateDeleteTimer did call dispatch_source_set_timer() // We are sure that -updateDeleteTimer did call dispatch_source_set_timer()
// since it has the same guards on _deleteInterval and _maxAge // since it has the same guards on _deleteInterval and _maxAge
if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) dispatch_activate(_deleteTimer);
dispatch_activate(_deleteTimer);
else
dispatch_resume(_deleteTimer);
} }
} }
} }
@@ -231,14 +215,10 @@
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
__block NSUInteger result; __block NSUInteger result;
dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(globalLoggingQueue, ^{
dispatch_sync(self.loggerQueue, ^{ dispatch_sync(self.loggerQueue, ^{
result = self->_saveThreshold; result = self->_saveThreshold;
}); });
@@ -271,10 +251,8 @@
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
@@ -291,14 +269,10 @@
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
__block NSTimeInterval result; __block NSTimeInterval result;
dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(globalLoggingQueue, ^{
dispatch_sync(self.loggerQueue, ^{ dispatch_sync(self.loggerQueue, ^{
result = self->_saveInterval; result = self->_saveInterval;
}); });
@@ -308,7 +282,7 @@
} }
- (void)setSaveInterval:(NSTimeInterval)interval { - (void)setSaveInterval:(NSTimeInterval)interval {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
// C99 recommended floating point comparison macro // C99 recommended floating point comparison macro
// Read: isLessThanOrGreaterThan(floatA, floatB) // Read: isLessThanOrGreaterThan(floatA, floatB)
@@ -362,10 +336,8 @@
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
@@ -382,14 +354,11 @@
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
__block NSTimeInterval result; __block NSTimeInterval result;
dispatch_sync(globalLoggingQueue, ^{ dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(self.loggerQueue, ^{ dispatch_sync(self.loggerQueue, ^{
result = self->_maxAge; result = self->_maxAge;
}); });
@@ -399,14 +368,14 @@
} }
- (void)setMaxAge:(NSTimeInterval)interval { - (void)setMaxAge:(NSTimeInterval)interval {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
// C99 recommended floating point comparison macro // C99 recommended floating point comparison macro
// Read: isLessThanOrGreaterThan(floatA, floatB) // Read: isLessThanOrGreaterThan(floatA, floatB)
if (/* maxAge != interval */ islessgreater(self->_maxAge, interval)) { if (/* maxAge != interval */ islessgreater(self->_maxAge, interval)) {
NSTimeInterval oldMaxAge = self->_maxAge; __auto_type oldMaxAge = self->_maxAge;
NSTimeInterval newMaxAge = interval; __auto_type newMaxAge = interval;
self->_maxAge = interval; self->_maxAge = interval;
@@ -424,7 +393,7 @@
// 4. If the maxAge was decreased, // 4. If the maxAge was decreased,
// then we should do an immediate delete. // then we should do an immediate delete.
BOOL shouldDeleteNow = NO; __auto_type shouldDeleteNow = NO;
if (oldMaxAge > 0.0) { if (oldMaxAge > 0.0) {
if (newMaxAge <= 0.0) { if (newMaxAge <= 0.0) {
@@ -459,10 +428,8 @@
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
@@ -479,14 +446,11 @@
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
__block NSTimeInterval result; __block NSTimeInterval result;
dispatch_sync(globalLoggingQueue, ^{ dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(self.loggerQueue, ^{ dispatch_sync(self.loggerQueue, ^{
result = self->_deleteInterval; result = self->_deleteInterval;
}); });
@@ -496,7 +460,7 @@
} }
- (void)setDeleteInterval:(NSTimeInterval)interval { - (void)setDeleteInterval:(NSTimeInterval)interval {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
// C99 recommended floating point comparison macro // C99 recommended floating point comparison macro
// Read: isLessThanOrGreaterThan(floatA, floatB) // Read: isLessThanOrGreaterThan(floatA, floatB)
@@ -549,10 +513,9 @@
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
dispatch_async(globalLoggingQueue, ^{ dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
@@ -569,14 +532,11 @@
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
__block BOOL result; __block BOOL result;
dispatch_sync(globalLoggingQueue, ^{ dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(self.loggerQueue, ^{ dispatch_sync(self.loggerQueue, ^{
result = self->_deleteOnEverySave; result = self->_deleteOnEverySave;
}); });
@@ -586,7 +546,7 @@
} }
- (void)setDeleteOnEverySave:(BOOL)flag { - (void)setDeleteOnEverySave:(BOOL)flag {
dispatch_block_t block = ^{ __auto_type block = ^{
self->_deleteOnEverySave = flag; self->_deleteOnEverySave = flag;
}; };
@@ -596,10 +556,8 @@
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
@@ -610,7 +568,7 @@
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)savePendingLogEntries { - (void)savePendingLogEntries {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
[self performSaveAndSuspendSaveTimer]; [self performSaveAndSuspendSaveTimer];
} }
@@ -624,7 +582,7 @@
} }
- (void)deleteOldLogEntries { - (void)deleteOldLogEntries {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
[self performDelete]; [self performDelete];
} }
@@ -643,24 +601,20 @@
- (void)didAddLogger { - (void)didAddLogger {
// If you override me be sure to invoke [super didAddLogger]; // If you override me be sure to invoke [super didAddLogger];
[self createSuspendedSaveTimer]; [self createSuspendedSaveTimer];
[self createAndStartDeleteTimer]; [self createAndStartDeleteTimer];
} }
- (void)willRemoveLogger { - (void)willRemoveLogger {
// If you override me be sure to invoke [super willRemoveLogger]; // If you override me be sure to invoke [super willRemoveLogger];
[self performSaveAndSuspendSaveTimer]; [self performSaveAndSuspendSaveTimer];
[self destroySaveTimer]; [self destroySaveTimer];
[self destroyDeleteTimer]; [self destroyDeleteTimer];
} }
- (void)logMessage:(DDLogMessage *)logMessage { - (void)logMessage:(DDLogMessage *)logMessage {
if ([self db_log:logMessage]) { if ([self db_log:logMessage]) {
BOOL firstUnsavedEntry = (++_unsavedCount == 1); __auto_type firstUnsavedEntry = (++_unsavedCount == 1);
if ((_unsavedCount >= _saveThreshold) && (_saveThreshold > 0)) { if ((_unsavedCount >= _saveThreshold) && (_saveThreshold > 0)) {
[self performSaveAndSuspendSaveTimer]; [self performSaveAndSuspendSaveTimer];
@@ -676,7 +630,6 @@
// //
// It is called automatically when the application quits, // It is called automatically when the application quits,
// or if the developer invokes DDLog's flushLog method prior to crashing or something. // or if the developer invokes DDLog's flushLog method prior to crashing or something.
[self performSaveAndSuspendSaveTimer]; [self performSaveAndSuspendSaveTimer];
} }

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -48,6 +48,11 @@
#define NSLogDebug(frmt, ...) do{ if(DD_DEBUG) NSLog((frmt), ##__VA_ARGS__); } while(0) #define NSLogDebug(frmt, ...) do{ if(DD_DEBUG) NSLog((frmt), ##__VA_ARGS__); } while(0)
#define DDLogAssertOnGlobalLoggingQueue() \
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), @"This method must be called on the logging thread/queue!")
#define DDLogAssertNotOnGlobalLoggingQueue() \
NSAssert(!dispatch_get_specific(GlobalLoggingQueueIdentityKey), @"This method must not be called on the logging thread/queue!")
// The "global logging queue" refers to [DDLog loggingQueue]. // The "global logging queue" refers to [DDLog loggingQueue].
// It is the queue that all log statements go through. // It is the queue that all log statements go through.
// //
@@ -107,7 +112,7 @@ static NSUInteger _numProcessors;
* @return The singleton `DDLog`. * @return The singleton `DDLog`.
*/ */
+ (instancetype)sharedInstance { + (instancetype)sharedInstance {
static id sharedInstance = nil; static DDLog *sharedInstance = nil;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
@@ -159,7 +164,7 @@ static NSUInteger _numProcessors;
self._loggers = [[NSMutableArray alloc] initWithCapacity:4]; self._loggers = [[NSMutableArray alloc] initWithCapacity:4];
#if TARGET_OS_IOS #if TARGET_OS_IOS
NSString *notificationName = UIApplicationWillTerminateNotification; __auto_type notificationName = UIApplicationWillTerminateNotification;
#else #else
NSString *notificationName = nil; NSString *notificationName = nil;
@@ -317,7 +322,7 @@ static NSUInteger _numProcessors;
// Now assume we have another separate thread that attempts to issue log message G. // Now assume we have another separate thread that attempts to issue log message G.
// It should block until log messages A and B have been unqueued. // It should block until log messages A and B have been unqueued.
dispatch_block_t logBlock = ^{ __auto_type logBlock = ^{
// We're now sure we won't overflow the queue. // We're now sure we won't overflow the queue.
// It is time to queue our log message. // It is time to queue our log message.
@autoreleasepool { @autoreleasepool {
@@ -349,21 +354,16 @@ static NSUInteger _numProcessors;
if (format) { if (format) {
va_start(args, format); va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
va_start(args, format);
[self log:asynchronous [self log:asynchronous
message:message
level:level level:level
flag:flag flag:flag
context:context context:context
file:file file:file
function:function function:function
line:line line:line
tag:tag]; tag:tag
format:format
args:args];
va_end(args); va_end(args);
} }
@@ -383,21 +383,16 @@ static NSUInteger _numProcessors;
if (format) { if (format) {
va_start(args, format); va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
va_start(args, format);
[self log:asynchronous [self log:asynchronous
message:message
level:level level:level
flag:flag flag:flag
context:context context:context
file:file file:file
function:function function:function
line:line line:line
tag:tag]; tag:tag
format:format
args:args];
va_end(args); va_end(args);
} }
@@ -427,54 +422,26 @@ static NSUInteger _numProcessors;
format:(NSString *)format format:(NSString *)format
args:(va_list)args { args:(va_list)args {
if (format) { if (format) {
NSString *message = [[NSString alloc] initWithFormat:format arguments:args]; // Null checks are handled by -initWithMessage:
[self log:asynchronous #pragma clang diagnostic push
message:message #pragma clang diagnostic ignored "-Wnullable-to-nonnull-conversion"
level:level __auto_type logMessage = [[DDLogMessage alloc] initWithFormat:format
flag:flag args:args
context:context level:level
file:file flag:flag
function:function context:context
line:line file:@(file)
tag:tag]; function:@(function)
line:line
tag:tag
options:(DDLogMessageOptions)0
timestamp:nil];
#pragma clang diagnostic pop
[self queueLogMessage:logMessage asynchronously: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)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
context:context
file:[NSString stringWithFormat:@"%s", file]
function:[NSString stringWithFormat:@"%s", function]
line:line
tag:tag
options:(DDLogMessageOptions)0
timestamp:nil];
[self queueLogMessage:logMessage asynchronously:asynchronous];
}
+ (void)log:(BOOL)asynchronous message:(DDLogMessage *)logMessage { + (void)log:(BOOL)asynchronous message:(DDLogMessage *)logMessage {
[self.sharedInstance log:asynchronous message:logMessage]; [self.sharedInstance log:asynchronous message:logMessage];
} }
@@ -488,12 +455,12 @@ static NSUInteger _numProcessors;
} }
- (void)flushLog { - (void)flushLog {
NSAssert(!dispatch_get_specific(GlobalLoggingQueueIdentityKey), DDLogAssertNotOnGlobalLoggingQueue();
@"This method shouldn't be run on the logging thread/queue that make flush fast enough"); dispatch_sync(_loggingQueue, ^{
@autoreleasepool {
dispatch_sync(_loggingQueue, ^{ @autoreleasepool { [self lt_flush];
[self lt_flush]; }
} }); });
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -501,69 +468,65 @@ static NSUInteger _numProcessors;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ (BOOL)isRegisteredClass:(Class)class { + (BOOL)isRegisteredClass:(Class)class {
SEL getterSel = @selector(ddLogLevel); __auto_type getterSel = @selector(ddLogLevel);
SEL setterSel = @selector(ddSetLogLevel:); __auto_type setterSel = @selector(ddSetLogLevel:);
#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
// Issue #6 (GoogleCode) - Crashes on iOS 4.2.1 and iPhone 4 // Issue #6 (GoogleCode) - Crashes on iOS 4.2.1 and iPhone 4
//
// Crash caused by class_getClassMethod(2). // Crash caused by class_getClassMethod(2).
//
// "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until // "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until
// users had VoiceOver enabled [...]. I was able to work around it by searching the // users had VoiceOver enabled [...]. I was able to work around it by searching the
// result of class_copyMethodList() instead of calling class_getClassMethod()" // result of class_copyMethodList() instead of calling class_getClassMethod()"
//
// Issue #24 (GitHub) - Crashing in in ARC+Simulator
// The method +[DDLog isRegisteredClass] will crash a project when using it with ARC + Simulator.
// For running in the Simulator, it needs to execute the non-iOS code. Unless we're running on iOS 17+.
BOOL result = NO; #if TARGET_OS_IPHONE
#if TARGET_OS_SIMULATOR
if (@available(iOS 17, tvOS 17, *)) {
#endif
__auto_type result = NO;
unsigned int methodCount, i;
__auto_type methodList = class_copyMethodList(object_getClass(class), &methodCount);
unsigned int methodCount, i; if (methodList != NULL) {
Method *methodList = class_copyMethodList(object_getClass(class), &methodCount); __auto_type getterFound = NO;
__auto_type setterFound = NO;
if (methodList != NULL) { for (i = 0; i < methodCount; ++i) {
BOOL getterFound = NO; __auto_type currentSel = method_getName(methodList[i]);
BOOL setterFound = NO;
for (i = 0; i < methodCount; ++i) { if (currentSel == getterSel) {
SEL currentSel = method_getName(methodList[i]); getterFound = YES;
} else if (currentSel == setterSel) {
setterFound = YES;
}
if (currentSel == getterSel) { if (getterFound && setterFound) {
getterFound = YES; result = YES;
} else if (currentSel == setterSel) { break;
setterFound = YES; }
} }
if (getterFound && setterFound) { free(methodList);
result = YES;
break;
}
} }
free(methodList); return result;
#if TARGET_OS_SIMULATOR
} else {
#endif /* TARGET_OS_SIMULATOR */
#endif /* TARGET_OS_IPHONE */
#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
__auto_type getter = class_getClassMethod(class, getterSel);
__auto_type setter = class_getClassMethod(class, setterSel);
return (getter != NULL) && (setter != NULL);
#endif /* !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR */
#if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR
} }
#endif /* TARGET_OS_IPHONE && TARGET_OS_SIMULATOR */
return result;
#else /* if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */
// Issue #24 (GitHub) - Crashing in in ARC+Simulator
//
// The method +[DDLog isRegisteredClass] will crash a project when using it with ARC + Simulator.
// For running in the Simulator, it needs to execute the non-iOS code.
Method getter = class_getClassMethod(class, getterSel);
Method setter = class_getClassMethod(class, setterSel);
if ((getter != NULL) && (setter != NULL)) {
return YES;
}
return NO;
#endif /* if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */
} }
+ (NSArray *)registeredClasses { + (NSArray *)registeredClasses {
// We're going to get the list of all registered classes. // We're going to get the list of all registered classes.
// The Objective-C runtime library automatically registers all the classes defined in your source code. // The Objective-C runtime library automatically registers all the classes defined in your source code.
// //
@@ -579,23 +542,19 @@ static NSUInteger _numProcessors;
Class *classes = NULL; Class *classes = NULL;
while (numClasses == 0) { while (numClasses == 0) {
numClasses = (NSUInteger)MAX(objc_getClassList(NULL, 0), 0); numClasses = (NSUInteger)MAX(objc_getClassList(NULL, 0), 0);
// numClasses now tells us how many classes we have (but it might change) // numClasses now tells us how many classes we have (but it might change)
// So we can allocate our buffer, and get pointers to all the class definitions. // So we can allocate our buffer, and get pointers to all the class definitions.
__auto_type bufferSize = numClasses;
NSUInteger bufferSize = numClasses;
classes = numClasses ? (Class *)calloc(bufferSize, sizeof(Class)) : NULL; classes = numClasses ? (Class *)calloc(bufferSize, sizeof(Class)) : NULL;
if (classes == NULL) { if (classes == NULL) {
return @[]; //no memory or classes? return @[]; // no memory or classes?
} }
numClasses = (NSUInteger)MAX(objc_getClassList(classes, (int)bufferSize),0); numClasses = (NSUInteger)MAX(objc_getClassList(classes, (int)bufferSize),0);
if (numClasses > bufferSize || numClasses == 0) { if (numClasses > bufferSize || numClasses == 0) {
//apparently more classes added between calls (or a problem); try again // apparently more classes added between calls (or a problem); try again
free(classes); free(classes);
classes = NULL; classes = NULL;
numClasses = 0; numClasses = 0;
@@ -603,10 +562,9 @@ static NSUInteger _numProcessors;
} }
// We can now loop through the classes, and test each one to see if it is a DDLogging class. // We can now loop through the classes, and test each one to see if it is a DDLogging class.
__auto_type result = [NSMutableArray arrayWithCapacity:numClasses];
NSMutableArray *result = [NSMutableArray arrayWithCapacity:numClasses];
for (NSUInteger i = 0; i < numClasses; i++) { for (NSUInteger i = 0; i < numClasses; i++) {
// Cannot use `__auto_type` here, since this will lead to crashes when deallocating!
Class class = classes[i]; Class class = classes[i];
if ([self isRegisteredClass:class]) { if ([self isRegisteredClass:class]) {
@@ -620,8 +578,8 @@ static NSUInteger _numProcessors;
} }
+ (NSArray *)registeredClassNames { + (NSArray *)registeredClassNames {
NSArray *registeredClasses = [self registeredClasses]; __auto_type registeredClasses = [self registeredClasses];
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[registeredClasses count]]; __auto_type result = [NSMutableArray arrayWithCapacity:[registeredClasses count]];
for (Class class in registeredClasses) { for (Class class in registeredClasses) {
[result addObject:NSStringFromClass(class)]; [result addObject:NSStringFromClass(class)];
@@ -637,9 +595,9 @@ static NSUInteger _numProcessors;
} }
+ (DDLogLevel)levelForClassWithName:(NSString *)aClassName { + (DDLogLevel)levelForClassWithName:(NSString *)aClassName {
Class aClass = NSClassFromString(aClassName); Class clazz = NSClassFromString(aClassName);
if (clazz == nil) return (DDLogLevel)-1;
return [self levelForClass:aClass]; return [self levelForClass:clazz];
} }
+ (void)setLevel:(DDLogLevel)level forClass:(Class)aClass { + (void)setLevel:(DDLogLevel)level forClass:(Class)aClass {
@@ -649,8 +607,9 @@ static NSUInteger _numProcessors;
} }
+ (void)setLevel:(DDLogLevel)level forClassWithName:(NSString *)aClassName { + (void)setLevel:(DDLogLevel)level forClassWithName:(NSString *)aClassName {
Class aClass = NSClassFromString(aClassName); Class clazz = NSClassFromString(aClassName);
[self setLevel:level forClass:aClass]; if (clazz == nil) return;
[self setLevel:level forClass:clazz];
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -662,15 +621,13 @@ static NSUInteger _numProcessors;
// Need to create loggerQueue if loggerNode doesn't provide one. // Need to create loggerQueue if loggerNode doesn't provide one.
for (DDLoggerNode *node in self._loggers) { for (DDLoggerNode *node in self._loggers) {
if (node->_logger == logger if (node->_logger == logger && node->_level == level) {
&& node->_level == level) {
// Exactly same logger already added, exit // Exactly same logger already added, exit
return; return;
} }
} }
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), DDLogAssertOnGlobalLoggingQueue();
@"This method should only be run on the logging thread/queue");
dispatch_queue_t loggerQueue = NULL; dispatch_queue_t loggerQueue = NULL;
if ([logger respondsToSelector:@selector(loggerQueue)]) { if ([logger respondsToSelector:@selector(loggerQueue)]) {
@@ -690,7 +647,7 @@ static NSUInteger _numProcessors;
loggerQueue = dispatch_queue_create(loggerQueueName, NULL); loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
} }
DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue level:level]; __auto_type loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue level:level];
[self._loggers addObject:loggerNode]; [self._loggers addObject:loggerNode];
if ([logger respondsToSelector:@selector(didAddLoggerInQueue:)]) { if ([logger respondsToSelector:@selector(didAddLoggerInQueue:)]) {
@@ -707,8 +664,7 @@ static NSUInteger _numProcessors;
- (void)lt_removeLogger:(id <DDLogger>)logger { - (void)lt_removeLogger:(id <DDLogger>)logger {
// Find associated loggerNode in list of added loggers // Find associated loggerNode in list of added loggers
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), DDLogAssertOnGlobalLoggingQueue();
@"This method should only be run on the logging thread/queue");
DDLoggerNode *loggerNode = nil; DDLoggerNode *loggerNode = nil;
@@ -736,8 +692,7 @@ static NSUInteger _numProcessors;
} }
- (void)lt_removeAllLoggers { - (void)lt_removeAllLoggers {
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), DDLogAssertOnGlobalLoggingQueue();
@"This method should only be run on the logging thread/queue");
// Notify all loggers // Notify all loggers
for (DDLoggerNode *loggerNode in self._loggers) { for (DDLoggerNode *loggerNode in self._loggers) {
@@ -749,17 +704,16 @@ static NSUInteger _numProcessors;
} }
// Remove all loggers from array // Remove all loggers from array
[self._loggers removeAllObjects]; [self._loggers removeAllObjects];
} }
- (NSArray *)lt_allLoggers { - (NSArray *)lt_allLoggers {
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), DDLogAssertOnGlobalLoggingQueue();
@"This method should only be run on the logging thread/queue");
NSMutableArray *theLoggers = [NSMutableArray new]; __auto_type loggerNodes = self._loggers;
__auto_type theLoggers = [NSMutableArray arrayWithCapacity:loggerNodes.count];
for (DDLoggerNode *loggerNode in self._loggers) { for (DDLoggerNode *loggerNode in loggerNodes) {
[theLoggers addObject:loggerNode->_logger]; [theLoggers addObject:loggerNode->_logger];
} }
@@ -767,12 +721,13 @@ static NSUInteger _numProcessors;
} }
- (NSArray *)lt_allLoggersWithLevel { - (NSArray *)lt_allLoggersWithLevel {
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), DDLogAssertOnGlobalLoggingQueue();
@"This method should only be run on the logging thread/queue");
NSMutableArray *theLoggersWithLevel = [NSMutableArray new];
for (DDLoggerNode *loggerNode in self._loggers) { __auto_type loggerNodes = self._loggers;
__auto_type theLoggersWithLevel = [NSMutableArray arrayWithCapacity:loggerNodes.count];
for (DDLoggerNode *loggerNode in loggerNodes) {
[theLoggersWithLevel addObject:[DDLoggerInformation informationWithLogger:loggerNode->_logger [theLoggersWithLevel addObject:[DDLoggerInformation informationWithLogger:loggerNode->_logger
andLevel:loggerNode->_level]]; andLevel:loggerNode->_level]];
} }
@@ -781,10 +736,9 @@ static NSUInteger _numProcessors;
} }
- (void)lt_log:(DDLogMessage *)logMessage { - (void)lt_log:(DDLogMessage *)logMessage {
// Execute the given log message on each of our loggers. DDLogAssertOnGlobalLoggingQueue();
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), // Execute the given log message on each of our loggers.
@"This method should only be run on the logging thread/queue");
if (_numProcessors > 1) { if (_numProcessors > 1) {
// Execute each logger concurrently, each within its own queue. // Execute each logger concurrently, each within its own queue.
@@ -797,7 +751,7 @@ static NSUInteger _numProcessors;
for (DDLoggerNode *loggerNode in self._loggers) { for (DDLoggerNode *loggerNode in self._loggers) {
// skip the loggers that shouldn't write this message based on the log level // skip the loggers that shouldn't write this message based on the log level
if (!(logMessage->_flag & loggerNode->_level)) { if (!(logMessage->_flag & (DDLogFlag)(loggerNode->_level))) {
continue; continue;
} }
@@ -813,7 +767,7 @@ static NSUInteger _numProcessors;
for (DDLoggerNode *loggerNode in self._loggers) { for (DDLoggerNode *loggerNode in self._loggers) {
// skip the loggers that shouldn't write this message based on the log level // skip the loggers that shouldn't write this message based on the log level
if (!(logMessage->_flag & loggerNode->_level)) { if (!(logMessage->_flag & (DDLogFlag)(loggerNode->_level))) {
continue; continue;
} }
@@ -846,8 +800,7 @@ static NSUInteger _numProcessors;
// Now we need to propagate the flush request to any loggers that implement the flush method. // Now we need to propagate the flush request to any loggers that implement the flush method.
// This is designed for loggers that buffer IO. // This is designed for loggers that buffer IO.
NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), DDLogAssertOnGlobalLoggingQueue();
@"This method should only be run on the logging thread/queue");
for (DDLoggerNode *loggerNode in self._loggers) { for (DDLoggerNode *loggerNode in self._loggers) {
if ([loggerNode->_logger respondsToSelector:@selector(flush)]) { if ([loggerNode->_logger respondsToSelector:@selector(flush)]) {
@@ -872,8 +825,7 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
char *lastSlash = NULL; char *lastSlash = NULL;
char *lastDot = NULL; char *lastDot = NULL;
char *p = (char *)filePath; __auto_type p = (char *)filePath;
while (*p != '\0') { while (*p != '\0') {
if (*p == '/') { if (*p == '/') {
lastSlash = p; lastSlash = p;
@@ -939,9 +891,9 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
if (loggerQueue) { if (loggerQueue) {
_loggerQueue = loggerQueue; _loggerQueue = loggerQueue;
#if !OS_OBJECT_USE_OBJC #if !OS_OBJECT_USE_OBJC
dispatch_retain(loggerQueue); dispatch_retain(loggerQueue);
#endif #endif
} }
_level = level; _level = level;
@@ -954,11 +906,11 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
} }
- (void)dealloc { - (void)dealloc {
#if !OS_OBJECT_USE_OBJC #if !OS_OBJECT_USE_OBJC
if (_loggerQueue) { if (_loggerQueue) {
dispatch_release(_loggerQueue); dispatch_release(_loggerQueue);
} }
#endif #endif
} }
@end @end
@@ -974,27 +926,33 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
return self; return self;
} }
- (instancetype)initWithMessage:(NSString *)message - (instancetype)initWithFormat:(NSString *)messageFormat
level:(DDLogLevel)level formatted:(NSString *)message
flag:(DDLogFlag)flag level:(DDLogLevel)level
context:(NSInteger)context flag:(DDLogFlag)flag
file:(NSString *)file context:(NSInteger)context
function:(NSString *)function file:(NSString *)file
line:(NSUInteger)line function:(NSString *)function
tag:(id)tag line:(NSUInteger)line
options:(DDLogMessageOptions)options tag:(id)tag
timestamp:(NSDate *)timestamp { options:(DDLogMessageOptions)options
if ((self = [super init])) { timestamp:(NSDate *)timestamp {
BOOL copyMessage = (options & DDLogMessageDontCopyMessage) == 0; NSParameterAssert(messageFormat);
_message = copyMessage ? [message copy] : message; NSParameterAssert(message);
_level = level; NSParameterAssert(file);
_flag = flag;
_context = context;
BOOL copyFile = (options & DDLogMessageCopyFile) != 0; if ((self = [super init])) {
__auto_type copyMessage = (options & DDLogMessageDontCopyMessage) == 0;
_messageFormat = copyMessage ? [messageFormat copy] : messageFormat;
_message = copyMessage ? [message copy] : message;
_level = level;
_flag = flag;
_context = context;
__auto_type copyFile = (options & DDLogMessageCopyFile) != 0;
_file = copyFile ? [file copy] : file; _file = copyFile ? [file copy] : file;
BOOL copyFunction = (options & DDLogMessageCopyFunction) != 0; __auto_type copyFunction = (options & DDLogMessageCopyFunction) != 0;
_function = copyFunction ? [function copy] : function; _function = copyFunction ? [function copy] : function;
_line = line; _line = line;
@@ -1006,48 +964,111 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
_options = options; _options = options;
_timestamp = timestamp ?: [NSDate new]; _timestamp = timestamp ?: [NSDate date];
__uint64_t tid; __uint64_t tid;
if (pthread_threadid_np(NULL, &tid) == 0) { if (pthread_threadid_np(NULL, &tid) == 0) {
_threadID = [[NSString alloc] initWithFormat:@"%llu", tid]; _threadID = [[NSString alloc] initWithFormat:@"%llu", tid];
} else { } else {
_threadID = @"missing threadId"; _threadID = @"N/A";
} }
_threadName = NSThread.currentThread.name; _threadName = NSThread.currentThread.name;
// Get the file name without extension // Get the file name without extension
_fileName = [_file lastPathComponent]; _fileName = [_file lastPathComponent];
NSUInteger dotLocation = [_fileName rangeOfString:@"." options:NSBackwardsSearch].location; __auto_type dotLocation = [_fileName rangeOfString:@"." options:NSBackwardsSearch].location;
if (dotLocation != NSNotFound) if (dotLocation != NSNotFound) {
{
_fileName = [_fileName substringToIndex:dotLocation]; _fileName = [_fileName substringToIndex:dotLocation];
} }
// Try to get the current queue's label // Try to get the current queue's label
_queueLabel = [[NSString alloc] initWithFormat:@"%s", dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)]; _queueLabel = @(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL));
_qos = (NSUInteger) qos_class_self(); _qos = (NSUInteger) qos_class_self();
} }
return self; return self;
} }
- (instancetype)initWithFormat:(NSString *)messageFormat
args:(va_list)messageArgs
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(NSString *)file
function:(NSString *)function
line:(NSUInteger)line
tag:(id)tag
options:(DDLogMessageOptions)options
timestamp:(NSDate *)timestamp {
__auto_type copyMessage = (options & DDLogMessageDontCopyMessage) == 0;
NSString *format = copyMessage ? [messageFormat copy] : messageFormat;
self = [self initWithFormat:format
formatted:[[NSString alloc] initWithFormat:format arguments:messageArgs]
level:level
flag:flag
context:context
file:file
function:function
line:line
tag:tag
options:options | DDLogMessageDontCopyMessage // we already did the copying if needed.
timestamp:timestamp];
return self;
}
- (instancetype)initWithMessage:(NSString *)message
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(NSString *)file
function:(NSString *)function
line:(NSUInteger)line
tag:(id)tag
options:(DDLogMessageOptions)options
timestamp:(NSDate *)timestamp {
self = [self initWithFormat:message
formatted:message
level:level
flag:flag
context:context
file:file
function:function
line:line
tag:tag
options:options
timestamp:timestamp];
return self;
}
NS_INLINE BOOL _nullable_strings_equal(NSString* _Nullable lhs, NSString* _Nullable rhs)
{
if (lhs == nil) {
if (rhs == nil) {
return YES;
}
} else if (rhs != nil && [lhs isEqualToString:(NSString* _Nonnull)rhs]) {
return YES;
}
return NO;
}
- (BOOL)isEqual:(id)other { - (BOOL)isEqual:(id)other {
// Subclasses of NSObject should not call [super isEqual:] here.
// See https://stackoverflow.com/questions/36593038/confused-about-the-default-isequal-and-hash-implements
if (other == self) { if (other == self) {
return YES; return YES;
} else if (![super isEqual:other] || ![other isKindOfClass:[self class]]) { } else if (!other || ![other isKindOfClass:[DDLogMessage class]]) {
return NO; return NO;
} else { } else {
__auto_type otherMsg = (DDLogMessage *)other; __auto_type otherMsg = (DDLogMessage *)other;
return [otherMsg->_message isEqualToString:_message] return [otherMsg->_message isEqualToString:_message]
&& [otherMsg->_messageFormat isEqualToString:_messageFormat]
&& otherMsg->_level == _level && otherMsg->_level == _level
&& otherMsg->_flag == _flag && otherMsg->_flag == _flag
&& otherMsg->_context == _context && otherMsg->_context == _context
&& [otherMsg->_file isEqualToString:_file] && [otherMsg->_file isEqualToString:_file]
&& [otherMsg->_fileName isEqualToString:_fileName] && _nullable_strings_equal(otherMsg->_function, _function)
&& [otherMsg->_function isEqualToString:_function]
&& otherMsg->_line == _line && otherMsg->_line == _line
&& (([otherMsg->_representedObject respondsToSelector:@selector(isEqual:)] && [otherMsg->_representedObject isEqual:_representedObject]) || otherMsg->_representedObject == _representedObject) && (([otherMsg->_representedObject respondsToSelector:@selector(isEqual:)] && [otherMsg->_representedObject isEqual:_representedObject]) || otherMsg->_representedObject == _representedObject)
&& otherMsg->_options == _options
&& [otherMsg->_timestamp isEqualToDate:_timestamp] && [otherMsg->_timestamp isEqualToDate:_timestamp]
&& [otherMsg->_threadID isEqualToString:_threadID] // If the thread ID is the same, the name will likely be the same as well. && [otherMsg->_threadID isEqualToString:_threadID] // If the thread ID is the same, the name will likely be the same as well.
&& [otherMsg->_queueLabel isEqualToString:_queueLabel] && [otherMsg->_queueLabel isEqualToString:_queueLabel]
@@ -1056,17 +1077,17 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
} }
- (NSUInteger)hash { - (NSUInteger)hash {
return [super hash] // Subclasses of NSObject should not call [super hash] here.
^ _message.hash // See https://stackoverflow.com/questions/36593038/confused-about-the-default-isequal-and-hash-implements
return _message.hash
^ _messageFormat.hash
^ _level ^ _level
^ _flag ^ _flag
^ _context ^ _context
^ _file.hash ^ _file.hash
^ _fileName.hash
^ _function.hash ^ _function.hash
^ _line ^ _line
^ ([_representedObject respondsToSelector:@selector(hash)] ? [_representedObject hash] : 0) ^ ([_representedObject respondsToSelector:@selector(hash)] ? [_representedObject hash] : (NSUInteger)_representedObject)
^ _options
^ _timestamp.hash ^ _timestamp.hash
^ _threadID.hash ^ _threadID.hash
^ _queueLabel.hash ^ _queueLabel.hash
@@ -1076,6 +1097,7 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
- (id)copyWithZone:(NSZone * __attribute__((unused)))zone { - (id)copyWithZone:(NSZone * __attribute__((unused)))zone {
DDLogMessage *newMessage = [DDLogMessage new]; DDLogMessage *newMessage = [DDLogMessage new];
newMessage->_messageFormat = _messageFormat;
newMessage->_message = _message; newMessage->_message = _message;
newMessage->_level = _level; newMessage->_level = _level;
newMessage->_flag = _flag; newMessage->_flag = _flag;
@@ -1139,8 +1161,8 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
// //
// This is used primarily for thread-safety assertions (via the isOnInternalLoggerQueue method below). // This is used primarily for thread-safety assertions (via the isOnInternalLoggerQueue method below).
void *key = (__bridge void *)self; __auto_type key = (__bridge void *)self;
void *nonNullValue = (__bridge void *)self; __auto_type nonNullValue = (__bridge void *)self;
dispatch_queue_set_specific(_loggerQueue, key, nonNullValue, NULL); dispatch_queue_set_specific(_loggerQueue, key, nonNullValue, NULL);
} }
@@ -1149,13 +1171,11 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
} }
- (void)dealloc { - (void)dealloc {
#if !OS_OBJECT_USE_OBJC #if !OS_OBJECT_USE_OBJC
if (_loggerQueue) { if (_loggerQueue) {
dispatch_release(_loggerQueue); dispatch_release(_loggerQueue);
} }
#endif
#endif
} }
- (void)logMessage:(DDLogMessage * __attribute__((unused)))logMessage { - (void)logMessage:(DDLogMessage * __attribute__((unused)))logMessage {
@@ -1212,14 +1232,10 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
__block id <DDLogFormatter> result; __block id <DDLogFormatter> result;
dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(globalLoggingQueue, ^{
dispatch_sync(self->_loggerQueue, ^{ dispatch_sync(self->_loggerQueue, ^{
result = self->_logFormatter; result = self->_logFormatter;
}); });
@@ -1231,10 +1247,9 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
- (void)setLogFormatter:(id <DDLogFormatter>)logFormatter { - (void)setLogFormatter:(id <DDLogFormatter>)logFormatter {
// The design of this method is documented extensively in the logFormatter message (above in code). // The design of this method is documented extensively in the logFormatter message (above in code).
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
if (self->_logFormatter != logFormatter) { if (self->_logFormatter != logFormatter) {
if ([self->_logFormatter respondsToSelector:@selector(willRemoveFromLogger:)]) { if ([self->_logFormatter respondsToSelector:@selector(willRemoveFromLogger:)]) {
@@ -1270,9 +1285,7 @@ NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BO
} }
- (BOOL)isOnInternalLoggerQueue { - (BOOL)isOnInternalLoggerQueue {
void *key = (__bridge void *)self; return dispatch_get_specific((__bridge void *)self) != NULL;
return (dispatch_get_specific(key) != NULL);
} }
@end @end

View File

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

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -13,18 +13,51 @@
// to endorse or promote products derived from this software without specific // to endorse or promote products derived from this software without specific
// prior written permission of Deusty, LLC. // prior written permission of Deusty, LLC.
#import <TargetConditionals.h>
#import <os/log.h> #import <os/log.h>
#import <CocoaLumberjack/DDOSLogger.h> #import <CocoaLumberjack/DDOSLogger.h>
@interface DDOSLogger () { @implementation DDOSLogLevelMapperDefault
NSString *_subsystem;
NSString *_category; - (instancetype)init {
self = [super init];
return self;
} }
@property (copy, nonatomic, readonly, nullable) NSString *subsystem; - (os_log_type_t)osLogTypeForLogFlag:(DDLogFlag)logFlag {
@property (copy, nonatomic, readonly, nullable) NSString *category; switch (logFlag) {
@property (strong, nonatomic, readwrite, nonnull) os_log_t logger; case DDLogFlagError:
case DDLogFlagWarning:
return OS_LOG_TYPE_ERROR;
case DDLogFlagInfo:
return OS_LOG_TYPE_INFO;
case DDLogFlagDebug:
case DDLogFlagVerbose:
return OS_LOG_TYPE_DEBUG;
default:
return OS_LOG_TYPE_DEFAULT;
}
}
@end
#if TARGET_OS_SIMULATOR
@implementation DDOSLogLevelMapperSimulatorConsoleAppWorkaround
- (os_log_type_t)osLogTypeForLogFlag:(DDLogFlag)logFlag {
__auto_type defaultMapping = [super osLogTypeForLogFlag:logFlag];
return (defaultMapping == OS_LOG_TYPE_DEBUG) ? OS_LOG_TYPE_DEFAULT : defaultMapping;
}
@end
#endif
@interface DDOSLogger ()
@property (nonatomic, copy, readonly, nullable) NSString *subsystem;
@property (nonatomic, copy, readonly, nullable) NSString *category;
@property (nonatomic, strong, readonly, nonnull) os_log_t logger;
@end @end
@@ -32,29 +65,14 @@
@synthesize subsystem = _subsystem; @synthesize subsystem = _subsystem;
@synthesize category = _category; @synthesize category = _category;
@synthesize logLevelMapper = _logLevelMapper;
@synthesize logger = _logger;
#pragma mark - Initialization #pragma mark - Shared Instance
/**
* Assertion
* Swift: (String, String)?
*/
- (instancetype)initWithSubsystem:(NSString *)subsystem category:(NSString *)category {
NSAssert((subsystem == nil) == (category == nil), @"Either both subsystem and category or neither should be nil.");
if (self = [super init]) {
_subsystem = [subsystem copy];
_category = [category copy];
}
return self;
}
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
static DDOSLogger *sharedInstance; static DDOSLogger *sharedInstance;
- (instancetype)init {
return [self initWithSubsystem:nil category:nil];
}
+ (instancetype)sharedInstance { + (instancetype)sharedInstance {
static dispatch_once_t DDOSLoggerOnceToken; static dispatch_once_t DDOSLoggerOnceToken;
@@ -65,53 +83,75 @@ static DDOSLogger *sharedInstance;
return sharedInstance; return sharedInstance;
} }
#pragma mark - os_log #pragma mark - Initialization
- (instancetype)initWithSubsystem:(NSString *)subsystem
- (os_log_t)getLogger { category:(NSString *)category
if (self.subsystem == nil || self.category == nil) { logLevelMapper:(id<DDOSLogLevelMapper>)logLevelMapper {
return OS_LOG_DEFAULT; NSAssert((subsystem == nil) == (category == nil),
@"Either both subsystem and category or neither should be nil.");
NSParameterAssert(logLevelMapper);
if (self = [super init]) {
_subsystem = [subsystem copy];
_category = [category copy];
_logLevelMapper = logLevelMapper;
} }
return os_log_create(self.subsystem.UTF8String, self.category.UTF8String); return self;
} }
- (instancetype)initWithSubsystem:(NSString *)subsystem category:(NSString *)category {
return [self initWithSubsystem:subsystem
category:category
logLevelMapper:[[DDOSLogLevelMapperDefault alloc] init]];
}
- (instancetype)init {
return [self initWithSubsystem:nil category:nil];
}
- (instancetype)initWithLogLevelMapper:(id<DDOSLogLevelMapper>)logLevelMapper {
return [self initWithSubsystem:nil category:nil logLevelMapper:logLevelMapper];
}
#pragma mark - Mapper
- (id<DDOSLogLevelMapper>)logLevelMapper {
if (_logLevelMapper == nil) {
_logLevelMapper = [[DDOSLogLevelMapperDefault alloc] init];
}
return _logLevelMapper;
}
#pragma mark - os_log
- (os_log_t)logger { - (os_log_t)logger {
if (_logger == nil) { if (_logger == nil) {
_logger = [self getLogger]; if (self.subsystem == nil || self.category == nil) {
_logger = OS_LOG_DEFAULT;
} else {
_logger = os_log_create(self.subsystem.UTF8String, self.category.UTF8String);
}
} }
return _logger; return _logger;
} }
#pragma mark - DDLogger #pragma mark - DDLogger
- (DDLoggerName)loggerName { - (DDLoggerName)loggerName {
return DDLoggerNameOS; return DDLoggerNameOS;
} }
- (void)logMessage:(DDLogMessage *)logMessage { - (void)logMessage:(DDLogMessage *)logMessage {
// Skip captured log messages #if !TARGET_OS_WATCH // See DDASLLogCapture.m -> Was never supported on watchOS.
// Skip captured log messages.
if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) { if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) {
return; return;
} }
#endif
if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) { if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message; __auto_type message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
if (message != nil) { if (message != nil) {
const char *msg = [message UTF8String]; __auto_type logType = [self.logLevelMapper osLogTypeForLogFlag:logMessage->_flag];
__auto_type logger = [self logger]; os_log_with_type(self.logger, logType, "%{public}s", message.UTF8String);
switch (logMessage->_flag) {
case DDLogFlagError :
os_log_error(logger, "%{public}s", msg);
break;
case DDLogFlagWarning:
case DDLogFlagInfo :
os_log_info(logger, "%{public}s", msg);
break;
case DDLogFlagDebug :
case DDLogFlagVerbose:
default :
os_log_debug(logger, "%{public}s", msg);
break;
}
} }
} }
} }

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -79,23 +79,18 @@
#define MAP_TO_TERMINAL_APP_COLORS 1 #define MAP_TO_TERMINAL_APP_COLORS 1
typedef struct { typedef struct {
uint8_t r; uint8_t r;
uint8_t g; uint8_t g;
uint8_t b; uint8_t b;
} DDRGBColor; } DDRGBColor;
@interface DDTTYLoggerColorProfile : NSObject { @interface DDTTYLoggerColorProfile : NSObject {
@public @public
DDLogFlag mask; DDLogFlag mask;
NSInteger context; NSInteger context;
uint8_t fg_r; DDRGBColor fg;
uint8_t fg_g; DDRGBColor bg;
uint8_t fg_b;
uint8_t bg_r;
uint8_t bg_g;
uint8_t bg_b;
NSUInteger fgCodeIndex; NSUInteger fgCodeIndex;
NSString *fgCodeRaw; NSString *fgCodeRaw;
@@ -117,10 +112,6 @@ typedef struct {
@end @end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface DDTTYLogger () { @interface DDTTYLogger () {
NSString *_appName; NSString *_appName;
char *_app; char *_app;
@@ -137,6 +128,7 @@ typedef struct {
@end @end
#pragma mark -
@implementation DDTTYLogger @implementation DDTTYLogger
@@ -144,30 +136,30 @@ static BOOL isaColorTTY;
static BOOL isaColor256TTY; static BOOL isaColor256TTY;
static BOOL isaXcodeColorTTY; static BOOL isaXcodeColorTTY;
static NSArray *codes_fg = nil; static NSArray *codesFg = nil;
static NSArray *codes_bg = nil; static NSArray *codesBg = nil;
static NSArray *colors = nil; static NSArray *colors = nil;
static DDTTYLogger *sharedInstance; static DDTTYLogger *sharedInstance;
/** /**
* Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 16 color mode. * Initializes the colors array, as well as the `codesFg` and `codesBg` arrays, for 16 color mode.
* *
* This method is used when the application is running from within a shell that only supports 16 color mode. * This method is used when the application is running from within a shell that only supports 16 color mode.
* This method is not invoked if the application is running within Xcode, or via normal UI app launch. * This method is not invoked if the application is running within Xcode, or via normal UI app launch.
**/ **/
+ (void)initialize_colors_16 { + (void)initializeColors16 {
if (codes_fg || codes_bg || colors) { if (codesFg || codesBg || colors) {
return; return;
} }
NSMutableArray *m_colors = [NSMutableArray arrayWithCapacity:16]; __auto_type mColors = [NSMutableArray arrayWithCapacity:16];
// In a standard shell only 16 colors are supported. // In a standard shell only 16 colors are supported.
// //
// More information about ansi escape codes can be found online. // More information about ansi escape codes can be found online.
// http://en.wikipedia.org/wiki/ANSI_escape_code // http://en.wikipedia.org/wiki/ANSI_escape_code
codes_fg = @[ codesFg = @[
@"30m", // normal - black @"30m", // normal - black
@"31m", // normal - red @"31m", // normal - red
@"32m", // normal - green @"32m", // normal - green
@@ -186,7 +178,7 @@ static DDTTYLogger *sharedInstance;
@"1;37m", // bright - white @"1;37m", // bright - white
]; ];
codes_bg = @[ codesBg = @[
@"40m", // normal - black @"40m", // normal - black
@"41m", // normal - red @"41m", // normal - red
@"42m", // normal - green @"42m", // normal - green
@@ -205,13 +197,12 @@ static DDTTYLogger *sharedInstance;
@"1;47m", // bright - white @"1;47m", // bright - white
]; ];
#if MAP_TO_TERMINAL_APP_COLORS #if MAP_TO_TERMINAL_APP_COLORS
// Standard Terminal.app colors: // Standard Terminal.app colors:
// //
// These are the default colors used by Apple's Terminal.app. // These are the default colors used by Apple's Terminal.app.
DDRGBColor rgbColors[] = { const DDRGBColor rgbColors[] = {
{ 0, 0, 0}, // normal - black { 0, 0, 0}, // normal - black
{194, 54, 33}, // normal - red {194, 54, 33}, // normal - red
{ 37, 188, 36}, // normal - green { 37, 188, 36}, // normal - green
@@ -235,8 +226,7 @@ static DDTTYLogger *sharedInstance;
// Standard xterm colors: // Standard xterm colors:
// //
// These are the default colors used by most xterm shells. // These are the default colors used by most xterm shells.
const DDRGBColor rgbColors[] = {
DDRGBColor rgbColors[] = {
{ 0, 0, 0}, // normal - black { 0, 0, 0}, // normal - black
{205, 0, 0}, // normal - red {205, 0, 0}, // normal - red
{ 0, 205, 0}, // normal - green { 0, 205, 0}, // normal - green
@@ -257,30 +247,30 @@ static DDTTYLogger *sharedInstance;
#endif /* if MAP_TO_TERMINAL_APP_COLORS */ #endif /* if MAP_TO_TERMINAL_APP_COLORS */
for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) { for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) {
[m_colors addObject:DDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)]; [mColors addObject:DDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)];
} }
colors = [m_colors copy]; colors = [mColors copy];
NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)"); NSAssert([codesFg count] == [codesBg count], @"Invalid colors/codes array(s)");
NSAssert([codes_fg count] == [colors count], @"Invalid colors/codes array(s)"); NSAssert([codesFg count] == [colors count], @"Invalid colors/codes array(s)");
} }
/** /**
* Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 256 color mode. * Initializes the colors array, as well as the `codesFg` and `codesBg` arrays, for 256 color mode.
* *
* This method is used when the application is running from within a shell that supports 256 color mode. * This method is used when the application is running from within a shell that supports 256 color mode.
* This method is not invoked if the application is running within Xcode, or via normal UI app launch. * This method is not invoked if the application is running within Xcode, or via normal UI app launch.
**/ **/
+ (void)initialize_colors_256 { + (void)initializeColors256 {
if (codes_fg || codes_bg || colors) { if (codesFg || codesBg || colors) {
return; return;
} }
NSMutableArray *m_codes_fg = [NSMutableArray arrayWithCapacity:(256 - 16)]; __auto_type mCodesFg = [NSMutableArray arrayWithCapacity:(256 - 16)];
NSMutableArray *m_codes_bg = [NSMutableArray arrayWithCapacity:(256 - 16)]; __auto_type mCodesBg = [NSMutableArray arrayWithCapacity:(256 - 16)];
NSMutableArray *m_colors = [NSMutableArray arrayWithCapacity:(256 - 16)]; __auto_type mColors = [NSMutableArray arrayWithCapacity:(256 - 16)];
#if MAP_TO_TERMINAL_APP_COLORS #if MAP_TO_TERMINAL_APP_COLORS
// Standard Terminal.app colors: // Standard Terminal.app colors:
// //
@@ -307,7 +297,7 @@ static DDTTYLogger *sharedInstance;
// http://en.wikipedia.org/wiki/ANSI_escape_code // http://en.wikipedia.org/wiki/ANSI_escape_code
// Colors // Colors
DDRGBColor rgbColors[] = { const DDRGBColor rgbColors[] = {
{ 47, 49, 49}, { 47, 49, 49},
{ 60, 42, 144}, { 60, 42, 144},
{ 66, 44, 183}, { 66, 44, 183},
@@ -592,21 +582,19 @@ static DDTTYLogger *sharedInstance;
}; };
for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) { for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) {
[m_colors addObject:DDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)]; [mColors addObject:DDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)];
} }
// Color codes // Color codes
int index = 16; int index = 16;
while (index < 256) { while (index < 256) {
[m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; [mCodesFg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
[m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; [mCodesBg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
index++; index++;
} }
#else /* if MAP_TO_TERMINAL_APP_COLORS */ #else /* if MAP_TO_TERMINAL_APP_COLORS */
// Standard xterm colors: // Standard xterm colors:
// //
@@ -652,9 +640,9 @@ static DDTTYLogger *sharedInstance;
for (bi = 0; bi < 6; bi++) { for (bi = 0; bi < 6; bi++) {
b = (bi == 0) ? 0 : 95 + (40 * (bi - 1)); b = (bi == 0) ? 0 : 95 + (40 * (bi - 1));
[m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; [mCodesFg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
[m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; [mCodesBg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
[m_colors addObject:DDMakeColor(r, g, b)]; [mColors addObject:DDMakeColor(r, g, b)];
index++; index++;
} }
@@ -668,9 +656,9 @@ static DDTTYLogger *sharedInstance;
b = 8; b = 8;
while (index < 256) { while (index < 256) {
[m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; [mCodesFg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
[m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; [mCodesBg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
[m_colors addObject:DDMakeColor(r, g, b)]; [mColor s addObject:DDMakeColor(r, g, b)];
r += 10; r += 10;
g += 10; g += 10;
@@ -679,22 +667,21 @@ static DDTTYLogger *sharedInstance;
index++; index++;
} }
#endif /* if MAP_TO_TERMINAL_APP_COLORS */ #endif /* if MAP_TO_TERMINAL_APP_COLORS */
codes_fg = [m_codes_fg copy]; codesFg = [mCodesFg copy];
codes_bg = [m_codes_bg copy]; codesBg = [mCodesBg copy];
colors = [m_colors copy]; colors = [mColors copy];
NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)"); NSAssert([codesFg count] == [codesBg count], @"Invalid colors/codes array(s)");
NSAssert([codes_fg count] == [colors count], @"Invalid colors/codes array(s)"); NSAssert([codesFg count] == [colors count], @"Invalid colors/codes array(s)");
} }
+ (void)getRed:(CGFloat *)rPtr green:(CGFloat *)gPtr blue:(CGFloat *)bPtr fromColor:(DDColor *)color { + (void)getRed:(CGFloat *)rPtr green:(CGFloat *)gPtr blue:(CGFloat *)bPtr fromColor:(DDColor *)color {
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
// iOS // iOS
__auto_type done = NO;
BOOL done = NO;
if ([color respondsToSelector:@selector(getRed:green:blue:alpha:)]) { if ([color respondsToSelector:@selector(getRed:green:blue:alpha:)]) {
done = [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; done = [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL];
@@ -704,44 +691,49 @@ static DDTTYLogger *sharedInstance;
// The method getRed:green:blue:alpha: was only available starting iOS 5. // The method getRed:green:blue:alpha: was only available starting iOS 5.
// So in iOS 4 and earlier, we have to jump through hoops. // So in iOS 4 and earlier, we have to jump through hoops.
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); __auto_type rgbColorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char pixel[4]; unsigned char pixel[4];
CGContextRef context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, rgbColorSpace, (CGBitmapInfo)(kCGBitmapAlphaInfoMask & kCGImageAlphaNoneSkipLast)); __auto_type context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, rgbColorSpace, (CGBitmapInfo)(((CGImageAlphaInfo)kCGBitmapAlphaInfoMask) & kCGImageAlphaNoneSkipLast));
CGContextSetFillColorWithColor(context, [color CGColor]); CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, CGRectMake(0, 0, 1, 1)); CGContextFillRect(context, CGRectMake(0, 0, 1, 1));
if (rPtr) { if (rPtr) {
*rPtr = pixel[0] / 255.0f; *rPtr = pixel[0] / 255.0;
} }
if (gPtr) { if (gPtr) {
*gPtr = pixel[1] / 255.0f; *gPtr = pixel[1] / 255.0;
} }
if (bPtr) { if (bPtr) {
*bPtr = pixel[2] / 255.0f; *bPtr = pixel[2] / 255.0;
} }
CGContextRelease(context); CGContextRelease(context);
CGColorSpaceRelease(rgbColorSpace); CGColorSpaceRelease(rgbColorSpace);
} }
#elif defined(DD_CLI) || !__has_include(<AppKit/NSColor.h>) #elif defined(DD_CLI) || !__has_include(<AppKit/NSColor.h>)
// OS X without AppKit // OS X without AppKit
[color getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL];
#else /* if TARGET_OS_IPHONE */ #else /* if TARGET_OS_IPHONE */
// OS X with AppKit // OS X with AppKit
NSColor *safeColor;
NSColor *safeColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; if (@available(macOS 10.14,*)) {
safeColor = [color colorUsingColorSpace:NSColorSpace.deviceRGBColorSpace];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
safeColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
#pragma clang diagnostic pop
}
[safeColor getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; [safeColor getRed:rPtr green:gPtr blue:bPtr alpha:NULL];
#endif /* if TARGET_OS_IPHONE */
#endif /* if TARGET_OS_IPHONE */
} }
/** /**
@@ -750,7 +742,7 @@ static DDTTYLogger *sharedInstance;
* *
* This method loops through the known supported color set, and calculates the closest color. * This method loops through the known supported color set, and calculates the closest color.
* The array index of that color, within the colors array, is then returned. * The array index of that color, within the colors array, is then returned.
* This array index may also be used as the index within the codes_fg and codes_bg arrays. * This array index may also be used as the index within the `codesFg` and `codesBg` arrays.
**/ **/
+ (NSUInteger)codeIndexForColor:(DDColor *)inColor { + (NSUInteger)codeIndexForColor:(DDColor *)inColor {
CGFloat inR, inG, inB; CGFloat inR, inG, inB;
@@ -758,7 +750,7 @@ static DDTTYLogger *sharedInstance;
[self getRed:&inR green:&inG blue:&inB fromColor:inColor]; [self getRed:&inR green:&inG blue:&inB fromColor:inColor];
NSUInteger bestIndex = 0; NSUInteger bestIndex = 0;
CGFloat lowestDistance = 100.0f; CGFloat lowestDistance = 100.0;
NSUInteger i = 0; NSUInteger i = 0;
@@ -768,14 +760,14 @@ static DDTTYLogger *sharedInstance;
CGFloat r, g, b; CGFloat r, g, b;
[self getRed:&r green:&g blue:&b fromColor:color]; [self getRed:&r green:&g blue:&b fromColor:color];
#if CGFLOAT_IS_DOUBLE #if CGFLOAT_IS_DOUBLE
CGFloat distance = sqrt(pow(r - inR, 2.0) + pow(g - inG, 2.0) + pow(b - inB, 2.0)); __auto_type distance = sqrt(pow(r - inR, 2.0) + pow(g - inG, 2.0) + pow(b - inB, 2.0));
#else #else
CGFloat distance = sqrtf(powf(r - inR, 2.0f) + powf(g - inG, 2.0f) + powf(b - inB, 2.0f)); __auto_type distance = sqrtf(powf(r - inR, 2.0f) + powf(g - inG, 2.0f) + powf(b - inB, 2.0f));
#endif #endif
NSLogVerbose(@"DDTTYLogger: %3lu : %.3f,%.3f,%.3f & %.3f,%.3f,%.3f = %.6f", NSLogVerbose(@"DDTTYLogger: %3lu : %.3f,%.3f,%.3f & %.3f,%.3f,%.3f = %.6f",
(unsigned long)i, inR, inG, inB, r, g, b, distance); (unsigned long)i, (double)inR, (double)inG, (double)inB, (double)r, (double)g, (double)b, (double)distance);
if (distance < lowestDistance) { if (distance < lowestDistance) {
bestIndex = i; bestIndex = i;
@@ -799,10 +791,10 @@ static DDTTYLogger *sharedInstance;
// //
// PS - Please read the header file before diving into the source code. // PS - Please read the header file before diving into the source code.
char *xcode_colors = getenv("XcodeColors"); __auto_type xcodeColors = getenv("XcodeColors");
char *term = getenv("TERM"); __auto_type term = getenv("TERM");
if (xcode_colors && (strcmp(xcode_colors, "YES") == 0)) { if (xcodeColors && (strcmp(xcodeColors, "YES") == 0)) {
isaXcodeColorTTY = YES; isaXcodeColorTTY = YES;
} else if (term) { } else if (term) {
if (strcasestr(term, "color") != NULL) { if (strcasestr(term, "color") != NULL) {
@@ -810,9 +802,9 @@ static DDTTYLogger *sharedInstance;
isaColor256TTY = (strcasestr(term, "256") != NULL); isaColor256TTY = (strcasestr(term, "256") != NULL);
if (isaColor256TTY) { if (isaColor256TTY) {
[self initialize_colors_256]; [self initializeColors256];
} else { } else {
[self initialize_colors_16]; [self initializeColors16];
} }
} }
} }
@@ -840,9 +832,7 @@ static DDTTYLogger *sharedInstance;
if ((self = [super init])) { if ((self = [super init])) {
// Initialize 'app' variable (char *) // Initialize 'app' variable (char *)
_appName = [[NSProcessInfo processInfo] processName]; _appName = [[NSProcessInfo processInfo] processName];
_appLen = [_appName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; _appLen = [_appName lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
if (_appLen == 0) { if (_appLen == 0) {
@@ -851,14 +841,12 @@ static DDTTYLogger *sharedInstance;
} }
_app = (char *)calloc(_appLen + 1, sizeof(char)); _app = (char *)calloc(_appLen + 1, sizeof(char));
if (_app == NULL) { if (_app == NULL) {
return nil; return nil;
} }
BOOL processedAppName = [_appName getCString:_app maxLength:(_appLen + 1) encoding:NSUTF8StringEncoding]; BOOL processedAppName = [_appName getCString:_app maxLength:(_appLen + 1) encoding:NSUTF8StringEncoding];
if (!processedAppName) {
if (NO == processedAppName) {
free(_app); free(_app);
return nil; return nil;
} }
@@ -876,8 +864,7 @@ static DDTTYLogger *sharedInstance;
} }
BOOL processedID = [_processID getCString:_pid maxLength:(_pidLen + 1) encoding:NSUTF8StringEncoding]; BOOL processedID = [_processID getCString:_pid maxLength:(_pidLen + 1) encoding:NSUTF8StringEncoding];
if (!processedID) {
if (NO == processedID) {
free(_app); free(_app);
free(_pid); free(_pid);
return nil; return nil;
@@ -915,14 +902,9 @@ static DDTTYLogger *sharedInstance;
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
__block BOOL result; __block BOOL result;
dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(globalLoggingQueue, ^{
dispatch_sync(self.loggerQueue, ^{ dispatch_sync(self.loggerQueue, ^{
result = self->_colorsEnabled; result = self->_colorsEnabled;
}); });
@@ -932,7 +914,7 @@ static DDTTYLogger *sharedInstance;
} }
- (void)setColorsEnabled:(BOOL)newColorsEnabled { - (void)setColorsEnabled:(BOOL)newColorsEnabled {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
self->_colorsEnabled = newColorsEnabled; self->_colorsEnabled = newColorsEnabled;
@@ -952,12 +934,8 @@ static DDTTYLogger *sharedInstance;
// This is the intended result. Fix it by accessing the ivar directly. // This is the intended result. Fix it by accessing the ivar directly.
// Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); DDAbstractLoggerAssertLockedPropertyAccess();
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); dispatch_async(DDLog.loggingQueue, ^{
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
@@ -969,11 +947,11 @@ static DDTTYLogger *sharedInstance;
- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask context:(NSInteger)ctxt { - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask context:(NSInteger)ctxt {
dispatch_block_t block = ^{ dispatch_block_t block = ^{
@autoreleasepool { @autoreleasepool {
DDTTYLoggerColorProfile *newColorProfile = DDTTYLoggerColorProfile *newColorProfile = [[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor
[[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor backgroundColor:bgColor
backgroundColor:bgColor flag:mask
flag:mask context:ctxt];
context:ctxt]; if (!newColorProfile) return;
NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile); NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile);
@@ -1001,25 +979,22 @@ static DDTTYLogger *sharedInstance;
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
} }
- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forTag:(id <NSCopying>)tag { - (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forTag:(id <NSCopying>)tag {
NSAssert([(id < NSObject >) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag"); NSAssert([(id <NSObject>)tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag");
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
DDTTYLoggerColorProfile *newColorProfile = __auto_type newColorProfile = [[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor
[[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor backgroundColor:bgColor
backgroundColor:bgColor flag:(DDLogFlag)0
flag:(DDLogFlag)0 context:0];
context:0];
NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile); NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile);
@@ -1033,10 +1008,8 @@ static DDTTYLogger *sharedInstance;
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
@@ -1047,7 +1020,7 @@ static DDTTYLogger *sharedInstance;
} }
- (void)clearColorsForFlag:(DDLogFlag)mask context:(NSInteger)context { - (void)clearColorsForFlag:(DDLogFlag)mask context:(NSInteger)context {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
NSUInteger i = 0; NSUInteger i = 0;
@@ -1071,19 +1044,17 @@ static DDTTYLogger *sharedInstance;
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
} }
- (void)clearColorsForTag:(id <NSCopying>)tag { - (void)clearColorsForTag:(id <NSCopying>)tag {
NSAssert([(id < NSObject >) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag"); NSAssert([(id <NSObject>) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag");
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
[self->_colorProfilesDict removeObjectForKey:tag]; [self->_colorProfilesDict removeObjectForKey:tag];
} }
@@ -1095,17 +1066,15 @@ static DDTTYLogger *sharedInstance;
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
} }
- (void)clearColorsForAllFlags { - (void)clearColorsForAllFlags {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
[self->_colorProfilesArray removeAllObjects]; [self->_colorProfilesArray removeAllObjects];
} }
@@ -1117,17 +1086,15 @@ static DDTTYLogger *sharedInstance;
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
} }
- (void)clearColorsForAllTags { - (void)clearColorsForAllTags {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
[self->_colorProfilesDict removeAllObjects]; [self->_colorProfilesDict removeAllObjects];
} }
@@ -1139,17 +1106,15 @@ static DDTTYLogger *sharedInstance;
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
} }
- (void)clearAllColors { - (void)clearAllColors {
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
[self->_colorProfilesArray removeAllObjects]; [self->_colorProfilesArray removeAllObjects];
[self->_colorProfilesDict removeAllObjects]; [self->_colorProfilesDict removeAllObjects];
@@ -1162,18 +1127,16 @@ static DDTTYLogger *sharedInstance;
if ([self isOnInternalLoggerQueue]) { if ([self isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; DDAbstractLoggerAssertNotOnGlobalLoggingQueue();
NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); dispatch_async(DDLog.loggingQueue, ^{
dispatch_async(globalLoggingQueue, ^{
dispatch_async(self.loggerQueue, block); dispatch_async(self.loggerQueue, block);
}); });
} }
} }
- (void)logMessage:(DDLogMessage *)logMessage { - (void)logMessage:(DDLogMessage *)logMessage {
NSString *logMsg = logMessage->_message; __auto_type logMsg = logMessage->_message;
BOOL isFormatted = NO; __auto_type isFormatted = NO;
if (_logFormatter) { if (_logFormatter) {
logMsg = [_logFormatter formatLogMessage:logMessage]; logMsg = [_logFormatter formatLogMessage:logMessage];
@@ -1217,8 +1180,8 @@ static DDTTYLogger *sharedInstance;
// We use the stack instead of the heap for speed if possible. // We use the stack instead of the heap for speed if possible.
// But we're extra cautious to avoid a stack overflow. // But we're extra cautious to avoid a stack overflow.
NSUInteger msgLen = [logMsg lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; __auto_type msgLen = [logMsg lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const BOOL useStack = msgLen < (1024 * 4); const __auto_type useStack = msgLen < (1024 * 4);
char *msg; char *msg;
if (useStack) { if (useStack) {
@@ -1242,8 +1205,12 @@ static DDTTYLogger *sharedInstance;
if (isFormatted) { if (isFormatted) {
// The log message has already been formatted. // The log message has already been formatted.
const int iovec_len = (_automaticallyAppendNewlineForCustomFormatters) ? 5 : 4;
struct iovec v[iovec_len]; // Needs to be a define, because otherwise the compiler warns "Variable length array folded to constant array as an extension"
#define DD_TTYLOGGER_MAX_IOVEC_LEN 5
size_t iovecLen = _automaticallyAppendNewlineForCustomFormatters ? 5 : 4;
struct iovec v[DD_TTYLOGGER_MAX_IOVEC_LEN] = { 0 };
if (colorProfile) { if (colorProfile) {
v[0].iov_base = colorProfile->fgCode; v[0].iov_base = colorProfile->fgCode;
@@ -1252,28 +1219,20 @@ static DDTTYLogger *sharedInstance;
v[1].iov_base = colorProfile->bgCode; v[1].iov_base = colorProfile->bgCode;
v[1].iov_len = colorProfile->bgCodeLen; v[1].iov_len = colorProfile->bgCodeLen;
v[iovec_len - 1].iov_base = colorProfile->resetCode; v[DD_TTYLOGGER_MAX_IOVEC_LEN - 1].iov_base = colorProfile->resetCode;
v[iovec_len - 1].iov_len = colorProfile->resetCodeLen; v[DD_TTYLOGGER_MAX_IOVEC_LEN - 1].iov_len = colorProfile->resetCodeLen;
} else {
v[0].iov_base = "";
v[0].iov_len = 0;
v[1].iov_base = "";
v[1].iov_len = 0;
v[iovec_len - 1].iov_base = "";
v[iovec_len - 1].iov_len = 0;
} }
v[2].iov_base = msg; v[2].iov_base = msg;
v[2].iov_len = msgLen; v[2].iov_len = (msgLen > SIZE_MAX - 1) ? SIZE_MAX - 1 : msgLen;
if (iovec_len == 5) { if (_automaticallyAppendNewlineForCustomFormatters && (v[2].iov_len == 0 || msg[v[2].iov_len - 1] != '\n')) {
v[3].iov_base = "\n"; v[3].iov_base = "\n";
v[3].iov_len = (msg[msgLen] == '\n') ? 0 : 1; v[3].iov_len = 1;
iovecLen = 5;
} }
writev(STDERR_FILENO, v, iovec_len); writev(STDERR_FILENO, v, (int)iovecLen);
} else { } else {
// The log message is unformatted, so apply standard NSLog style formatting. // The log message is unformatted, so apply standard NSLog style formatting.
@@ -1284,13 +1243,15 @@ static DDTTYLogger *sharedInstance;
// Calculate timestamp. // Calculate timestamp.
// The technique below is faster than using NSDateFormatter. // The technique below is faster than using NSDateFormatter.
if (logMessage->_timestamp) { if (logMessage->_timestamp) {
NSTimeInterval epoch = [logMessage->_timestamp timeIntervalSince1970]; __auto_type epoch = [logMessage->_timestamp timeIntervalSince1970];
double integral;
__auto_type fract = modf(epoch, &integral);
struct tm tm; struct tm tm;
time_t time = (time_t)epoch; __auto_type time = (time_t)integral;
(void)localtime_r(&time, &tm); (void)localtime_r(&time, &tm);
int milliseconds = (int)((epoch - floor(epoch)) * 1000.0); __auto_type milliseconds = (long)(fract * 1000.0);
len = snprintf(ts, 24, "%04d-%02d-%02d %02d:%02d:%02d:%03d", // yyyy-MM-dd HH:mm:ss:SSS len = snprintf(ts, 24, "%04d-%02d-%02d %02d:%02d:%02d:%03ld", // yyyy-MM-dd HH:mm:ss:SSS
tm.tm_year + 1900, tm.tm_year + 1900,
tm.tm_mon + 1, tm.tm_mon + 1,
tm.tm_mday, tm.tm_mday,
@@ -1312,7 +1273,7 @@ static DDTTYLogger *sharedInstance;
char tid[9]; char tid[9];
len = snprintf(tid, 9, "%s", [logMessage->_threadID cStringUsingEncoding:NSUTF8StringEncoding]); len = snprintf(tid, 9, "%s", [logMessage->_threadID cStringUsingEncoding:NSUTF8StringEncoding]);
size_t tidLen = (NSUInteger)MAX(MIN(9 - 1, len), 0); __auto_type tidLen = (NSUInteger)MAX(MIN(9 - 1, len), 0);
// Here is our format: "%s %s[%i:%s] %s", timestamp, appName, processID, threadID, logMsg // Here is our format: "%s %s[%i:%s] %s", timestamp, appName, processID, threadID, logMsg
@@ -1379,7 +1340,7 @@ static DDTTYLogger *sharedInstance;
@end @end
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark -
@implementation DDTTYLoggerColorProfile @implementation DDTTYLoggerColorProfile
@@ -1393,31 +1354,31 @@ static DDTTYLogger *sharedInstance;
if (fgColor) { if (fgColor) {
[DDTTYLogger getRed:&r green:&g blue:&b fromColor:fgColor]; [DDTTYLogger getRed:&r green:&g blue:&b fromColor:fgColor];
fg_r = (uint8_t)(r * 255.0f); fg.r = (uint8_t)(r * (CGFloat)255.0);
fg_g = (uint8_t)(g * 255.0f); fg.g = (uint8_t)(g * (CGFloat)255.0);
fg_b = (uint8_t)(b * 255.0f); fg.b = (uint8_t)(b * (CGFloat)255.0);
} }
if (bgColor) { if (bgColor) {
[DDTTYLogger getRed:&r green:&g blue:&b fromColor:bgColor]; [DDTTYLogger getRed:&r green:&g blue:&b fromColor:bgColor];
bg_r = (uint8_t)(r * 255.0f); bg.r = (uint8_t)(r * (CGFloat)255.0);
bg_g = (uint8_t)(g * 255.0f); bg.g = (uint8_t)(g * (CGFloat)255.0);
bg_b = (uint8_t)(b * 255.0f); bg.b = (uint8_t)(b * (CGFloat)255.0);
} }
if (fgColor && isaColorTTY) { if (fgColor && isaColorTTY) {
// Map foreground color to closest available shell color // Map foreground color to closest available shell color
fgCodeIndex = [DDTTYLogger codeIndexForColor:fgColor]; fgCodeIndex = [DDTTYLogger codeIndexForColor:fgColor];
fgCodeRaw = codes_fg[fgCodeIndex]; fgCodeRaw = codesFg[fgCodeIndex];
NSString *escapeSeq = @"\033["; const __auto_type escapeSeq = @"\033[";
NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; __auto_type len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger len2 = [fgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; __auto_type len2 = [fgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
BOOL escapeSeqEnc = [escapeSeq getCString:(fgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding]; BOOL escapeSeqEnc = [escapeSeq getCString:(fgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding];
BOOL fgCodeRawEsc = [fgCodeRaw getCString:(fgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding]; BOOL fgCodeRawEsc = [fgCodeRaw getCString:(fgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding];
if (!escapeSeqEnc || !fgCodeRawEsc) { if (!escapeSeqEnc || !fgCodeRawEsc) {
@@ -1427,14 +1388,11 @@ static DDTTYLogger *sharedInstance;
fgCodeLen = len1 + len2; fgCodeLen = len1 + len2;
} else if (fgColor && isaXcodeColorTTY) { } else if (fgColor && isaXcodeColorTTY) {
// Convert foreground color to color code sequence // Convert foreground color to color code sequence
const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ; const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ;
__auto_type result = snprintf(fgCode, 24, "%sfg%u,%u,%u;", escapeSeq, fg.r, fg.g, fg.b);
int result = snprintf(fgCode, 24, "%sfg%u,%u,%u;", escapeSeq, fg_r, fg_g, fg_b);
fgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0); fgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0);
} else { } else {
// No foreground color or no color support // No foreground color or no color support
fgCode[0] = '\0'; fgCode[0] = '\0';
fgCodeLen = 0; fgCodeLen = 0;
} }
@@ -1443,14 +1401,14 @@ static DDTTYLogger *sharedInstance;
// Map background color to closest available shell color // Map background color to closest available shell color
bgCodeIndex = [DDTTYLogger codeIndexForColor:bgColor]; bgCodeIndex = [DDTTYLogger codeIndexForColor:bgColor];
bgCodeRaw = codes_bg[bgCodeIndex]; bgCodeRaw = codesBg[bgCodeIndex];
NSString *escapeSeq = @"\033["; const __auto_type escapeSeq = @"\033[";
NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; __auto_type len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger len2 = [bgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; __auto_type len2 = [bgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
BOOL escapeSeqEnc = [escapeSeq getCString:(bgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding]; BOOL escapeSeqEnc = [escapeSeq getCString:(bgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding];
BOOL bgCodeRawEsc = [bgCodeRaw getCString:(bgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding]; BOOL bgCodeRawEsc = [bgCodeRaw getCString:(bgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding];
if (!escapeSeqEnc || !bgCodeRawEsc) { if (!escapeSeqEnc || !bgCodeRawEsc) {
@@ -1460,14 +1418,11 @@ static DDTTYLogger *sharedInstance;
bgCodeLen = len1 + len2; bgCodeLen = len1 + len2;
} else if (bgColor && isaXcodeColorTTY) { } else if (bgColor && isaXcodeColorTTY) {
// Convert background color to color code sequence // Convert background color to color code sequence
const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ; const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ;
__auto_type result = snprintf(bgCode, 24, "%sbg%u,%u,%u;", escapeSeq, bg.r, bg.g, bg.b);
int result = snprintf(bgCode, 24, "%sbg%u,%u,%u;", escapeSeq, bg_r, bg_g, bg_b);
bgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0); bgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0);
} else { } else {
// No background color or no color support // No background color or no color support
bgCode[0] = '\0'; bgCode[0] = '\0';
bgCodeLen = 0; bgCodeLen = 0;
} }
@@ -1488,7 +1443,7 @@ static DDTTYLogger *sharedInstance;
- (NSString *)description { - (NSString *)description {
return [NSString stringWithFormat: return [NSString stringWithFormat:
@"<DDTTYLoggerColorProfile: %p mask:%i ctxt:%ld fg:%u,%u,%u bg:%u,%u,%u fgCode:%@ bgCode:%@>", @"<DDTTYLoggerColorProfile: %p mask:%i ctxt:%ld fg:%u,%u,%u bg:%u,%u,%u fgCode:%@ bgCode:%@>",
self, (int)mask, (long)context, fg_r, fg_g, fg_b, bg_r, bg_g, bg_b, fgCodeRaw, bgCodeRaw]; self, (int)mask, (long)context, fg.r, fg.g, fg.b, bg.r, bg.g, bg.b, fgCodeRaw, bgCodeRaw];
} }
@end @end

View File

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

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -171,7 +171,7 @@
} }
- (BOOL)isInSet:(NSInteger)loggingContext { - (BOOL)isInSet:(NSInteger)loggingContext {
BOOL result = NO; __auto_type result = NO;
pthread_mutex_lock(&_mutex); pthread_mutex_lock(&_mutex);
{ {

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -134,99 +134,70 @@ static DDQualityOfServiceName _qos_name(NSUInteger qos) {
- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage { - (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage {
// As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue // As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue
NSUInteger minQueueLength = self.minQueueLength; __auto_type useQueueLabel = NO;
NSUInteger maxQueueLength = self.maxQueueLength;
// Get the name of the queue, thread, or machID (whichever we are to use).
NSString *queueThreadLabel = nil;
BOOL useQueueLabel = YES;
BOOL useThreadName = NO;
if (logMessage->_queueLabel) { if (logMessage->_queueLabel) {
useQueueLabel = YES;
// If you manually create a thread, it's dispatch_queue will have one of the thread names below. // If you manually create a thread, it's dispatch_queue will have one of the thread names below.
// Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID. // Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID.
const NSArray<NSString *> *names = @[
NSArray *names = @[
@"com.apple.root.low-priority", @"com.apple.root.low-priority",
@"com.apple.root.default-priority", @"com.apple.root.default-priority",
@"com.apple.root.high-priority", @"com.apple.root.high-priority",
@"com.apple.root.low-overcommit-priority", @"com.apple.root.low-overcommit-priority",
@"com.apple.root.default-overcommit-priority", @"com.apple.root.default-overcommit-priority",
@"com.apple.root.high-overcommit-priority", @"com.apple.root.high-overcommit-priority",
@"com.apple.root.default-qos.overcommit" @"com.apple.root.default-qos.overcommit",
]; ];
for (NSString *name in names) {
for (NSString * name in names) {
if ([logMessage->_queueLabel isEqualToString:name]) { if ([logMessage->_queueLabel isEqualToString:name]) {
useQueueLabel = NO; useQueueLabel = NO;
useThreadName = [logMessage->_threadName length] > 0;
break; break;
} }
} }
} else {
useQueueLabel = NO;
useThreadName = [logMessage->_threadName length] > 0;
} }
if (useQueueLabel || useThreadName) { // Get the name of the queue, thread, or machID (whichever we are to use).
NSString *fullLabel; NSString *queueThreadLabel;
if (useQueueLabel || [logMessage->_threadName length] > 0) {
__auto_type fullLabel = useQueueLabel ? logMessage->_queueLabel : logMessage->_threadName;
NSString *abrvLabel; NSString *abrvLabel;
if (useQueueLabel) {
fullLabel = logMessage->_queueLabel;
} else {
fullLabel = logMessage->_threadName;
}
pthread_mutex_lock(&_mutex); pthread_mutex_lock(&_mutex);
{ {
abrvLabel = _replacements[fullLabel]; abrvLabel = _replacements[fullLabel];
} }
pthread_mutex_unlock(&_mutex); pthread_mutex_unlock(&_mutex);
if (abrvLabel) { queueThreadLabel = abrvLabel ?: fullLabel;
queueThreadLabel = abrvLabel;
} else {
queueThreadLabel = fullLabel;
}
} else { } else {
queueThreadLabel = logMessage->_threadID; queueThreadLabel = logMessage->_threadID;
} }
// Now use the thread label in the output // Now use the thread label in the output
NSUInteger labelLength = [queueThreadLabel length];
// labelLength > maxQueueLength : truncate // labelLength > maxQueueLength : truncate
// labelLength < minQueueLength : padding // labelLength < minQueueLength : padding
// : exact // : exact
__auto_type minQueueLength = self.minQueueLength;
if ((maxQueueLength > 0) && (labelLength > maxQueueLength)) { __auto_type maxQueueLength = self.maxQueueLength;
__auto_type labelLength = [queueThreadLabel length];
if (maxQueueLength > 0 && labelLength > maxQueueLength) {
// Truncate // Truncate
return [queueThreadLabel substringToIndex:maxQueueLength]; return [queueThreadLabel substringToIndex:maxQueueLength];
} else if (labelLength < minQueueLength) { } else if (labelLength < minQueueLength) {
// Padding // Padding
return [queueThreadLabel stringByPaddingToLength:minQueueLength
NSUInteger numSpaces = minQueueLength - labelLength; withString:@" "
startingAtIndex:0];
char spaces[numSpaces + 1];
memset(spaces, ' ', numSpaces);
spaces[numSpaces] = '\0';
return [NSString stringWithFormat:@"%@%s", queueThreadLabel, spaces];
} else { } else {
// Exact // Exact
return queueThreadLabel; return queueThreadLabel;
} }
} }
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { - (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
NSString *timestamp = [self stringFromDate:(logMessage->_timestamp)]; __auto_type timestamp = [self stringFromDate:logMessage->_timestamp];
NSString *queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage]; __auto_type queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage];
return [NSString stringWithFormat:@"%@ [%@ (QOS:%@)] %@", timestamp, queueThreadLabel, _qos_name(logMessage->_qos), logMessage->_message]; return [NSString stringWithFormat:@"%@ [%@ (QOS:%@)] %@", timestamp, queueThreadLabel, _qos_name(logMessage->_qos), logMessage->_message];
} }

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -26,11 +26,11 @@ static const NSUInteger kDDMaxBufferSize = 1048576; // ~1 mB, f_iosize on iphone
// f_bsize == "default", and f_iosize == "max" // f_bsize == "default", and f_iosize == "max"
static inline NSUInteger p_DDGetDefaultBufferSizeBytesMax(const BOOL max) { static inline NSUInteger p_DDGetDefaultBufferSizeBytesMax(const BOOL max) {
struct statfs *mountedFileSystems = NULL; struct statfs *mountedFileSystems = NULL;
int count = getmntinfo(&mountedFileSystems, 0); __auto_type count = getmntinfo(&mountedFileSystems, 0);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
struct statfs mounted = mountedFileSystems[i]; __auto_type mounted = mountedFileSystems[i];
const char *name = mounted.f_mntonname; __auto_type name = mounted.f_mntonname;
// We can use 2 as max here, since any length > 1 will fail the if-statement. // We can use 2 as max here, since any length > 1 will fail the if-statement.
if (strnlen(name, 2) == 1 && *name == '/') { if (strnlen(name, 2) == 1 && *name == '/') {
@@ -41,7 +41,7 @@ static inline NSUInteger p_DDGetDefaultBufferSizeBytesMax(const BOOL max) {
return max ? kDDMaxBufferSize : kDDDefaultBufferSize; return max ? kDDMaxBufferSize : kDDDefaultBufferSize;
} }
static NSUInteger DDGetMaxBufferSizeBytes() { static NSUInteger DDGetMaxBufferSizeBytes(void) {
static NSUInteger maxBufferSize = 0; static NSUInteger maxBufferSize = 0;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
@@ -50,7 +50,7 @@ static NSUInteger DDGetMaxBufferSizeBytes() {
return maxBufferSize; return maxBufferSize;
} }
static NSUInteger DDGetDefaultBufferSizeBytes() { static NSUInteger DDGetDefaultBufferSizeBytes(void) {
static NSUInteger defaultBufferSize = 0; static NSUInteger defaultBufferSize = 0;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
@@ -80,7 +80,7 @@ static NSUInteger DDGetDefaultBufferSizeBytes() {
} }
- (void)dealloc { - (void)dealloc {
dispatch_block_t block = ^{ __auto_type block = ^{
[self lt_sendBufferedDataToFileLogger]; [self lt_sendBufferedDataToFileLogger];
self.fileLogger = nil; self.fileLogger = nil;
}; };
@@ -111,18 +111,18 @@ static NSUInteger DDGetDefaultBufferSizeBytes() {
- (void)logMessage:(DDLogMessage *)logMessage { - (void)logMessage:(DDLogMessage *)logMessage {
// Don't need to check for isOnInternalLoggerQueue, -lt_dataForMessage: will do it for us. // Don't need to check for isOnInternalLoggerQueue, -lt_dataForMessage: will do it for us.
NSData *data = [_fileLogger lt_dataForMessage:logMessage]; __auto_type data = [_fileLogger lt_dataForMessage:logMessage];
if (data.length == 0) { if (data.length == 0) {
return; return;
} }
[data enumerateByteRangesUsingBlock:^(const void * __nonnull bytes, NSRange byteRange, BOOL * __nonnull __unused stop) { [data enumerateByteRangesUsingBlock:^(const void * __nonnull bytes, NSRange byteRange, BOOL * __nonnull __unused stop) {
NSUInteger bytesLength = byteRange.length; __auto_type bytesLength = byteRange.length;
#ifdef NS_BLOCK_ASSERTIONS #ifdef NS_BLOCK_ASSERTIONS
__unused __unused
#endif #endif
NSInteger written = [_buffer write:bytes maxLength:bytesLength]; __auto_type written = [_buffer write:bytes maxLength:bytesLength];
NSAssert(written > 0 && (NSUInteger)written == bytesLength, @"Failed to write to memory buffer."); NSAssert(written > 0 && (NSUInteger)written == bytesLength, @"Failed to write to memory buffer.");
_currentBufferSizeBytes += bytesLength; _currentBufferSizeBytes += bytesLength;
@@ -137,7 +137,7 @@ static NSUInteger DDGetDefaultBufferSizeBytes() {
// This method is public. // This method is public.
// We need to execute the rolling on our logging thread/queue. // We need to execute the rolling on our logging thread/queue.
dispatch_block_t block = ^{ __auto_type block = ^{
@autoreleasepool { @autoreleasepool {
[self lt_sendBufferedDataToFileLogger]; [self lt_sendBufferedDataToFileLogger];
[self.fileLogger flush]; [self.fileLogger flush];
@@ -150,10 +150,8 @@ static NSUInteger DDGetDefaultBufferSizeBytes() {
if ([self.fileLogger isOnInternalLoggerQueue]) { if ([self.fileLogger isOnInternalLoggerQueue]) {
block(); block();
} else { } else {
dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
NSAssert(![self.fileLogger isOnGlobalLoggingQueue], @"Core architecture requirement failure"); NSAssert(![self.fileLogger isOnGlobalLoggingQueue], @"Core architecture requirement failure");
dispatch_sync(DDLog.loggingQueue, ^{
dispatch_sync(globalLoggingQueue, ^{
dispatch_sync(self.fileLogger.loggerQueue, block); dispatch_sync(self.fileLogger.loggerQueue, block);
}); });
} }

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -45,11 +45,11 @@
#pragma mark Processing #pragma mark Processing
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { - (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
__block NSString *line = logMessage->_message; __block __auto_type line = logMessage->_message;
dispatch_sync(_queue, ^{ dispatch_sync(_queue, ^{
for (id<DDLogFormatter> formatter in self->_formatters) { for (id<DDLogFormatter> formatter in self->_formatters) {
DDLogMessage *message = [self logMessageForLine:line originalMessage:logMessage]; __auto_type message = [self logMessageForLine:line originalMessage:logMessage];
line = [formatter formatLogMessage:message]; line = [formatter formatLogMessage:message];
if (!line) { if (!line) {
@@ -63,7 +63,6 @@
- (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message { - (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message {
DDLogMessage *newMessage = [message copy]; DDLogMessage *newMessage = [message copy];
newMessage->_message = line; newMessage->_message = line;
return newMessage; return newMessage;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -22,7 +22,7 @@
DDLogError(@"%@", description); \ DDLogError(@"%@", description); \
NSAssert(NO, @"%@", description); \ NSAssert(NO, @"%@", description); \
} }
#define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition) #define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %@", @(#condition))
/** /**
* Analog to `DDAssertionFailure` from DDAssert.swift for use in Objective C * Analog to `DDAssertionFailure` from DDAssert.swift for use in Objective C

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -48,6 +48,41 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
#pragma mark - #pragma mark -
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// The serializer is responsible for turning a log message into binary for writing into a file.
/// It allows storing log messages in a non-text format.
/// The serialier should not be used for filtering or formatting messages!
/// Also, it must be fast!
@protocol DDFileLogMessageSerializer <NSObject>
@required
/// Returns the binary representation of the message.
/// - Parameter message: The formatted log message to serialize.
//
/// Returns the binary representation of the message.
/// - Parameters:
/// - string: The string to serialize. Usually, this is the formatted message, but it can also be e.g. a log file header.
/// - message: The message which represents the `string`. This is null, if `string` is e.g. a log file header.
/// - Note: The `message` parameter should not be used for formatting! It should simply be used to extract the necessary metadata for serializing.
- (NSData *)dataForString:(NSString *)string
originatingFromMessage:(nullable DDLogMessage *)message NS_SWIFT_NAME(dataForString(_:originatingFrom:));
@end
/// The (default) plain text message serializer.
@interface DDFileLogPlainTextMessageSerializer : NSObject <DDFileLogMessageSerializer>
- (instancetype)init;
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@class DDFileLogger;
/** /**
* The LogFileManager protocol is designed to allow you to control all aspects of your log files. * The LogFileManager protocol is designed to allow you to control all aspects of your log files.
* *
@@ -152,30 +187,49 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
@optional @optional
// Private methods (only to be used by DDFileLogger) /// The log message serializer.
/** @property (nonatomic, readonly, strong) id<DDFileLogMessageSerializer> logMessageSerializer;
* Creates a new log file ignoring any errors. Deprecated in favor of `-createNewLogFileWithError:`.
* Will only be called if `-createNewLogFileWithError:` is not implemented.
**/
- (nullable NSString *)createNewLogFile __attribute__((deprecated("Use -createNewLogFileWithError:"))) NS_SWIFT_UNAVAILABLE("Use -createNewLogFileWithError:");
// Notifications from DDFileLogger /// The file manager to use. Defaults to `[NSFileManager defaultManager]`.
@property (nonatomic, readonly, strong) NSFileManager *fileManager;
/// Whether the log file should be locked by the file logger before writing to it (and unlocked after).
/// - Parameter logFilePath: The path to the log file for which to decide locking.
/// - Remark: Logging from multiple processes (e.g. an app extensions) to the same log file without file locking will result in interleaved and possibly even overwritten log messages.
/// Without locking, the resulting logfile could be described as "best effort" and might become corrupted.
/// The downside of locking is that if the process holds the file lock when it gets suspended by the system, the system will kill the process.
/// This could happen by inproper handling of app suspension (e.g. not properly calling `+[DDLog flushLog]` and waiting for its completion before suspension).
/// Regardless of locking, you should always call `+[DDLog flushLog]` before your app gets suspended or terminated to make sure every log message makes it to your disk.
- (BOOL)shouldLockLogFile:(NSString *)logFilePath;
/// Manually perform a cleanup of the log files managed by this manager.
/// This can be called from any queue!
- (BOOL)cleanupLogFilesWithError:(NSError **)error;
// MARK: Private methods (only to be used by DDFileLogger)
// MARK: Notifications from DDFileLogger
/// Called when the log file manager was added to a file logger.
/// This should be used to make the manager "active" - like starting internal timers etc.
/// Executed on global queue with default priority.
/// - Parameter fileLogger: The file logger this manager was added to.
/// - Important: The manager **must not** keep a strong reference to `fileLogger` or a retain cycle will be created!
- (void)didAddToFileLogger:(DDFileLogger *)fileLogger;
/// Called when a log file was archived. Executed on global queue with default priority. /// Called when a log file was archived. Executed on global queue with default priority.
/// @param logFilePath The path to the log file that was archived. /// @param logFilePath The path to the log file that was archived.
/// @param wasRolled Whether or not the archiving happend after rolling the log file. /// @param wasRolled Whether or not the archiving happend after rolling the log file.
- (void)didArchiveLogFile:(NSString *)logFilePath wasRolled:(BOOL)wasRolled NS_SWIFT_NAME(didArchiveLogFile(atPath:wasRolled:)); - (void)didArchiveLogFile:(NSString *)logFilePath wasRolled:(BOOL)wasRolled NS_SWIFT_NAME(didArchiveLogFile(atPath:wasRolled:));
// Deprecated APIs // MARK: Deprecated APIs
/** /// Creates a new log file ignoring any errors. Deprecated in favor of `-createNewLogFileWithError:`.
* Called when a log file was archived. Executed on global queue with default priority. /// Will only be called if `-createNewLogFileWithError:` is not implemented.
*/ - (nullable NSString *)createNewLogFile __attribute__((deprecated("Use -createNewLogFileWithError:"))) NS_SWIFT_UNAVAILABLE("Use -createNewLogFileWithError:");
/// Called when a log file was archived. Executed on global queue with default priority.
- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:"))); - (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:")));
/** /// Called when the roll action was executed and the log was archived. Executed on global queue with default priority.
* Called when the roll action was executed and the log was archived.
* Executed on global queue with default priority.
*/
- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:"))); - (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:")));
@end @end
@@ -199,11 +253,6 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
**/ **/
@interface DDLogFileManagerDefault : NSObject <DDLogFileManager> @interface DDLogFileManagerDefault : NSObject <DDLogFileManager>
/**
* Default initializer
*/
- (instancetype)init;
/** /**
* If logDirectory is not specified, then a folder called "Logs" is created in the app's cache directory. * If logDirectory is not specified, then a folder called "Logs" is created in the app's cache directory.
* While running on the simulator, the "Logs" folder is located in the library temporary directory. * While running on the simulator, the "Logs" folder is located in the library temporary directory.
@@ -226,6 +275,9 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel; defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel;
#endif #endif
/// Convenience initializer.
- (instancetype)init;
/* /*
* Methods to override. * Methods to override.
* *
@@ -276,6 +328,12 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
**/ **/
@property (readonly, copy, nullable) NSString *logFileHeader; @property (readonly, copy, nullable) NSString *logFileHeader;
/// The log message serializer.
@property (nonatomic, strong) id<DDFileLogMessageSerializer> logMessageSerializer;
/// The file manager to use. Defaults to `[NSFileManager defaultManager]`.
@property (nonatomic, strong) NSFileManager *fileManager;
/* Inherited from DDLogFileManager protocol: /* Inherited from DDLogFileManager protocol:
@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles; @property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
@@ -310,16 +368,12 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
**/ **/
@interface DDLogFileFormatterDefault : NSObject <DDLogFormatter> @interface DDLogFileFormatterDefault : NSObject <DDLogFormatter>
/** /// Designated initializer, requires a date formatter
* Default initializer
*/
- (instancetype)init;
/**
* Designated initializer, requires a date formatter
*/
- (instancetype)initWithDateFormatter:(nullable NSDateFormatter *)dateFormatter NS_DESIGNATED_INITIALIZER; - (instancetype)initWithDateFormatter:(nullable NSDateFormatter *)dateFormatter NS_DESIGNATED_INITIALIZER;
/// Convenience initializer
- (instancetype)init;
@end @end
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -507,12 +561,18 @@ extern unsigned long long const kDDDefaultLogFilesDiskQuota;
@property (nonatomic, readonly) NSTimeInterval age; @property (nonatomic, readonly) NSTimeInterval age;
@property (nonatomic, readonly) BOOL isSymlink;
@property (nonatomic, readwrite) BOOL isArchived; @property (nonatomic, readwrite) BOOL isArchived;
+ (nullable instancetype)logFileWithPath:(nullable NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)"); + (nullable instancetype)logFileWithPath:(nullable NSString *)filePath
__attribute__((deprecated("Check file path for nil and pass it to the initializer instead")))
NS_SWIFT_UNAVAILABLE("Use init(filePath:)");
- (instancetype)init NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER; - (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER;
// TODO: This should really become the designated initializer.
- (instancetype)initWithFilePath:(NSString *)filePath fileManager:(NSFileManager *)fileManager;
- (void)reset; - (void)reset;
- (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:)); - (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:));

View File

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

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -207,6 +207,20 @@ FOUNDATION_EXTERN NSString * __nullable DDExtractFileNameWithoutExtension(const
**/ **/
#define THIS_METHOD NSStringFromSelector(_cmd) #define THIS_METHOD NSStringFromSelector(_cmd)
/**
* Makes a declaration "Sendable" in Swift (if supported by the compiler).
*/
#ifndef DD_SENDABLE
#ifdef __has_attribute
#if __has_attribute(swift_attr)
#define DD_SENDABLE __attribute__((swift_attr("@Sendable")))
#endif
#endif
#endif
#ifndef DD_SENDABLE
#define DD_SENDABLE
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - #pragma mark -
@@ -216,6 +230,7 @@ FOUNDATION_EXTERN NSString * __nullable DDExtractFileNameWithoutExtension(const
* The main class, exposes all logging mechanisms, loggers, ... * The main class, exposes all logging mechanisms, loggers, ...
* For most of the users, this class is hidden behind the logging functions like `DDLogInfo` * For most of the users, this class is hidden behind the logging functions like `DDLogInfo`
*/ */
DD_SENDABLE
@interface DDLog : NSObject @interface DDLog : NSObject
/** /**
@@ -770,11 +785,13 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
* The `DDLogMessage` class encapsulates information about the log message. * The `DDLogMessage` class encapsulates information about the log message.
* If you write custom loggers or formatters, you will be dealing with objects of this class. * If you write custom loggers or formatters, you will be dealing with objects of this class.
**/ **/
DD_SENDABLE
@interface DDLogMessage : NSObject <NSCopying> @interface DDLogMessage : NSObject <NSCopying>
{ {
// Direct accessors to be used only for performance // Direct accessors to be used only for performance
@public @public
NSString *_message; NSString *_message;
NSString *_messageFormat;
DDLogLevel _level; DDLogLevel _level;
DDLogFlag _flag; DDLogFlag _flag;
NSInteger _context; NSInteger _context;
@@ -782,9 +799,9 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
NSString *_fileName; NSString *_fileName;
NSString *_function; NSString *_function;
NSUInteger _line; NSUInteger _line;
#if DD_LEGACY_MESSAGE_TAG #if DD_LEGACY_MESSAGE_TAG
id _tag __attribute__((deprecated("Use _representedObject instead", "_representedObject")));; id _tag __attribute__((deprecated("Use _representedObject instead", "_representedObject")));
#endif #endif
id _representedObject; id _representedObject;
DDLogMessageOptions _options; DDLogMessageOptions _options;
NSDate * _timestamp; NSDate * _timestamp;
@@ -813,6 +830,64 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
* so it makes sense to optimize and skip the unnecessary allocations. * so it makes sense to optimize and skip the unnecessary allocations.
* However, if you need them to be copied you may use the options parameter to specify this. * However, if you need them to be copied you may use the options parameter to specify this.
* *
* @param messageFormat the message format
* @param message the formatted message
* @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 options a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
* @param timestamp the log timestamp
*
* @return a new instance of a log message model object
*/
- (instancetype)initWithFormat:(NSString *)messageFormat
formatted:(NSString *)message
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(NSString *)file
function:(nullable NSString *)function
line:(NSUInteger)line
tag:(nullable id)tag
options:(DDLogMessageOptions)options
timestamp:(nullable NSDate *)timestamp NS_DESIGNATED_INITIALIZER;
/**
* Convenience initializer taking a `va_list` as arguments to create the formatted message.
*
* @param messageFormat the message format
* @param messageArgs the message arguments.
* @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 options a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction.
* @param timestamp the log timestamp
*
* @return a new instance of a log message model object
*/
- (instancetype)initWithFormat:(NSString *)messageFormat
args:(va_list)messageArgs
level:(DDLogLevel)level
flag:(DDLogFlag)flag
context:(NSInteger)context
file:(NSString *)file
function:(nullable NSString *)function
line:(NSUInteger)line
tag:(nullable id)tag
options:(DDLogMessageOptions)options
timestamp:(nullable NSDate *)timestamp;
/**
* Deprecated initialier. See initWithFormat:args:formatted:level:flag:context:file:function:line:tag:options:timestamp:.
*
* @param message the message * @param message the message
* @param level the log level * @param level the log level
* @param flag the log flag * @param flag the log flag
@@ -835,16 +910,21 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
line:(NSUInteger)line line:(NSUInteger)line
tag:(nullable id)tag tag:(nullable id)tag
options:(DDLogMessageOptions)options options:(DDLogMessageOptions)options
timestamp:(nullable NSDate *)timestamp NS_DESIGNATED_INITIALIZER; timestamp:(nullable NSDate *)timestamp
__attribute__((deprecated("Use initializer taking unformatted message and args instead", "initWithFormat:formatted:level:flag:context:file:function:line:tag:options:timestamp:")));
/** /**
* Read-only properties * Read-only properties
**/ **/
/** /**
* The log message * The log message.
*/ */
@property (readonly, nonatomic) NSString *message; @property (readonly, nonatomic) NSString *message;
/**
* The message format. When the deprecated initializer is used, this might be the same as `message`.
*/
@property (readonly, nonatomic) NSString *messageFormat;
@property (readonly, nonatomic) DDLogLevel level; @property (readonly, nonatomic) DDLogLevel level;
@property (readonly, nonatomic) DDLogFlag flag; @property (readonly, nonatomic) DDLogFlag flag;
@property (readonly, nonatomic) NSInteger context; @property (readonly, nonatomic) NSInteger context;
@@ -889,7 +969,7 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
{ {
// Direct accessors to be used only for performance // Direct accessors to be used only for performance
@public @public
id <DDLogFormatter> _logFormatter; _Nullable id <DDLogFormatter> _logFormatter;
dispatch_queue_t _loggerQueue; dispatch_queue_t _loggerQueue;
} }
@@ -901,7 +981,7 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
/** /**
* Return YES if the current logger uses a global queue for logging * Return YES if the current logger uses a global queue for logging
*/ */
@property (nonatomic, readonly, getter=isOnGlobalLoggingQueue) BOOL onGlobalLoggingQueue; @property (nonatomic, readonly, getter=isOnGlobalLoggingQueue) BOOL onGlobalLoggingQueue;
/** /**
* Return YES if the current logger uses the internal designated queue for logging * Return YES if the current logger uses the internal designated queue for logging
@@ -910,10 +990,27 @@ typedef NS_OPTIONS(NSInteger, DDLogMessageOptions){
@end @end
#define _DDAbstractLoggerSelectorMessage(msg) [NSStringFromSelector(_cmd) stringByAppendingString:@" " msg]
// Note: we do not wrap these in any do {...} while 0 construct, because NSAssert does that for us.
#define DDAbstractLoggerAssertOnGlobalLoggingQueue() \
NSAssert([self isOnGlobalLoggingQueue], _DDAbstractLoggerSelectorMessage("must only be called on the global logging queue!"))
#define DDAbstractLoggerAssertOnInternalLoggerQueue() \
NSAssert([self isOnInternalLoggerQueue], _DDAbstractLoggerSelectorMessage("must only be called on the internal logger queue!"))
#define DDAbstractLoggerAssertNotOnGlobalLoggingQueue() \
NSAssert(![self isOnGlobalLoggingQueue], _DDAbstractLoggerSelectorMessage("must not be called on the global logging queue!"))
#define DDAbstractLoggerAssertNotOnInternalLoggerQueue() \
NSAssert(![self isOnGlobalLoggingQueue], _DDAbstractLoggerSelectorMessage("must not be called on the internal logger queue!"))
#define DDAbstractLoggerAssertLockedPropertyAccess() \
DDAbstractLoggerAssertNotOnGlobalLoggingQueue(); \
NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.")
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - #pragma mark -
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DD_SENDABLE
@interface DDLoggerInformation : NSObject @interface DDLoggerInformation : NSObject
@property (nonatomic, readonly) id <DDLogger> logger; @property (nonatomic, readonly) id <DDLogger> logger;

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -80,10 +80,10 @@
* We also define shorthand versions for asynchronous and synchronous logging. * We also define shorthand versions for asynchronous and synchronous logging.
**/ **/
#define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \ #define LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
do { if((lvl & flg) != 0) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0) do { if(((NSUInteger)lvl & (NSUInteger)flg) != 0) 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, ...) \ #define LOG_MAYBE_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ...) \
do { if((lvl & flg) != 0) LOG_MACRO_TO_DDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0) do { if(((NSUInteger)lvl & (NSUInteger)flg) != 0) 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. * Ready to use log macros with no context or tag.

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -13,7 +13,9 @@
// to endorse or promote products derived from this software without specific // to endorse or promote products derived from this software without specific
// prior written permission of Deusty, LLC. // prior written permission of Deusty, LLC.
#import <TargetConditionals.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <os/log.h>
// Disable legacy macros // Disable legacy macros
#ifndef DD_LEGACY_MACROS #ifndef DD_LEGACY_MACROS
@@ -24,31 +26,79 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
/** /// Describes a type that maps CocoaLumberjack log levels to os\_log levels (`os_log_type_t`).
* This class provides a logger for the Apple os_log facility.
**/
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0)) API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
DD_SENDABLE
@protocol DDOSLogLevelMapper <NSObject>
/// Maps the given `DDLogFlag` to a `os_log_type_t`.
/// - Parameter logFlag: `DDLogFlag` for which to return the os log type.
- (os_log_type_t)osLogTypeForLogFlag:(DDLogFlag)logFlag;
@end
/// The default os\_log level mapper.
/// Uses the following mapping:
/// - `DDLogFlagError` -> `OS_LOG_TYPE_ERROR`
/// - `DDLogFlagWarning` -> `OS_LOG_TYPE_ERROR`
/// - `DDLogFlagInfo` -> `OS_LOG_TYPE_INFO`
/// - `DDLogFlagDebug` -> `OS_LOG_TYPE_DEBUG`
/// - `DDLogFlagVerbose` -> `OS_LOG_TYPE_DEBUG`
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
DD_SENDABLE
@interface DDOSLogLevelMapperDefault : NSObject <DDOSLogLevelMapper>
- (instancetype)init NS_DESIGNATED_INITIALIZER;
@end
#if TARGET_OS_SIMULATOR
/// An os\_log level mapper that works around the fact that `OS_LOG_TYPE_DEBUG` messages logged in the simulator do not show up in the Console.app.
/// Performs the same mapping as ``DDOSLogLevelMapperDefault``, except that `OS_LOG_TYPE_DEBUG` is raised to `OS_LOG_TYPE_DEFAULT`.
/// See [this thread](https://developer.apple.com/forums/thread/82736?answerId=761544022#761544022) in the Apple Developer Forums.
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
DD_SENDABLE
@interface DDOSLogLevelMapperSimulatorConsoleAppWorkaround : DDOSLogLevelMapperDefault
@end
#endif
/// This class provides a logger for the Apple os\_log facility.
API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
DD_SENDABLE
@interface DDOSLogger : DDAbstractLogger <DDLogger> @interface DDOSLogger : DDAbstractLogger <DDLogger>
/** /// The shared instance using `OS_LOG_DEFAULT`.
* Singleton method
*
* @return the shared instance with OS_LOG_DEFAULT.
*/
@property (nonatomic, class, readonly, strong) DDOSLogger *sharedInstance; @property (nonatomic, class, readonly, strong) DDOSLogger *sharedInstance;
/** /// The log level mapper, that maps ``DDLogFlag``s to ``os_log_type_t`` for this logger.
Designated initializer @property (nonatomic, strong, readonly) id<DDOSLogLevelMapper> logLevelMapper;
@param subsystem Desired subsystem in log. E.g. "org.example" /// An initializer that in addition to subsystem and category also allows providing the log level mapper.
@param category Desired category in log. E.g. "Point of interests." /// @param subsystem Desired subsystem in log. E.g. "org.example"
@return New instance of DDOSLogger. /// @param category Desired category in log. E.g. "Point of interests."
/// @param logLevelMapper The log level mapper to use.
/// @discussion This method requires either both or no parameter to be set. Much like `(String, String)?` in Swift.
/// If both parameters are nil, this method will return a logger configured with `OS_LOG_DEFAULT`.
/// If both parameters are non-nil, it will return a logger configured with `os_log_create(subsystem, category)`
- (instancetype)initWithSubsystem:(nullable NSString *)subsystem
category:(nullable NSString *)category
logLevelMapper:(id<DDOSLogLevelMapper>)logLevelMapper NS_DESIGNATED_INITIALIZER;
@discussion This method requires either both or no parameter to be set. Much like `(String, String)?` in Swift. /// The designated initializer, using `DDOSLogLevelMapperDefault`.
If both parameters are nil, this method will return a logger configured with `OS_LOG_DEFAULT`. /// @param subsystem Desired subsystem in log. E.g. "org.example"
If both parameters are non-nil, it will return a logger configured with `os_log_create(subsystem, category)` /// @param category Desired category in log. E.g. "Point of interests."
*/ /// @discussion This method requires either both or no parameter to be set. Much like `(String, String)?` in Swift.
- (instancetype)initWithSubsystem:(nullable NSString *)subsystem category:(nullable NSString *)category NS_DESIGNATED_INITIALIZER; /// If both parameters are nil, this method will return a logger configured with `OS_LOG_DEFAULT`.
/// If both parameters are non-nil, it will return a logger configured with `os_log_create(subsystem, category)`.
- (instancetype)initWithSubsystem:(nullable NSString *)subsystem
category:(nullable NSString *)category;
/// Creates an instance that uses `OS_LOG_DEFAULT`.
/// @param logLevelMapper The log level mapper to use.
- (instancetype)initWithLogLevelMapper:(id<DDOSLogLevelMapper>)logLevelMapper;
/// Creates an instance that uses `OS_LOG_DEFAULT` and `DDOSLogLevelMapperDefault`.
- (instancetype)init;
@end @end

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -28,17 +28,17 @@
// iOS or tvOS or watchOS // iOS or tvOS or watchOS
#import <UIKit/UIColor.h> #import <UIKit/UIColor.h>
typedef UIColor DDColor; typedef UIColor DDColor;
static inline DDColor* _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];} static inline DDColor* _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithRed:(r/(CGFloat)255.0) green:(g/(CGFloat)255.0) blue:(b/(CGFloat)255.0) alpha:1.0];}
#elif defined(DD_CLI) || !__has_include(<AppKit/NSColor.h>) #elif defined(DD_CLI) || !__has_include(<AppKit/NSColor.h>)
// OS X CLI // OS X CLI
#import <CocoaLumberjack/CLIColor.h> #import <CocoaLumberjack/CLIColor.h>
typedef CLIColor DDColor; typedef CLIColor DDColor;
static inline DDColor* _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];} static inline DDColor* _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0];}
#else #else
// OS X with AppKit // OS X with AppKit
#import <AppKit/NSColor.h> #import <AppKit/NSColor.h>
typedef NSColor DDColor; typedef NSColor DDColor;
static inline DDColor * _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];} static inline DDColor * _Nonnull DDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [DDColor colorWithCalibratedRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0];}
#endif #endif
#pragma clang diagnostic pop #pragma clang diagnostic pop

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -13,71 +13,164 @@
// to endorse or promote products derived from this software without specific // to endorse or promote products derived from this software without specific
// prior written permission of Deusty, LLC. // prior written permission of Deusty, LLC.
@_exported import CocoaLumberjack @_exported public import CocoaLumberjack
#if SWIFT_PACKAGE #if SWIFT_PACKAGE
import CocoaLumberjackSwiftSupport public import CocoaLumberjackSwiftSupport
#endif #endif
extension DDLogFlag {
public static func from(_ logLevel: DDLogLevel) -> DDLogFlag {
return DDLogFlag(rawValue: logLevel.rawValue)
}
public init(_ logLevel: DDLogLevel) {
self = DDLogFlag(rawValue: logLevel.rawValue)
}
/// Returns the log level, or the lowest equivalent.
public func toLogLevel() -> DDLogLevel {
if let ourValid = DDLogLevel(rawValue: 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
} else {
return .off
}
}
}
}
/// The log level that can dynamically limit log messages (vs. the static DDDefaultLogLevel). This log level will only be checked, if the message passes the `DDDefaultLogLevel`.
public var dynamicLogLevel = DDLogLevel.all
/// Resets the `dynamicLogLevel` to `.all`.
/// - SeeAlso: `dynamicLogLevel`
@inlinable @inlinable
public func resetDynamicLogLevel() { public func _DDLogMessage(_ messageFormat: @autoclosure () -> DDLogMessageFormat,
dynamicLogLevel = .all level: DDLogLevel,
} flag: DDLogFlag,
context: Int,
@available(*, deprecated, message: "Please use dynamicLogLevel", renamed: "dynamicLogLevel") file: StaticString,
public var defaultDebugLevel: DDLogLevel { function: StaticString,
get { line: UInt,
return dynamicLogLevel tag: Any?,
asynchronous: Bool?,
ddlog: DDLog) {
// The `dynamicLogLevel` will always be checked here (instead of being passed in).
// We cannot "mix" it with the `DDDefaultLogLevel`, because otherwise the compiler won't strip strings that are not logged.
#if compiler(>=6.2)
if unsafe level.rawValue & flag.rawValue != 0 && dynamicLogLevel.rawValue & flag.rawValue != 0 {
let logMessage = DDLogMessage(messageFormat(),
level: level,
flag: flag,
context: context,
file: file,
function: function,
line: line,
tag: tag)
unsafe ddlog.log(asynchronous: asynchronous ?? asyncLoggingEnabled, message: logMessage)
} }
set { #else
dynamicLogLevel = newValue if level.rawValue & flag.rawValue != 0 && dynamicLogLevel.rawValue & flag.rawValue != 0 {
let logMessage = DDLogMessage(messageFormat(),
level: level,
flag: flag,
context: context,
file: file,
function: function,
line: line,
tag: tag)
ddlog.log(asynchronous: asynchronous ?? asyncLoggingEnabled, message: logMessage)
} }
#endif
} }
@available(*, deprecated, message: "Please use resetDynamicLogLevel", renamed: "resetDynamicLogLevel")
public func resetDefaultDebugLevel() {
resetDynamicLogLevel()
}
/// If `true`, all logs (except errors) are logged asynchronously by default.
public var asyncLoggingEnabled = true
@inlinable @inlinable
public func DDLogDebug(_ message: @autoclosure () -> DDLogMessageFormat,
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous: Bool? = nil,
ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(),
level: level,
flag: .debug,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: asynchronous,
ddlog: ddlog)
}
@inlinable
public func DDLogInfo(_ message: @autoclosure () -> DDLogMessageFormat,
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous: Bool? = nil,
ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(),
level: level,
flag: .info,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: asynchronous,
ddlog: ddlog)
}
@inlinable
public func DDLogWarn(_ message: @autoclosure () -> DDLogMessageFormat,
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous: Bool? = nil,
ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(),
level: level,
flag: .warning,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: asynchronous,
ddlog: ddlog)
}
@inlinable
public func DDLogVerbose(_ message: @autoclosure () -> DDLogMessageFormat,
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous: Bool? = nil,
ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(),
level: level,
flag: .verbose,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: asynchronous,
ddlog: ddlog)
}
@inlinable
public func DDLogError(_ message: @autoclosure () -> DDLogMessageFormat,
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous: Bool? = nil,
ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(),
level: level,
flag: .error,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: asynchronous ?? false,
ddlog: ddlog)
}
@available(*, deprecated, message: "Use an interpolated DDLogMessageFormat instead")
@inlinable
@_disfavoredOverload
public func _DDLogMessage(_ message: @autoclosure () -> Any, public func _DDLogMessage(_ message: @autoclosure () -> Any,
level: DDLogLevel, level: DDLogLevel,
flag: DDLogFlag, flag: DDLogFlag,
@@ -86,27 +179,25 @@ public func _DDLogMessage(_ message: @autoclosure () -> Any,
function: StaticString, function: StaticString,
line: UInt, line: UInt,
tag: Any?, tag: Any?,
asynchronous: Bool, asynchronous: Bool?,
ddlog: DDLog) { ddlog: DDLog) {
// The `dynamicLogLevel` will always be checked here (instead of being passed in). // This will lead to `messageFormat` and `message` being equal on DDLogMessage,
// We cannot "mix" it with the `DDDefaultLogLevel`, because otherwise the compiler won't strip strings that are not logged. // which is what the legacy initializer of DDLogMessage does as well.
if level.rawValue & flag.rawValue != 0 && dynamicLogLevel.rawValue & flag.rawValue != 0 { _DDLogMessage(.init(_formattedMessage: String(describing: message())),
// Tell the DDLogMessage constructor to copy the C strings that get passed to it. level: level,
let logMessage = DDLogMessage(message: String(describing: message()), flag: flag,
level: level, context: context,
flag: flag, file: file,
context: context, function: function,
file: String(describing: file), line: line,
function: String(describing: function), tag: tag,
line: line, asynchronous: asynchronous,
tag: tag, ddlog: ddlog)
options: [.copyFile, .copyFunction],
timestamp: nil)
ddlog.log(asynchronous: asynchronous, message: logMessage)
}
} }
@available(*, deprecated, message: "Use an interpolated DDLogMessageFormat instead")
@inlinable @inlinable
@_disfavoredOverload
public func DDLogDebug(_ message: @autoclosure () -> Any, public func DDLogDebug(_ message: @autoclosure () -> Any,
level: DDLogLevel = DDDefaultLogLevel, level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0, context: Int = 0,
@@ -114,12 +205,23 @@ public func DDLogDebug(_ message: @autoclosure () -> Any,
function: StaticString = #function, function: StaticString = #function,
line: UInt = #line, line: UInt = #line,
tag: Any? = nil, tag: Any? = nil,
asynchronous async: Bool = asyncLoggingEnabled, asynchronous async: Bool? = nil,
ddlog: DDLog = .sharedInstance) { ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(), level: level, flag: .debug, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) _DDLogMessage(message(),
level: level,
flag: .debug,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
} }
@available(*, deprecated, message: "Use an interpolated DDLogMessageFormat instead")
@inlinable @inlinable
@_disfavoredOverload
public func DDLogInfo(_ message: @autoclosure () -> Any, public func DDLogInfo(_ message: @autoclosure () -> Any,
level: DDLogLevel = DDDefaultLogLevel, level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0, context: Int = 0,
@@ -127,12 +229,23 @@ public func DDLogInfo(_ message: @autoclosure () -> Any,
function: StaticString = #function, function: StaticString = #function,
line: UInt = #line, line: UInt = #line,
tag: Any? = nil, tag: Any? = nil,
asynchronous async: Bool = asyncLoggingEnabled, asynchronous async: Bool? = nil,
ddlog: DDLog = .sharedInstance) { ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(), level: level, flag: .info, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) _DDLogMessage(message(),
level: level,
flag: .info,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
} }
@available(*, deprecated, message: "Use an interpolated DDLogMessageFormat instead")
@inlinable @inlinable
@_disfavoredOverload
public func DDLogWarn(_ message: @autoclosure () -> Any, public func DDLogWarn(_ message: @autoclosure () -> Any,
level: DDLogLevel = DDDefaultLogLevel, level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0, context: Int = 0,
@@ -140,12 +253,23 @@ public func DDLogWarn(_ message: @autoclosure () -> Any,
function: StaticString = #function, function: StaticString = #function,
line: UInt = #line, line: UInt = #line,
tag: Any? = nil, tag: Any? = nil,
asynchronous async: Bool = asyncLoggingEnabled, asynchronous async: Bool? = nil,
ddlog: DDLog = .sharedInstance) { ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(), level: level, flag: .warning, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) _DDLogMessage(message(),
level: level,
flag: .warning,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
} }
@available(*, deprecated, message: "Use an interpolated DDLogMessageFormat instead")
@inlinable @inlinable
@_disfavoredOverload
public func DDLogVerbose(_ message: @autoclosure () -> Any, public func DDLogVerbose(_ message: @autoclosure () -> Any,
level: DDLogLevel = DDDefaultLogLevel, level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0, context: Int = 0,
@@ -153,12 +277,23 @@ public func DDLogVerbose(_ message: @autoclosure () -> Any,
function: StaticString = #function, function: StaticString = #function,
line: UInt = #line, line: UInt = #line,
tag: Any? = nil, tag: Any? = nil,
asynchronous async: Bool = asyncLoggingEnabled, asynchronous async: Bool? = nil,
ddlog: DDLog = .sharedInstance) { ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(), level: level, flag: .verbose, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) _DDLogMessage(message(),
level: level,
flag: .verbose,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
} }
@available(*, deprecated, message: "Use an interpolated DDLogMessageFormat instead")
@inlinable @inlinable
@_disfavoredOverload
public func DDLogError(_ message: @autoclosure () -> Any, public func DDLogError(_ message: @autoclosure () -> Any,
level: DDLogLevel = DDDefaultLogLevel, level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0, context: Int = 0,
@@ -166,28 +301,16 @@ public func DDLogError(_ message: @autoclosure () -> Any,
function: StaticString = #function, function: StaticString = #function,
line: UInt = #line, line: UInt = #line,
tag: Any? = nil, tag: Any? = nil,
asynchronous async: Bool = false, asynchronous async: Bool? = nil,
ddlog: DDLog = .sharedInstance) { ddlog: DDLog = .sharedInstance) {
_DDLogMessage(message(), level: level, flag: .error, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) _DDLogMessage(message(),
} level: level,
flag: .error,
/// Returns a String of the current filename, without full path or extension. context: context,
/// file: file,
/// Analogous to the C preprocessor macro `THIS_FILE`. function: function,
public func currentFileName(_ fileName: StaticString = #file) -> String { line: line,
var str = String(describing: fileName) tag: tag,
if let idx = str.range(of: "/", options: .backwards)?.upperBound { asynchronous: async ?? false,
str = String(str[idx...]) ddlog: ddlog)
}
if let idx = str.range(of: ".", options: .backwards)?.lowerBound {
str = String(str[..<idx])
}
return str
}
// swiftlint:disable identifier_name
// swiftlint doesn't like func names that begin with a capital letter - deprecated
@available(*, deprecated, message: "Please use currentFileName", renamed: "currentFileName")
public func CurrentFileName(_ fileName: StaticString = #file) -> String {
return currentFileName(fileName)
} }

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -14,8 +14,8 @@
// prior written permission of Deusty, LLC. // prior written permission of Deusty, LLC.
#if SWIFT_PACKAGE #if SWIFT_PACKAGE
import CocoaLumberjack public import CocoaLumberjack
import CocoaLumberjackSwiftSupport public import CocoaLumberjackSwiftSupport
#endif #endif
/** /**
@@ -29,9 +29,91 @@ import CocoaLumberjackSwiftSupport
* The default is an empty string. * The default is an empty string.
*/ */
@inlinable @inlinable
public func DDAssert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = "", level: DDLogLevel = DDDefaultLogLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = false, ddlog: DDLog = DDLog.sharedInstance) { public func DDAssert(_ condition: @autoclosure () -> Bool,
_ message: @autoclosure () -> DDLogMessageFormat = "",
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous async: Bool? = nil,
ddlog: DDLog = DDLog.sharedInstance) {
if !condition() { if !condition() {
DDLogError(message(), level: level, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) DDLogError(message(),
level: level,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
Swift.assertionFailure(message().formatted, file: file, line: line)
}
}
/**
* Replacement for Swift's `assertionFailure` function that will output a log message even
* when assertions are disabled.
*
* - Parameters:
* - message: A string to log (using `DDLogError`). The default is an empty string.
*/
@inlinable
public func DDAssertionFailure(_ message: @autoclosure () -> DDLogMessageFormat = "",
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous async: Bool? = nil,
ddlog: DDLog = DDLog.sharedInstance) {
DDLogError(message(),
level: level,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
Swift.assertionFailure(message().formatted, file: file, line: line)
}
/**
* Replacement for Swift's `assert` function that will output a log message even when assertions
* are disabled.
*
* - Parameters:
* - condition: The condition to test. Unlike `Swift.assert`, `condition` is always evaluated,
* even when assertions are disabled.
* - message: A string to log (using `DDLogError`) if `condition` evaluates to `false`.
* The default is an empty string.
*/
@inlinable
@available(*, deprecated, message: "Use an interpolated message.")
public func DDAssert(_ condition: @autoclosure () -> Bool,
_ message: @autoclosure () -> String = "",
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous async: Bool? = nil,
ddlog: DDLog = DDLog.sharedInstance) {
if !condition() {
DDLogError(message(),
level: level,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
Swift.assertionFailure(message(), file: file, line: line) Swift.assertionFailure(message(), file: file, line: line)
} }
} }
@@ -44,7 +126,24 @@ public func DDAssert(_ condition: @autoclosure () -> Bool, _ message: @autoclosu
* - message: A string to log (using `DDLogError`). The default is an empty string. * - message: A string to log (using `DDLogError`). The default is an empty string.
*/ */
@inlinable @inlinable
public func DDAssertionFailure(_ message: @autoclosure () -> String = "", level: DDLogLevel = DDDefaultLogLevel, context: Int = 0, file: StaticString = #file, function: StaticString = #function, line: UInt = #line, tag: Any? = nil, asynchronous async: Bool = false, ddlog: DDLog = DDLog.sharedInstance) { @available(*, deprecated, message: "Use an interpolated message.")
DDLogError(message(), level: level, context: context, file: file, function: function, line: line, tag: tag, asynchronous: async, ddlog: ddlog) public func DDAssertionFailure(_ message: @autoclosure () -> String = "",
level: DDLogLevel = DDDefaultLogLevel,
context: Int = 0,
file: StaticString = #file,
function: StaticString = #function,
line: UInt = #line,
tag: Any? = nil,
asynchronous async: Bool? = nil,
ddlog: DDLog = DDLog.sharedInstance) {
DDLogError(message(),
level: level,
context: context,
file: file,
function: function,
line: line,
tag: tag,
asynchronous: async,
ddlog: ddlog)
Swift.assertionFailure(message(), file: file, line: line) Swift.assertionFailure(message(), file: file, line: line)
} }

View File

@@ -1,6 +1,6 @@
// Software License Agreement (BSD License) // Software License Agreement (BSD License)
// //
// Copyright (c) 2010-2021, Deusty, LLC // Copyright (c) 2010-2026, Deusty, LLC
// All rights reserved. // All rights reserved.
// //
// Redistribution and use of this software in source and binary forms, // Redistribution and use of this software in source and binary forms,
@@ -15,15 +15,76 @@
#if arch(arm64) || arch(x86_64) #if arch(arm64) || arch(x86_64)
#if canImport(Combine) #if canImport(Combine)
import Combine public import Combine
#if SWIFT_PACKAGE #if SWIFT_PACKAGE
import CocoaLumberjack public import CocoaLumberjack
import CocoaLumberjackSwiftSupport
#endif #endif
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension DDLog { extension DDLog {
// MARK: - Subscription
private final class Subscription<S: Subscriber>: NSObject, DDLogger, Combine.Subscription
where S.Input == DDLogMessage
{ // swiftlint:disable:this opening_brace
private var subscriber: S?
private weak var log: DDLog?
/// Not used but ``DDLogger`` requires it.
/// The preferred way to achieve this is to use the `map` Combine operator of the publisher.
/// Example:
/// ```
/// DDLog.sharedInstance.messagePublisher()
/// .map { message in /* format message */ }
/// .sink(receiveValue: { formattedMessage in /* process formattedMessage */ })
/// ```
var logFormatter: (any DDLogFormatter)?
init(log: DDLog, with logLevel: DDLogLevel, subscriber: S) {
self.subscriber = subscriber
self.log = log
super.init()
log.add(self, with: logLevel)
}
func request(_ demand: Subscribers.Demand) {
// The log messages are endless until canceled, so we won't do any demand management.
// Combine operators can be used to deal with it as needed.
}
func cancel() {
log?.remove(self)
subscriber = nil
}
func log(message logMessage: DDLogMessage) {
_ = subscriber?.receive(logMessage)
}
}
// MARK: - Publisher
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public struct MessagePublisher: Combine.Publisher {
public typealias Output = DDLogMessage
public typealias Failure = Never
private let log: DDLog
private let logLevel: DDLogLevel
public init(log: DDLog, with logLevel: DDLogLevel) {
self.log = log
self.logLevel = logLevel
}
public func receive<S>(subscriber: S)
where S: Subscriber, S.Failure == Failure, S.Input == Output
{ // swiftlint:disable:this opening_brace
let subscription = Subscription(log: log, with: logLevel, subscriber: subscriber)
subscriber.receive(subscription: subscription)
}
}
/** /**
* Creates a message publisher. * Creates a message publisher.
* *
@@ -40,73 +101,15 @@ extension DDLog {
* - Returns: A MessagePublisher that emits LogMessages filtered by the specified logLevel * - Returns: A MessagePublisher that emits LogMessages filtered by the specified logLevel
**/ **/
public func messagePublisher(with logLevel: DDLogLevel = .all) -> MessagePublisher { public func messagePublisher(with logLevel: DDLogLevel = .all) -> MessagePublisher {
return MessagePublisher(log: self, with: logLevel) MessagePublisher(log: self, with: logLevel)
}
// MARK: - MessagePublisher
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public struct MessagePublisher: Combine.Publisher {
public typealias Output = DDLogMessage
public typealias Failure = Never
private let log: DDLog
private let logLevel: DDLogLevel
public init(log: DDLog, with logLevel: DDLogLevel) {
self.log = log
self.logLevel = logLevel
}
public func receive<S>(subscriber: S) where S: Subscriber, S.Failure == Failure, S.Input == Output {
let subscription = Subscription(log: log, with: logLevel, subscriber: subscriber)
subscriber.receive(subscription: subscription)
}
}
// MARK: - Subscription
private final class Subscription<S: Subscriber>: NSObject, DDLogger, Combine.Subscription where S.Input == DDLogMessage {
private var subscriber: S?
private weak var log: DDLog?
//Not used but DDLogger requires it. The preferred way to achieve this is to use the `map()` Combine operator of the publisher.
//ie:
// DDLog.sharedInstance.messagePublisher()
// .map { [format log message] }
// .sink(receiveValue: { [process log message] })
//
var logFormatter: DDLogFormatter?
init(log: DDLog, with logLevel: DDLogLevel, subscriber: S) {
self.subscriber = subscriber
self.log = log
super.init()
log.add(self, with: logLevel)
}
func request(_ demand: Subscribers.Demand) {
//The log messages are endless until canceled, so we won't do any demand management.
//Combine operators can be used to deal with it as needed.
}
func cancel() {
log?.remove(self)
subscriber = nil
}
func log(message logMessage: DDLogMessage) {
_ = subscriber?.receive(logMessage)
}
} }
} }
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension Publisher where Output == DDLogMessage { extension Publisher where Output == DDLogMessage {
public func formatted(with formatter: DDLogFormatter) -> Publishers.CompactMap<Self, String> { public func formatted(with formatter: any DDLogFormatter) -> Publishers.CompactMap<Self, String> {
return compactMap { formatter.format(message: $0) } compactMap { formatter.format(message: $0) }
} }
} }
#endif #endif
#endif #endif

View File

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

View File

@@ -30,18 +30,13 @@
], ],
"vendored_frameworks": "SellyCloudSDK/sdk/*.{framework,xcframework}", "vendored_frameworks": "SellyCloudSDK/sdk/*.{framework,xcframework}",
"dependencies": { "dependencies": {
"CocoaLumberjack": [ "CocoaLumberjack": [],
"~>3.7.2"
],
"CocoaLumberjack/Swift": [], "CocoaLumberjack/Swift": [],
"ReactiveObjC": [], "ReactiveObjC": [],
"Reachability": [], "Reachability": [],
"YYModel": [], "YYModel": [],
"SSZipArchive": [], "SSZipArchive": [],
"SocketRocket": [], "SocketRocket": []
"Logboard": [
"~> 2.5.0"
]
}, },
"swift_version": "5.10" "swift_version": "5.10"
} }

View File

@@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2017, shogo4405
All rights reserved.
Redistribution and use 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.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,96 +0,0 @@
# Logboard
[![Release](https://img.shields.io/github/v/release/shogo4405/Logboard)](https://github.com/shogo4405/Logboard/releases/latest)
[![Platform Compatibility](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fshogo4405%2FLogboard%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/shogo4405/Logboard)
[![Swift Compatibility](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fshogo4405%2FLogboard%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/shogo4405/Logboard)
[![GitHub license](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://raw.githubusercontent.com/shogo4405/Logboard/master/LICENSE.md)
* Simple logging framework for your framework project.
* [API Documentation](https://shogo4405.github.io/Logboard/documentation/logboard/)
## Usage
```swift
let logger = LBLogger.with("identifier")
logger.level = .trace
logger.trace("trace")
logger.debug("debug")
logger.info("hoge")
logger.warn("sample")
logger.error("error")
```
## Requirements
|-|iOS|macOS|tvOS|watchOS|visionOS|Xcode|Swift|
|:----:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|
|2.5.0+|13.0+|10.15+|13.0+|6.0|-|15.3+|5.8|
|2.4.1+|12.0+|10.13+|12.0+|4.0|1.0+|15.0+|5.3|
## Installation
### CocoaPods
```rb
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
def import_pods
pod 'Logboard', '~> 2.4.1'
end
target 'Your Target' do
platform :ios, '12.0'
import_pods
end
```
### Carthage
```
github "shogo4405/Logboard" ~> 2.4.1
```
## Appenders
### ConsoleAppender
Use print function. You can see Xcode's console.
```swift
let logger = LBLogger.with("identifier")
let console = ConsoleAppender()
logger.appender = console
```
### MultiAppender
```swift
let logger = LBLogger.with("identifier")
let multi = MultiAppender()
multi.appenders.append(ConsoleAppender())
multi.appenders.append(SocketAppender())
logger.appender = multi
```
### SocketAppender
```swift
let logger = LBLogger.with("identifier")
let socket = SocketAppender()
socket.connect("toHost", 22222)
logger.appender = socket
```
## Network Console
iOS, macOS, tvOS, watchOS Debugging Tool, Logging console via Network.
![screenshot](https://user-images.githubusercontent.com/810189/183241560-5ceb2d7e-9421-4eb7-babb-370ce1429645.gif)
### Download
```
git clone https://github.com/shogo4405/Logboard.git
cd Logboard/Console
carthage update --platform macOS --use-xcframewokrs
```
### Build
Open xcode 'Console' and [Product] -> [Archive].
### SocketAppender
```
let logger = LBLogger.with("identifier")
let socket = SocketAppender()
socket.connect("toHost", 22222)
logger.appender = socket
```
## License
BSD-3-Clause

View File

@@ -1,16 +0,0 @@
import Foundation
/// The ConsoleAppender class can output your xcode console with print function.
public class ConsoleAppender: LBLoggerAppender {
/// Creates a ConsoleAppender instance.
public init() {
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, message: [Any], file: StaticString, function: StaticString, line: Int) {
print(LBLogger.dateFormatter.string(from: Date()), "[\(level)]", "[\(logboard.identifier)]", "[\(filename(file.description)):\(line)]", function, ">", message.map({ String(describing: $0) }).joined(separator: ""))
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, format: String, arguments: any CVarArg, file: StaticString, function: StaticString, line: Int) {
print(LBLogger.dateFormatter.string(from: Date()), "[\(level)]", "[\(logboard.identifier)]", "[\(filename(file.description)):\(line)]", function, ">", String(format: format, arguments))
}
}

View File

@@ -1,42 +0,0 @@
import Foundation
extension LBLogger {
/// The logging message model.
public struct Data {
/// The date.
public let date: Date
/// The logging level.
public let level: Level
/// The identifier.
public let identifier: String
/// The filename.
public let file: String
/// The line number.
public let line: Int
/// The function name.
public let function: String
/// The message.
public let message: String
/// Create a Logboard.Data with data.
public init?(_ data: Foundation.Data) {
guard let strings: [String.SubSequence] = String(bytes: data, encoding: .utf8)?.split(separator: "\t"), 7 <= strings.count else {
return nil
}
date = LBLogger.dateFormatter.date(from: String(strings[0])) ?? Date()
level = Level(string: String(strings[1])) ?? .trace
identifier = String(strings[2])
file = String(strings[3])
line = Int(String(strings[4])) ?? 0
function = String(strings[5])
message = strings[6...].joined(separator: "\t")
}
}
}
extension LBLogger.Data: CustomStringConvertible {
// MARK: CustomStringConvertible
public var description: String {
return "\(LBLogger.dateFormatter.string(from: date)) [\(level)] [\(identifier)] [\(filename(file)):\(line)] \(function) > \(message)"
}
}

View File

@@ -1,150 +0,0 @@
import Foundation
func filename(_ file: String) -> String {
return file.components(separatedBy: "/").last ?? file
}
/// The LBLogger class is writing string messages to the LogboardAppender.
public class LBLogger {
/// The default dateFormatter values that is yyyy-dd-MM HH:mm:ss.SSS.
static public var dateFormatter: DateFormatter = {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-dd-MM HH:mm:ss.SSS"
return dateFormatter
}()
/// The logging level.
public enum Level: Int, CustomStringConvertible {
/// The trace log level.
case trace = 0
/// The debug log level.
case debug = 1
/// The infomative log level.
case info = 2
/// The warning log level.
case warn = 3
/// The error log level.
case error = 4
/// Ctrate a logging level from string.
public init?(string: String) {
switch string {
case "Trace":
self = .trace
case "Debug":
self = .debug
case "Info":
self = .info
case "Warn":
self = .warn
case "Error":
self = .error
default:
return nil
}
}
/// The description represents a string expression.
public var description: String {
switch self {
case .trace:
return "Trace"
case .debug:
return "Debug"
case .info:
return "Info"
case .warn:
return "Warn"
case .error:
return "Error"
}
}
}
private static var instances: [String: LBLogger] = [:]
/// Create or get a Logboard instance.
public static func with(_ identifier: String) -> LBLogger {
if instances[identifier] == nil {
instances[identifier] = LBLogger(identifier)
}
return instances[identifier]!
}
/// The identifier is the subsystem name.
public let identifier: String
/// Specifies the logging level.
public var level: LBLogger.Level = .info
/// Specifies logging appenders.
public var appender: any LBLoggerAppender = ConsoleAppender()
/// Create a logger with the identifier.
public init(_ identifier: String) {
self.identifier = identifier
}
/// Is logging enabled for the supplied level or not.
public func isEnabledFor(level: LBLogger.Level) -> Bool {
return self.level.rawValue <= level.rawValue
}
/// Writes a trace message to the appender.
public func trace(_ message: Any..., file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .trace) else { return }
appender.append(self, level: .trace, message: message, file: file, function: function, line: line)
}
/// Writes a trace message to the appender with a format string.
public func trace(format: String, arguments: any CVarArg, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .trace) else { return }
appender.append(self, level: .trace, format: format, arguments: arguments, file: file, function: function, line: line)
}
/// Writes a debug message to the appender.
public func debug(_ message: Any..., file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .debug) else { return }
appender.append(self, level: .debug, message: message, file: file, function: function, line: line)
}
/// Writes a debug message to the appender with a format string.
public func debug(format: String, arguments: any CVarArg, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .debug) else { return }
appender.append(self, level: .debug, format: format, arguments: arguments, file: file, function: function, line: line)
}
/// Writes a informative message to the appender.
public func info(_ message: Any..., file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .info) else { return }
appender.append(self, level: .info, message: message, file: file, function: function, line: line)
}
/// Writes a informative message to the appender with a format string.
public func info(format: String, arguments: any CVarArg, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .info) else { return }
appender.append(self, level: .info, format: format, arguments: arguments, file: file, function: function, line: line)
}
/// Writes a warning message to the appender.
public func warn(_ message: Any..., file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .warn) else { return }
appender.append(self, level: .warn, message: message, file: file, function: function, line: line)
}
/// Writes a warning message to the appender with a format string.
public func warn(format: String, arguments: any CVarArg, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .warn) else { return }
appender.append(self, level: .warn, format: format, arguments: arguments, file: file, function: function, line: line)
}
/// Writes a error message to the appender.
public func error(_ message: Any..., file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .error) else { return }
appender.append(self, level: .error, message: message, file: file, function: function, line: line)
}
/// Writes a error message to the appender with a format string.
public func error(format: String, arguments: any CVarArg, file: StaticString = #file, function: StaticString = #function, line: Int = #line) {
guard isEnabledFor(level: .error) else { return }
appender.append(self, level: .error, format: format, arguments: arguments, file: file, function: function, line: line)
}
}

View File

@@ -1,10 +0,0 @@
import Foundation
/// An interface that manages the logging appending.
public protocol LBLoggerAppender {
/// Appends a logging message string.
func append(_ logboard: LBLogger, level: LBLogger.Level, message: [Any], file: StaticString, function: StaticString, line: Int)
/// Appends a logging message with a format sting.
func append(_ logboard: LBLogger, level: LBLogger.Level, format: String, arguments: any CVarArg, file: StaticString, function: StaticString, line: Int)
}

View File

@@ -1,30 +0,0 @@
import Foundation
/// The MultiAppender class delegates appenders.
/// ## Example code:
/// ```
/// let multi = MultiAppender()
/// multi.appenders.append(ConsoleAppender())
/// multi.appenders.append(SocketAppender())
/// logger.appender = multi
/// ```
public class MultiAppender: LBLoggerAppender {
/// The appenders.
public var appenders: [any LBLoggerAppender] = []
/// Creates a MultIAppender instance.
public init() {
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, message: [Any], file: StaticString, function: StaticString, line: Int) {
for appender in appenders {
appender.append(logboard, level: level, message: message, file: file, function: function, line: line)
}
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, format: String, arguments: any CVarArg, file: StaticString, function: StaticString, line: Int) {
for appender in appenders {
appender.append(logboard, level: level, format: format, arguments: arguments, file: file, function: function, line: line)
}
}
}

View File

@@ -1,12 +0,0 @@
import Foundation
/// The NullAppender class does output no message.
public class NullAppender: LBLoggerAppender {
public static let shared = NullAppender()
public func append(_ logboard: LBLogger, level: LBLogger.Level, message: [Any], file: StaticString, function: StaticString, line: Int) {
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, format: String, arguments: any CVarArg, file: StaticString, function: StaticString, line: Int) {
}
}

View File

@@ -1,60 +0,0 @@
import Foundation
#if canImport(OSLog)
import OSLog
#endif
/// The OSLoggerAppender class can output your Console.app with os_log function.
/// - seealso: https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code
@available(iOS 14.0, *)
@available(macOS 11.0, *)
@available(tvOS 14.0, *)
@available(watchOS 7.0, *)
public class OSLoggerAppender: LBLoggerAppender {
private let logger: Logger
/// Creates a logger using the specified subsystem and category.
public init(sybsystem: String, category: String) {
logger = Logger(subsystem: sybsystem, category: category)
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, message: [Any], file: StaticString, function: StaticString, line: Int) {
let message =
"[\(filename(file.description)):\(line)]" +
function.description +
">" +
message.map({ String(describing: $0) }).joined(separator: "")
switch level {
case .trace:
logger.trace("\(message, privacy: .public)")
case .debug:
logger.debug("\(message, privacy: .public)")
case .info:
logger.info("\(message, privacy: .public)")
case .warn:
logger.warning("\(message, privacy: .public)")
case .error:
logger.error("\(message, privacy: .public)")
}
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, format: String, arguments: any CVarArg, file: StaticString, function: StaticString, line: Int) {
let message =
"[\(filename(file.description)):\(line)]" +
function.description +
">" +
String(format: format, arguments)
switch level {
case .trace:
logger.trace("\(message, privacy: .public)")
case .debug:
logger.debug("\(message, privacy: .public)")
case .info:
logger.info("\(message, privacy: .public)")
case .warn:
logger.warning("\(message, privacy: .public)")
case .error:
logger.error("\(message, privacy: .public)")
}
}
}

View File

@@ -1,231 +0,0 @@
import Foundation
/// The SocketAppender class writes a message to LogboardConsole service.
public class SocketAppender: LBLoggerAppender {
private var socket: NetSocket = NetSocket()
/// Creates a SocketAppende instance.
public init() {
}
/// Connects the Logboard Console service.
public func connect(_ name: String, port: Int) {
socket.connect(withName: name, port: port)
}
/// Closes a conneciton.
public func close() {
socket.close(isDisconnected: false)
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, message: [Any], file: StaticString, function: StaticString, line: Int) {
let strings: [String] = [
LBLogger.dateFormatter.string(from: Date()),
level.description,
logboard.identifier,
file.description,
String(line),
function.description,
message.map({ String(describing: $0) }).joined(separator: "")
]
if let data: Data = (strings.joined(separator: "\t") + "\r\n\r\n").data(using: .utf8) {
socket.doOutput(data: data)
}
}
public func append(_ logboard: LBLogger, level: LBLogger.Level, format: String, arguments: any CVarArg, file: StaticString, function: StaticString, line: Int) {
let strings: [String] = [
LBLogger.dateFormatter.string(from: Date()),
level.description,
logboard.identifier,
file.description,
String(line),
function.description,
String(format: format, arguments)
]
if let data: Data = (strings.joined(separator: "\t") + "\r\n\r\n").data(using: .utf8) {
socket.doOutput(data: data)
}
}
}
class NetSocket: NSObject {
static let defaultTimeout: Int64 = 15 // sec
static let defaultWindowSizeC: Int = Int(UInt16.max)
var inputBuffer: Data = Data()
var timeout: Int64 = NetSocket.defaultTimeout
var connected: Bool = false
var windowSizeC: Int = NetSocket.defaultWindowSizeC
var securityLevel: StreamSocketSecurityLevel = .none
var inputStream: InputStream?
var outputStream: OutputStream?
var inputQueue = DispatchQueue(label: "com.haishinkit.HaishinKit.NetSocket.input")
private var buffer: UnsafeMutablePointer<UInt8>?
private var runloop: RunLoop?
private let outputQueue = DispatchQueue(label: "com.haishinkit.HaishinKit.NetSocket.output")
private var timeoutHandler: (() -> Void)?
func connect(withName: String, port: Int) {
inputQueue.async {
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
CFStreamCreatePairWithSocketToHost(
kCFAllocatorDefault,
withName as CFString,
UInt32(port),
&readStream,
&writeStream
)
self.inputStream = readStream!.takeRetainedValue()
self.outputStream = writeStream!.takeRetainedValue()
self.initConnection()
}
}
@discardableResult
final func doOutput(data: Data) -> Int {
outputQueue.async {
data.withUnsafeBytes { bytes in
guard let bytes = bytes.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
return
}
self.doOutputProcess(bytes, maxLength: data.count)
}
}
return data.count
}
final func doOutputProcess(_ buffer: UnsafePointer<UInt8>, maxLength: Int) {
guard let outputStream = outputStream else {
return
}
var total: Int = 0
while total < maxLength {
let length: Int = outputStream.write(buffer.advanced(by: total), maxLength: maxLength - total)
if length <= 0 {
break
}
total += length
}
}
func close(isDisconnected: Bool) {
outputQueue.async {
guard let runloop: RunLoop = self.runloop else {
return
}
self.deinitConnection(isDisconnected: isDisconnected)
self.runloop = nil
CFRunLoopStop(runloop.getCFRunLoop())
}
}
func close() {
close(isDisconnected: false)
}
func listen() {
}
func initConnection() {
buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: windowSizeC)
buffer?.initialize(repeating: 0, count: windowSizeC)
timeoutHandler = didTimeout
inputBuffer.removeAll(keepingCapacity: false)
guard let inputStream: InputStream = inputStream, let outputStream: OutputStream = outputStream else {
return
}
runloop = .current
inputStream.delegate = self
inputStream.schedule(in: runloop!, forMode: RunLoop.Mode.default)
inputStream.setProperty(securityLevel.rawValue, forKey: .socketSecurityLevelKey)
outputStream.delegate = self
outputStream.schedule(in: runloop!, forMode: RunLoop.Mode.default)
outputStream.setProperty(securityLevel.rawValue, forKey: .socketSecurityLevelKey)
inputStream.open()
outputStream.open()
if 0 < timeout {
outputQueue.asyncAfter(deadline: .now() + Double(timeout * Int64(NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) {
guard let timeoutHandler: (() -> Void) = self.timeoutHandler else {
return
}
timeoutHandler()
}
}
runloop?.run()
connected = false
}
func deinitConnection(isDisconnected: Bool) {
inputStream?.close()
inputStream?.remove(from: runloop!, forMode: RunLoop.Mode.default)
inputStream?.delegate = nil
inputStream = nil
outputStream?.close()
outputStream?.remove(from: runloop!, forMode: RunLoop.Mode.default)
outputStream?.delegate = nil
outputStream = nil
buffer?.deinitialize(count: windowSizeC)
buffer?.deallocate()
buffer = nil
}
func didTimeout() {
}
private func doInput() {
guard let inputStream: InputStream = inputStream, let buffer: UnsafeMutablePointer<UInt8> = buffer else {
return
}
let length: Int = inputStream.read(buffer, maxLength: windowSizeC)
if 0 < length {
inputBuffer.append(buffer, count: length)
listen()
}
}
}
extension NetSocket: StreamDelegate {
// MARK: StreamDelegate
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
// 1 = 1 << 0
case .openCompleted:
guard let inputStream = inputStream, let outputStream = outputStream,
inputStream.streamStatus == .open && outputStream.streamStatus == .open else {
break
}
if aStream == inputStream {
timeoutHandler = nil
connected = true
}
// 2 = 1 << 1
case .hasBytesAvailable:
if aStream == inputStream {
doInput()
}
// 4 = 1 << 2
case .hasSpaceAvailable:
break
// 8 = 1 << 3
case .errorOccurred:
close(isDisconnected: true)
// 16 = 1 << 4
case .endEncountered:
close(isDisconnected: true)
default:
break
}
}
}

View File

@@ -14,10 +14,10 @@ PODS:
- AFNetworking/Serialization (4.0.1) - AFNetworking/Serialization (4.0.1)
- AFNetworking/UIKit (4.0.1): - AFNetworking/UIKit (4.0.1):
- AFNetworking/NSURLSession - AFNetworking/NSURLSession
- CocoaLumberjack (3.7.4): - CocoaLumberjack (3.9.1):
- CocoaLumberjack/Core (= 3.7.4) - CocoaLumberjack/Core (= 3.9.1)
- CocoaLumberjack/Core (3.7.4) - CocoaLumberjack/Core (3.9.1)
- CocoaLumberjack/Swift (3.7.4): - CocoaLumberjack/Swift (3.9.1):
- CocoaLumberjack/Core - CocoaLumberjack/Core
- FBSnapshotTestCase (2.1.4): - FBSnapshotTestCase (2.1.4):
- FBSnapshotTestCase/SwiftSupport (= 2.1.4) - FBSnapshotTestCase/SwiftSupport (= 2.1.4)
@@ -29,7 +29,6 @@ PODS:
- FURenderKit - FURenderKit
- FUCommonUIComponent (1.0) - FUCommonUIComponent (1.0)
- FURenderKit (0.1.0) - FURenderKit (0.1.0)
- Logboard (2.5.0)
- Masonry (1.1.0) - Masonry (1.1.0)
- MBProgressHUD (1.2.0) - MBProgressHUD (1.2.0)
- Reachability (3.7.7) - Reachability (3.7.7)
@@ -38,9 +37,8 @@ PODS:
- SDWebImage/Core (= 5.21.3) - SDWebImage/Core (= 5.21.3)
- SDWebImage/Core (5.21.3) - SDWebImage/Core (5.21.3)
- SellyCloudSDK (0.1.0): - SellyCloudSDK (0.1.0):
- CocoaLumberjack (~> 3.7.2) - CocoaLumberjack
- CocoaLumberjack/Swift - CocoaLumberjack/Swift
- Logboard (~> 2.5.0)
- Reachability - Reachability
- ReactiveObjC - ReactiveObjC
- SocketRocket - SocketRocket
@@ -67,7 +65,6 @@ SPEC REPOS:
trunk: trunk:
- CocoaLumberjack - CocoaLumberjack
- FBSnapshotTestCase - FBSnapshotTestCase
- Logboard
- Masonry - Masonry
- MBProgressHUD - MBProgressHUD
- Reachability - Reachability
@@ -91,18 +88,17 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
AFNetworking: 5789ed1f9a480117fec1f7bb13011d2c0eca41af AFNetworking: 5789ed1f9a480117fec1f7bb13011d2c0eca41af
CocoaLumberjack: 543c79c114dadc3b1aba95641d8738b06b05b646 CocoaLumberjack: e4ba3b414dfca8c1916c6303d37f63b3a95134c6
FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a
FUBeautyComponent: 7625f5cddc9e023fb184a0971efd2dcbcfa75bd2 FUBeautyComponent: 7625f5cddc9e023fb184a0971efd2dcbcfa75bd2
FUCommonUIComponent: 73e969a7bf0eb1b1a4e6188ce85635688252d512 FUCommonUIComponent: 73e969a7bf0eb1b1a4e6188ce85635688252d512
FURenderKit: 4c7c207c0b71d965ceb17de26f9e2f4bd967c72f FURenderKit: 4c7c207c0b71d965ceb17de26f9e2f4bd967c72f
Logboard: 4674a3d86681539a0ad1fca528d888b90871e268
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406 MBProgressHUD: 3ee5efcc380f6a79a7cc9b363dd669c5e1ae7406
Reachability: 8bf74b755b2993968c344b465c13e602db2b1044 Reachability: 8bf74b755b2993968c344b465c13e602db2b1044
ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040 ReactiveObjC: 011caa393aa0383245f2dcf9bf02e86b80b36040
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
SellyCloudSDK: 2642641ff3562001f0852fe85fa284f0704f5a21 SellyCloudSDK: 5171ac4d860d6b15089bdbedabf7d613ce165da7
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30 YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.7.4</string> <string>3.9.1</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>

View File

@@ -3,7 +3,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS $(inherited) -DCOCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}

View File

@@ -3,7 +3,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS $(inherited) -DCOCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>${PODS_DEVELOPMENT_LANGUAGE}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.5.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Logboard : NSObject
@end
@implementation PodsDummy_Logboard
@end

View File

@@ -1,12 +0,0 @@
#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

@@ -1,16 +0,0 @@
#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
FOUNDATION_EXPORT double LogboardVersionNumber;
FOUNDATION_EXPORT const unsigned char LogboardVersionString[];

View File

@@ -1,15 +0,0 @@
APPLICATION_EXTENSION_API_ONLY = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Logboard
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Logboard
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -1,6 +0,0 @@
framework module Logboard {
umbrella header "Logboard-umbrella.h"
export *
module * { export * }
}

View File

@@ -1,15 +0,0 @@
APPLICATION_EXTENSION_API_ONLY = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Logboard
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE}
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Logboard
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@@ -5,7 +5,7 @@ This application makes use of the following third party libraries:
BSD 3-Clause License BSD 3-Clause License
Copyright (c) 2010-2021, Deusty, LLC Copyright (c) 2010-2026, Deusty, LLC
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -19,39 +19,6 @@ Redistribution and use in source and binary forms, with or without modification,
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## Logboard
BSD 3-Clause License
Copyright (c) 2017, shogo4405
All rights reserved.
Redistribution and use 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.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## Reachability ## Reachability
Copyright (c) 2011-2026, Tony Million. Copyright (c) 2011-2026, Tony Million.

View File

@@ -16,7 +16,7 @@
<key>FooterText</key> <key>FooterText</key>
<string>BSD 3-Clause License <string>BSD 3-Clause License
Copyright (c) 2010-2021, Deusty, LLC Copyright (c) 2010-2026, Deusty, LLC
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -36,45 +36,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
</dict> </dict>
<dict>
<key>FooterText</key>
<string>BSD 3-Clause License
Copyright (c) 2017, shogo4405
All rights reserved.
Redistribution and use 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.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</string>
<key>License</key>
<string>New BSD</string>
<key>Title</key>
<string>Logboard</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict> <dict>
<key>FooterText</key> <key>FooterText</key>
<string>Copyright (c) 2011-2026, Tony Million. <string>Copyright (c) 2011-2026, Tony Million.

View File

@@ -1,11 +1,11 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard/Logboard.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "Foundation" -framework "Logboard" -framework "Reachability" -framework "ReactiveObjC" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "YYModel" OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "Foundation" -framework "Reachability" -framework "ReactiveObjC" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "YYModel"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

View File

@@ -1,11 +1,11 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard/Logboard.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "Foundation" -framework "Logboard" -framework "Reachability" -framework "ReactiveObjC" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "YYModel" OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "Foundation" -framework "Reachability" -framework "ReactiveObjC" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "YYModel"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

View File

@@ -28,7 +28,7 @@ THE SOFTWARE.
BSD 3-Clause License BSD 3-Clause License
Copyright (c) 2010-2021, Deusty, LLC Copyright (c) 2010-2026, Deusty, LLC
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -65,39 +65,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
## Logboard
BSD 3-Clause License
Copyright (c) 2017, shogo4405
All rights reserved.
Redistribution and use 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.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## MBProgressHUD ## MBProgressHUD
Copyright © 2009-2020 Matej Bukovinski Copyright © 2009-2020 Matej Bukovinski

View File

@@ -45,7 +45,7 @@ THE SOFTWARE.
<key>FooterText</key> <key>FooterText</key>
<string>BSD 3-Clause License <string>BSD 3-Clause License
Copyright (c) 2010-2021, Deusty, LLC Copyright (c) 2010-2026, Deusty, LLC
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -94,45 +94,6 @@ THE SOFTWARE.
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
</dict> </dict>
<dict>
<key>FooterText</key>
<string>BSD 3-Clause License
Copyright (c) 2017, shogo4405
All rights reserved.
Redistribution and use 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.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</string>
<key>License</key>
<string>New BSD</string>
<key>Title</key>
<string>Logboard</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict> <dict>
<key>FooterText</key> <key>FooterText</key>
<string>Copyright © 2009-2020 Matej Bukovinski <string>Copyright © 2009-2020 Matej Bukovinski

View File

@@ -181,7 +181,6 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/FUBeautyComponent/FUBeautyComponent.framework" install_framework "${BUILT_PRODUCTS_DIR}/FUBeautyComponent/FUBeautyComponent.framework"
install_framework "${BUILT_PRODUCTS_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework" install_framework "${BUILT_PRODUCTS_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework"
install_framework "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk/FURenderKit.framework" install_framework "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk/FURenderKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Logboard/Logboard.framework"
install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework" install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework" install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework" install_framework "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework"
@@ -198,7 +197,6 @@ if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "${BUILT_PRODUCTS_DIR}/FUBeautyComponent/FUBeautyComponent.framework" install_framework "${BUILT_PRODUCTS_DIR}/FUBeautyComponent/FUBeautyComponent.framework"
install_framework "${BUILT_PRODUCTS_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework" install_framework "${BUILT_PRODUCTS_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework"
install_framework "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk/FURenderKit.framework" install_framework "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk/FURenderKit.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Logboard/Logboard.framework"
install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework" install_framework "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework" install_framework "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework"
install_framework "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework" install_framework "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework"

View File

@@ -1,12 +1,12 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard/Logboard.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "Logboard" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "YYModel" OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "YYModel"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FURenderKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FURenderKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

View File

@@ -1,12 +1,12 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard/Logboard.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "Logboard" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "YYModel" OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "YYModel"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FURenderKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "-F${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "-F${PODS_CONFIGURATION_BUILD_DIR}/FURenderKit" "-F${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "-F${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "-F${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "-F${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "-F${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "-F${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "-F${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK" "-F${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "-F${PODS_CONFIGURATION_BUILD_DIR}/YYModel"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

View File

@@ -1,11 +1,11 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard/Logboard.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FBSnapshotTestCase" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "Logboard" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "XCTest" -framework "YYModel" OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FBSnapshotTestCase" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "XCTest" -framework "YYModel"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}

View File

@@ -1,11 +1,11 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard/Logboard.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers" HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUBeautyComponent/FUBeautyComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD/MBProgressHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability/Reachability.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket/SocketRocket.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel/YYModel.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks'
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FBSnapshotTestCase" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "Logboard" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "XCTest" -framework "YYModel" OTHER_LDFLAGS = $(inherited) -l"iconv" -l"icucore" -l"z" -framework "AFNetworking" -framework "CFNetwork" -framework "CocoaLumberjack" -framework "CoreFoundation" -framework "CoreGraphics" -framework "FBSnapshotTestCase" -framework "FUBeautyComponent" -framework "FUCommonUIComponent" -framework "FURenderKit" -framework "Foundation" -framework "ImageIO" -framework "MBProgressHUD" -framework "Masonry" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Reachability" -framework "ReactiveObjC" -framework "SDWebImage" -framework "SSZipArchive" -framework "Security" -framework "SellyCloudSDK" -framework "SocketRocket" -framework "SystemConfiguration" -framework "UIKit" -framework "XCTest" -framework "YYModel"
OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase" OTHER_MODULE_VERIFIER_FLAGS = $(inherited) "-F${PODS_CONFIGURATION_BUILD_DIR}/FBSnapshotTestCase"
OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
PODS_BUILD_DIR = ${BUILD_DIR} PODS_BUILD_DIR = ${BUILD_DIR}

View File

@@ -3,7 +3,7 @@ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES
CLANG_CXX_LANGUAGE_STANDARD = c++17 CLANG_CXX_LANGUAGE_STANDARD = c++17
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -ObjC OTHER_LDFLAGS = $(inherited) -ObjC

View File

@@ -3,7 +3,7 @@ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES
CLANG_CXX_LANGUAGE_STANDARD = c++17 CLANG_CXX_LANGUAGE_STANDARD = c++17
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SellyCloudSDK
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Logboard" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK" FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/Reachability" "${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC" "${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive" "${PODS_CONFIGURATION_BUILD_DIR}/SocketRocket" "${PODS_CONFIGURATION_BUILD_DIR}/YYModel" "${PODS_ROOT}/../SubModules/SellyCloudSDK/SellyCloudSDK/sdk" "${PODS_XCFRAMEWORKS_BUILD_DIR}/SellyCloudSDK"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift
OTHER_LDFLAGS = $(inherited) -ObjC OTHER_LDFLAGS = $(inherited) -ObjC

View File

@@ -828,7 +828,6 @@
"${BUILT_PRODUCTS_DIR}/FUBeautyComponent/FUBeautyComponent.framework", "${BUILT_PRODUCTS_DIR}/FUBeautyComponent/FUBeautyComponent.framework",
"${BUILT_PRODUCTS_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework", "${BUILT_PRODUCTS_DIR}/FUCommonUIComponent/FUCommonUIComponent.framework",
"${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk/FURenderKit.framework", "${PODS_ROOT}/../SubModules/FURenderKit/FURenderKit/sdk/FURenderKit.framework",
"${BUILT_PRODUCTS_DIR}/Logboard/Logboard.framework",
"${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework", "${BUILT_PRODUCTS_DIR}/MBProgressHUD/MBProgressHUD.framework",
"${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework", "${BUILT_PRODUCTS_DIR}/Masonry/Masonry.framework",
"${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework", "${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework",
@@ -846,7 +845,6 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FUBeautyComponent.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FUBeautyComponent.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FUCommonUIComponent.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FUCommonUIComponent.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FURenderKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FURenderKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Logboard.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MBProgressHUD.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Masonry.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework",

View File

@@ -41,7 +41,7 @@ TODO: Add long description of the pod here.
s.vendored_frameworks = 'SellyCloudSDK/sdk/*.{framework,xcframework}' s.vendored_frameworks = 'SellyCloudSDK/sdk/*.{framework,xcframework}'
s.dependency 'CocoaLumberjack', '~>3.7.2' s.dependency 'CocoaLumberjack'
s.dependency 'CocoaLumberjack/Swift' s.dependency 'CocoaLumberjack/Swift'
s.dependency 'ReactiveObjC' s.dependency 'ReactiveObjC'
s.dependency 'Reachability' s.dependency 'Reachability'