A debug log framework for use in Swift projects. Allows you to log details to the console (and optionally a file), just like you would have with NSLog() or print(), but with additional information, such as the date, function name, filename and line number.

Overview

XCGLogger

badge-language badge-platforms badge-license

badge-travis badge-swiftpm badge-cocoapods badge-carthage

badge-mastodon badge-twitter

badge-sponsors badge-patreon

tl;dr

XCGLogger is the original debug log module for use in Swift projects.

Swift does not include a C preprocessor so developers are unable to use the debug log #define macros they would use in Objective-C. This means our traditional way of generating nice debug logs no longer works. Resorting to just plain old print calls means you lose a lot of helpful information, or requires you to type a lot more code.

XCGLogger allows you to log details to the console (and optionally a file, or other custom destinations), just like you would have with NSLog() or print(), but with additional information, such as the date, function name, filename and line number.

Go from this:

Simple message

to this:

2014-06-09 06:44:43.600 [Debug] [AppDelegate.swift:40] application(_:didFinishLaunchingWithOptions:): Simple message

Example

Example

Communication (Hat Tip AlamoFire)

  • If you need help, use Stack Overflow (Tag 'xcglogger').
  • If you'd like to ask a general question, use Stack Overflow.
  • If you've found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.
  • If you use XCGLogger, please Star the project on GitHub

Installation

Git Submodule

Execute:

git submodule add https://github.com/DaveWoodCom/XCGLogger.git

in your repository folder.

Carthage

Add the following line to your Cartfile.

github "DaveWoodCom/XCGLogger" ~> 7.0.1

Then run carthage update --no-use-binaries or just carthage update. For details of the installation and usage of Carthage, visit its project page.

Developers running 5.0 and above in Swift will need to add $(SRCROOT)/Carthage/Build/iOS/ObjcExceptionBridging.framework to their Input Files in the Copy Carthage Frameworks Build Phase.

CocoaPods

Add something similar to the following lines to your Podfile. You may need to adjust based on your platform, version/branch etc.

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'XCGLogger', '~> 7.0.1'

Specifying the pod XCGLogger on its own will include the core framework. We're starting to add subspecs to allow you to include optional components as well:

pod 'XCGLogger/UserInfoHelpers', '~> 7.0.1': Include some experimental code to help deal with using UserInfo dictionaries to tag log messages.

Then run pod install. For details of the installation and usage of CocoaPods, visit its official web site.

Note: Before CocoaPods 1.4.0 it was not possible to use multiple pods with a mixture of Swift versions. You may need to ensure each pod is configured for the correct Swift version (check the targets in the pod project of your workspace). If you manually adjust the Swift version for a project, it'll reset the next time you run pod install. You can add a post_install hook into your podfile to automate setting the correct Swift versions. This is largely untested, and I'm not sure it's a good solution, but it seems to work:

post_install do |installer|
    installer.pods_project.targets.each do |target|
        if ['SomeTarget-iOS', 'SomeTarget-watchOS'].include? "#{target}"
            print "Setting #{target}'s SWIFT_VERSION to 4.2\n"
            target.build_configurations.each do |config|
                config.build_settings['SWIFT_VERSION'] = '4.2'
            end
        else
            print "Setting #{target}'s SWIFT_VERSION to Undefined (Xcode will automatically resolve)\n"
            target.build_configurations.each do |config|
                config.build_settings.delete('SWIFT_VERSION')
            end
        end
    end

    print "Setting the default SWIFT_VERSION to 3.2\n"
    installer.pods_project.build_configurations.each do |config|
        config.build_settings['SWIFT_VERSION'] = '3.2'
    end
end

You can adjust that to suit your needs of course.

Swift Package Manager

Add the following entry to your package's dependencies:

.Package(url: "https://github.com/DaveWoodCom/XCGLogger.git", majorVersion: 7)

Backwards Compatibility

Use:

  • XCGLogger version 7.0.1 for Swift 5.0
  • XCGLogger version 6.1.0 for Swift 4.2
  • XCGLogger version 6.0.4 for Swift 4.1
  • XCGLogger version 6.0.2 for Swift 4.0
  • XCGLogger version 5.0.5 for Swift 3.0-3.2
  • XCGLogger version 3.6.0 for Swift 2.3
  • XCGLogger version 3.5.3 for Swift 2.2
  • XCGLogger version 3.2 for Swift 2.0-2.1
  • XCGLogger version 2.x for Swift 1.2
  • XCGLogger version 1.x for Swift 1.1 and below.

Basic Usage (Quick Start)

This quick start method is intended just to get you up and running with the logger. You should however use the advanced usage below to get the most out of this library.

Add the XCGLogger project as a subproject to your project, and add the appropriate library as a dependency of your target(s). Under the General tab of your target, add XCGLogger.framework and ObjcExceptionBridging.framework to the Embedded Binaries section.

Then, in each source file:

import XCGLogger

In your AppDelegate (or other global file), declare a global constant to the default XCGLogger instance.

let log = XCGLogger.default

In the

application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) // iOS, tvOS

or

applicationDidFinishLaunching(_ notification: Notification) // macOS

function, configure the options you need:

log.setup(level: .debug, showThreadName: true, showLevel: true, showFileNames: true, showLineNumbers: true, writeToFile: "path/to/file", fileLevel: .debug)

The value for writeToFile: can be a String or URL. If the file already exists, it will be cleared before we use it. Omit the parameter or set it to nil to log to the console only. You can optionally set a different log level for the file output using the fileLevel: parameter. Set it to nil or omit it to use the same log level as the console.

Then, whenever you'd like to log something, use one of the convenience methods:

log.verbose("A verbose message, usually useful when working on a specific problem")
log.debug("A debug message")
log.info("An info message, probably useful to power users looking in console.app")
log.notice("A notice message")
log.warning("A warning message, may indicate a possible error")
log.error("An error occurred, but it's recoverable, just info about what happened")
log.severe("A severe error occurred, we are likely about to crash now")
log.alert("An alert error occurred, a log destination could be made to email someone")
log.emergency("An emergency error occurred, a log destination could be made to text someone")

The different methods set the log level of the message. XCGLogger will only print messages with a log level that is greater to or equal to its current log level setting. So a logger with a level of .error will only output log messages with a level of .error, .severe, .alert, or .emergency.

Advanced Usage (Recommended)

XCGLogger aims to be simple to use and get you up and running quickly with as few as 2 lines of code above. But it allows for much greater control and flexibility.

A logger can be configured to deliver log messages to a variety of destinations. Using the basic setup above, the logger will output log messages to the standard Xcode debug console, and optionally a file if a path is provided. It's quite likely you'll want to send logs to more interesting places, such as the Apple System Console, a database, third party server, or another application such as NSLogger. This is accomplished by adding the destination to the logger.

Here's an example of configuring the logger to output to the Apple System Log as well as a file.

// Create a logger object with no destinations
let log = XCGLogger(identifier: "advancedLogger", includeDefaultDestinations: false)

// Create a destination for the system console log (via NSLog)
let systemDestination = AppleSystemLogDestination(identifier: "advancedLogger.systemDestination")

// Optionally set some configuration options
systemDestination.outputLevel = .debug
systemDestination.showLogIdentifier = false
systemDestination.showFunctionName = true
systemDestination.showThreadName = true
systemDestination.showLevel = true
systemDestination.showFileName = true
systemDestination.showLineNumber = true
systemDestination.showDate = true

// Add the destination to the logger
log.add(destination: systemDestination)

// Create a file log destination
let fileDestination = FileDestination(writeToFile: "/path/to/file", identifier: "advancedLogger.fileDestination")

// Optionally set some configuration options
fileDestination.outputLevel = .debug
fileDestination.showLogIdentifier = false
fileDestination.showFunctionName = true
fileDestination.showThreadName = true
fileDestination.showLevel = true
fileDestination.showFileName = true
fileDestination.showLineNumber = true
fileDestination.showDate = true

// Process this destination in the background
fileDestination.logQueue = XCGLogger.logQueue

// Add the destination to the logger
log.add(destination: fileDestination)

// Add basic app info, version info etc, to the start of the logs
log.logAppDetails()

You can configure each log destination with different options depending on your needs.

Another common usage pattern is to have multiple loggers, perhaps one for UI issues, one for networking, and another for data issues.

Each log destination can have its own log level. As a convenience, you can set the log level on the log object itself and it will pass that level to each destination. Then set the destinations that need to be different.

Note: A destination object can only be added to one logger object, adding it to a second will remove it from the first.

Initialization Using A Closure

Alternatively you can use a closure to initialize your global variable, so that all initialization is done in one place

let log: XCGLogger = {
    let log = XCGLogger(identifier: "advancedLogger", includeDefaultDestinations: false)

	// Customize as needed
    
    return log
}()

Note: This creates the log object lazily, which means it's not created until it's actually needed. This delays the initial output of the app information details. Because of this, I recommend forcing the log object to be created at app launch by adding the line let _ = log at the top of your didFinishLaunching method if you don't already log something on app launch.

Log Anything

You can log strings:

log.debug("Hi there!")

or pretty much anything you want:

log.debug(true)
log.debug(CGPoint(x: 1.1, y: 2.2))
log.debug(MyEnum.Option)
log.debug((4, 2))
log.debug(["Device": "iPhone", "Version": 7])

Filtering Log Messages

New to XCGLogger 4, you can now create filters to apply to your logger (or to specific destinations). Create and configure your filters (examples below), and then add them to the logger or destination objects by setting the optional filters property to an array containing the filters. Filters are applied in the order they exist in the array. During processing, each filter is asked if the log message should be excluded from the log. If any filter excludes the log message, it's excluded. Filters have no way to reverse the exclusion of another filter.

If a destination's filters property is nil, the log's filters property is used instead. To have one destination log everything, while having all other destinations filter something, add the filters to the log object and set the one destination's filters property to an empty array [].

Note: Unlike destinations, you can add the same filter object to multiple loggers and/or multiple destinations.

Filter by Filename

To exclude all log messages from a specific file, create an exclusion filter like so:

log.filters = [FileNameFilter(excludeFrom: ["AppDelegate.swift"], excludePathWhenMatching: true)]

excludeFrom: takes an Array<String> or Set<String> so you can specify multiple files at the same time.

excludePathWhenMatching: defaults to true so you can omit it unless you want to match path's as well.

To include log messages only for a specific set to files, create the filter using the includeFrom: initializer. It's also possible to just toggle the inverse property to flip the exclusion filter to an inclusion filter.

Filter by Tag

In order to filter log messages by tag, you must of course be able to set a tag on the log messages. Each log message can now have additional, user defined data attached to them, to be used by filters (and/or formatters etc). This is handled with a userInfo: Dictionary<String, Any> object. The dictionary key should be a namespaced string to avoid collisions with future additions. Official keys will begin with com.cerebralgardens.xcglogger. The tag key can be accessed by XCGLogger.Constants.userInfoKeyTags. You definitely don't want to be typing that, so feel free to create a global shortcut: let tags = XCGLogger.Constants.userInfoKeyTags. Now you can easily tag your logs:

let sensitiveTag = "Sensitive"
log.debug("A tagged log message", userInfo: [tags: sensitiveTag])

The value for tags can be an Array<String>, Set<String>, or just a String, depending on your needs. They'll all work the same way when filtered.

Depending on your workflow and usage, you'll probably create faster methods to set up the userInfo dictionary. See below for other possible shortcuts.

Now that you have your logs tagged, you can filter easily:

log.filters = [TagFilter(excludeFrom: [sensitiveTag])]

Just like the FileNameFilter, you can use includeFrom: or toggle inverse to include only log messages that have the specified tags.

Filter by Developer

Filtering by developer is exactly like filtering by tag, only using the userInfo key of XCGLogger.Constants.userInfoKeyDevs. In fact, both filters are subclasses of the UserInfoFilter class that you can use to create additional filters. See Extending XCGLogger below.

Mixing and Matching

In large projects with multiple developers, you'll probably want to start tagging log messages, as well as indicate the developer that added the message.

While extremely flexible, the userInfo dictionary can be a little cumbersome to use. There are a few possible methods you can use to simply things. I'm still testing these out myself so they're not officially part of the library yet (I'd love feedback or other suggestions).

I have created some experimental code to help create the UserInfo dictionaries. (Include the optional UserInfoHelpers subspec if using CocoaPods). Check the iOS Demo app to see it in use.

There are two structs that conform to the UserInfoTaggingProtocol protocol. Tag and Dev.

You can create an extension on each of these that suit your project. For example:

extension Tag {
    static let sensitive = Tag("sensitive")
    static let ui = Tag("ui")
    static let data = Tag("data")
}

extension Dev {
    static let dave = Dev("dave")
    static let sabby = Dev("sabby")
}

Along with these types, there's an overloaded operator | that can be used to merge them together into a dictionary compatible with the UserInfo: parameter of the logging calls.

Then you can log messages like this:

log.debug("A tagged log message", userInfo: Dev.dave | Tag.sensitive)

There are some current issues I see with these UserInfoHelpers, which is why I've made it optional/experimental for now. I'd love to hear comments/suggestions for improvements.

  1. The overloaded operator | merges dictionaries so long as there are no Sets. If one of the dictionaries contains a Set, it'll use one of them, without merging them. Preferring the left hand side if both sides have a set for the same key.
  2. Since the userInfo: parameter needs a dictionary, you can't pass in a single Dev or Tag object. You need to use at least two with the | operator to have it automatically convert to a compatible dictionary. If you only want one Tag for example, you must access the .dictionary parameter manually: userInfo: Tag("Blah").dictionary.

Selectively Executing Code

All log methods operate on closures. Using the same syntactic sugar as Swift's assert() function, this approach ensures we don't waste resources building log messages that won't be output anyway, while at the same time preserving a clean call site.

For example, the following log statement won't waste resources if the debug log level is suppressed:

log.debug("The description of \(thisObject) is really expensive to create")

Similarly, let's say you have to iterate through a loop in order to do some calculation before logging the result. In Objective-C, you could put that code block between #if #endif, and prevent the code from running. But in Swift, previously you would need to still process that loop, wasting resources. With XCGLogger it's as simple as:

log.debug {
    var total = 0.0
    for receipt in receipts {
        total += receipt.total
    }

    return "Total of all receipts: \(total)"
}

In cases where you wish to selectively execute code without generating a log line, return nil, or use one of the methods: verboseExec, debugExec, infoExec, warningExec, errorExec, and severeExec.

Custom Date Formats

You can create your own DateFormatter object and assign it to the logger.

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy hh:mma"
dateFormatter.locale = Locale.current
log.dateFormatter = dateFormatter

Enhancing Log Messages With Colour

XCGLogger supports adding formatting codes to your log messages to enable colour in various places. The original option was to use the XcodeColors plug-in. However, Xcode (as of version 8) no longer officially supports plug-ins. You can still view your logs in colour, just not in Xcode at the moment. You can use the ANSI colour support to add colour to your fileDestination objects and view your logs via a terminal window. This gives you some extra options such as adding Bold, Italics, or (please don't) Blinking!

Once enabled, each log level can have its own colour. These colours can be customized as desired. If using multiple loggers, you could alternatively set each logger to its own colour.

An example of setting up the ANSI formatter:

if let fileDestination: FileDestination = log.destination(withIdentifier: XCGLogger.Constants.fileDestinationIdentifier) as? FileDestination {
    let ansiColorLogFormatter: ANSIColorLogFormatter = ANSIColorLogFormatter()
    ansiColorLogFormatter.colorize(level: .verbose, with: .colorIndex(number: 244), options: [.faint])
    ansiColorLogFormatter.colorize(level: .debug, with: .black)
    ansiColorLogFormatter.colorize(level: .info, with: .blue, options: [.underline])
    ansiColorLogFormatter.colorize(level: .notice, with: .green, options: [.italic])
    ansiColorLogFormatter.colorize(level: .warning, with: .red, options: [.faint])
    ansiColorLogFormatter.colorize(level: .error, with: .red, options: [.bold])
    ansiColorLogFormatter.colorize(level: .severe, with: .white, on: .red)
    ansiColorLogFormatter.colorize(level: .alert, with: .white, on: .red, options: [.bold])
    ansiColorLogFormatter.colorize(level: .emergency, with: .white, on: .red, options: [.bold, .blink])
    fileDestination.formatters = [ansiColorLogFormatter]
}

As with filters, you can use the same formatter objects for multiple loggers and/or multiple destinations. If a destination's formatters property is nil, the logger's formatters property will be used instead.

See Extending XCGLogger below for info on creating your own custom formatters.

Alternate Configurations

By using Swift build flags, different log levels can be used in debugging versus staging/production. Go to Build Settings -> Swift Compiler - Custom Flags -> Other Swift Flags and add -DDEBUG to the Debug entry.

#if DEBUG
    log.setup(level: .debug, showThreadName: true, showLevel: true, showFileNames: true, showLineNumbers: true)
#else
    log.setup(level: .severe, showThreadName: true, showLevel: true, showFileNames: true, showLineNumbers: true)
#endif

You can set any number of options up in a similar fashion. See the updated iOSDemo app for an example of using different log destinations based on options, search for USE_NSLOG.

Background Log Processing

By default, the supplied log destinations will process the logs on the thread they're called on. This is to ensure the log message is displayed immediately when debugging an application. You can add a breakpoint immediately after a log call and see the results when the breakpoint hits.

However, if you're not actively debugging the application, processing the logs on the current thread can introduce a performance hit. You can now specify a destination process its logs on a dispatch queue of your choice (or even use a default supplied one).

fileDestination.logQueue = XCGLogger.logQueue

or even

fileDestination.logQueue = DispatchQueue.global(qos: .background)

This works extremely well when combined with the Alternate Configurations method above.

#if DEBUG
    log.setup(level: .debug, showThreadName: true, showLevel: true, showFileNames: true, showLineNumbers: true)
#else
    log.setup(level: .severe, showThreadName: true, showLevel: true, showFileNames: true, showLineNumbers: true)
    if let consoleLog = log.logDestination(XCGLogger.Constants.baseConsoleDestinationIdentifier) as? ConsoleDestination {
        consoleLog.logQueue = XCGLogger.logQueue
    }
#endif

Append To Existing Log File

When using the advanced configuration of the logger (see Advanced Usage above), you can now specify that the logger append to an existing log file, instead of automatically overwriting it.

Add the optional shouldAppend: parameter when initializing the FileDestination object. You can also add the appendMarker: parameter to add a marker to the log file indicating where a new instance of your app started appending. By default we'll add -- ** ** ** -- if the parameter is omitted. Set it to nil to skip appending the marker.

let fileDestination = FileDestination(writeToFile: "/path/to/file", identifier: "advancedLogger.fileDestination", shouldAppend: true, appendMarker: "-- Relauched App --")

Automatic Log File Rotation

When logging to a file, you have the option to automatically rotate the log file to an archived destination, and have the logger automatically create a new log file in place of the old one.

Create a destination using the AutoRotatingFileDestination class and set the following properties:

targetMaxFileSize: Auto rotate once the file is larger than this

targetMaxTimeInterval: Auto rotate after this many seconds

targetMaxLogFiles: Number of archived log files to keep, older ones are automatically deleted

Those are all guidelines for the logger, not hard limits.

Extending XCGLogger

You can create alternate log destinations (besides the built in ones). Your custom log destination must implement the DestinationProtocol protocol. Instantiate your object, configure it, and then add it to the XCGLogger object with add(destination:). There are two base destination classes (BaseDestination and BaseQueuedDestination) you can inherit from to handle most of the process for you, requiring you to only implement one additional method in your custom class. Take a look at ConsoleDestination and FileDestination for examples.

You can also create custom filters or formatters. Take a look at the provided versions as a starting point. Note that filters and formatters have the ability to alter the log messages as they're processed. This means you can create a filter that strips passwords, highlights specific words, encrypts messages, etc.

Contributing

XCGLogger is the best logger available for Swift because of the contributions from the community like you. There are many ways you can help continue to make it great.

  1. Star the project on GitHub.
  2. Report issues/bugs you find.
  3. Suggest features.
  4. Submit pull requests.
  5. Download and install one of my apps: https://www.cerebralgardens.com/apps/ Try my newest app: All the Rings.
  6. You can visit my Patreon and contribute financially.

Note: when submitting a pull request, please use lots of small commits verses one huge commit. It makes it much easier to merge in when there are several pull requests that need to be combined for a new version.

To Do

  • Add more examples of some advanced use cases
  • Add additional log destination types
  • Add Objective-C support
  • Add Linux support

More

If you find this library helpful, you'll definitely find this other tool helpful:

Watchdog: https://watchdogforxcode.com/

Also, please check out some of my other projects:

Change Log

The change log is now in its own file: CHANGELOG.md

Comments
  • Append to log file instead of overwrite?

    Append to log file instead of overwrite?

    Is there currently a way to just append logs to a log file instead of overwriting the file when re-opening the app? If not, I'd love to see this functionality.

    opened by ryanweber88 35
  • Added auto log rotation.

    Added auto log rotation.

    To address issue #66 I have added two features: auto log rotation and function mostRecentLogFiles(). The following outlines their usage.

    The following properties of FileDestination are used to configure auto log rotation:

    open var rotation = Rotation.none
    open var rotationFileSizeBytes = 1024 * 1024  // 1M
    open var rotationFilesMax = 1
    open var rotationFileDateFormat = "-yyyy-MM-dd'T'HH:mm"
    open var rotationFileHasSuffix = true
    

    Auto log rotation occurs when the log file size exceeds rotationFileSizeBytes. Log rotation can happen at the start time of the app (Rotation.onlyAtAppStart) or at every write (Rotation.alsoWhileWriting). It is strongly advised that asynchronous logging (log queue) is used with .alsoWhileWriting.

    The rotation files are placed in the same directory of the log file. When the number of rotation files exceeds rotationFileMax, the older files are deleted. It is strongly advised that a designated directory is created for the log file and its rotations.

    The rotation files are named as -yyyy-MM-ddTHH:mm., if a suffix, such as .txt is found in the log file name. If the log file name includes "."(dot) but no suffix, rotationFileHasSuffix should be set to false.

    A new function mostRecentLogFiles is added to return specific number of the newest log files. As an example, this function can be used to send the most recent log files to the developer. The same named function is also available via the XCGLogger object.

    Please feel free to make changes, especially styling changes to fit in. For the testing case added, I can't figure out how to make the 5-digit test number. So I just used xxxxx.

    opened by xyzisinus 25
  • Swift 3.0

    Swift 3.0

    _Starting a separate issue to track issues with the Swift 3.0 branch_

    Ok, it's not quite where I want it yet, still some more to add/fix, but I've pushed up where I'm at so far. There are a tonne of changes, and I haven't updated the docs yet. You'll want to look at the demo apps to see how to use it now. Lots of new features, log formatting (ANSI colours etc), log filtering (exclude logs from specific files), easier to add/customize log destinations, and a tonne of renaming to adjust to the new Swift 3 way of doing things.

    Still planned for the short term (late tonight/tomorrow):

    • Add demo's for filtering (including additional example filters)
    • Add Objective-C exception handling to fix #123
    • Documentation/Readme updates
    • More probably.

    Please give me any feedback, issues that you see with this new version, bugs obviously, but I'm also interested in how you think the architecture is changing. Ie, multiple files, destination updates, how filtering/formatting is applied etc.

    This will likely be the last commit that will be 'pure swift' since I need to incorporate Objective-C to handle the exceptions that Swift can't catch. I doubt that's a problem for anyone, but if it is, please let me know.

    opened by DaveWoodCom 23
  • Unable to build version 4.0.0 using Carthage and Xcode 8.3

    Unable to build version 4.0.0 using Carthage and Xcode 8.3

    Below is the error output I get. Note that building top of master branch works fine, but the app crashes due to the memory leak mentioned in #193.

    *** Checking out XCGLogger at "Version_4.0.0"
    *** xcodebuild output can be found in /var/folders/5f/svdt98f10w130w2l3l6z__xh0000gn/T/carthage-xcodebuild.HWu26K.log
    *** Building scheme "ObjcExceptionBridging (iOS)" in XCGLogger.xcodeproj
    *** Building scheme "XCGLogger (iOS)" in XCGLogger.xcodeproj
    ** BUILD FAILED **
    
    
    The following build commands failed:
    	CompileSwift normal arm64
    	CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
    (2 failures)
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Extensions/DispatchQueue+XCGAdditions.swift:11:11: error: use of undeclared type 'DispatchQueue'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/ConsoleDestination.swift:15:24: error: use of undeclared type 'DispatchQueue'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Misc/LogDetails.swift:18:22: error: use of undeclared type 'Date'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Misc/HelperFunctions.swift:25:89: error: use of undeclared type 'NSException'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/BaseDestination.swift:95:16: error: use of unresolved identifier 'Thread'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/BaseDestination.swift:99:37: error: use of unresolved identifier 'Thread'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/BaseDestination.swift:102:41: error: use of unresolved identifier 'DispatchQueue'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/BaseDestination.swift:106:64: error: use of unresolved identifier 'Thread'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/BaseDestination.swift:112:60: error: use of undeclared type 'NSString'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Filters/UserInfoFilter.swift:71:29: warning: @discardableResult declared on a function returning Void is unnecessary
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/TestDestination.swift:15:24: error: use of undeclared type 'DispatchQueue'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/TestDestination.swift:60:17: error: closure use of non-escaping parameter 'closure' may allow it to escape
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Filters/FileNameFilter.swift:71:29: warning: @discardableResult declared on a function returning Void is unnecessary
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Filters/FileNameFilter.swift:61:67: error: use of undeclared type 'NSString'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Filters/FileNameFilter.swift:102:93: error: use of undeclared type 'NSString'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Misc/LogDetails.swift:35:47: error: use of undeclared type 'Date'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Misc/HelperFunctions.swift:35:12: error: use of unresolved identifier 'NSException'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Misc/HelperFunctions.swift:35:30: error: use of unresolved identifier 'NSExceptionName'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/AppleSystemLogDestination.swift:15:24: error: use of undeclared type 'DispatchQueue'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/AppleSystemLogDestination.swift:49:13: error: use of unresolved identifier 'NSLog'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:27:24: error: use of undeclared type 'DispatchQueue'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:30:30: error: use of undeclared type 'URL'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:37:33: error: use of undeclared type 'FileHandle'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:50:27: error: use of undeclared type 'NSString'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:51:30: error: use of unresolved identifier 'URL'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:53:32: error: use of undeclared type 'URL'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:54:46: error: use of undeclared type 'URL'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:88:30: error: use of undeclared type 'FileManager'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:95:37: error: use of unresolved identifier 'FileHandle'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:105:46: error: use of undeclared type 'NSException'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:111:32: error: use of undeclared type 'NSError'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:119:61: error: use of unresolved identifier 'Date'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:148:31: error: use of undeclared type 'URL'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:150:29: error: use of undeclared type 'NSString'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:151:32: error: use of unresolved identifier 'URL'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:153:34: error: use of undeclared type 'URL'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:163:30: error: use of undeclared type 'FileManager'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:172:32: error: use of undeclared type 'NSError'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/Destinations/FileDestination.swift:212:38: error: use of undeclared type 'NSException'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/XCGLogger.swift:338:38: error: cannot invoke initializer for type 'LogDetails' with an argument list of type '(level: XCGLogger.Level, date: Date, message: String, functionName: String, fileName: String, lineNumber: Int, userInfo: [String : Any])'
    /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/Sources/XCGLogger/XCGLogger.swift:1191:34: error: cannot invoke initializer for type 'LogDetails' with an argument list of type '(level: XCGLogger.Level, date: Date, message: String, functionName: String, fileName: String, lineNumber: Int, userInfo: [String : Any])'
    A shell task (/usr/bin/xcrun xcodebuild -project /Users/bbaron/workspacex/iSub/Carthage/Checkouts/XCGLogger/XCGLogger.xcodeproj -scheme "XCGLogger (iOS)" -configuration Release -sdk iphoneos ONLY_ACTIVE_ARCH=NO BITCODE_GENERATION_MODE=bitcode CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES clean build) failed with exit code 65:
    ** BUILD FAILED **
    
    
    The following build commands failed:
    	CompileSwift normal arm64
    	CompileSwiftSources normal arm64 com.apple.xcode.tools.swift.compiler
    (2 failures)
    
    opened by einsteinx2 22
  • Critical:

    Critical: "The app contains one or more corrupted binaries. Rebuild the app and resubmit."

    This version prevents app from being accepted by iTunes Connect. Always gets bounced back with the error message: "The app contains one or more corrupted binaries. Rebuild the app and resubmit."

    I had to submit an empty app and add cocoapods piece by piece until I found the offending one. Unfortunately it was XCGLogger.

    opened by markuswinkler 13
  • Swift 4 Compatibility

    Swift 4 Compatibility

    Swift Compiler Error: Subscripts returning String were obsoleted in Swift 4; explicit construct a String from subscripted result.

    This error occurs in the file AutoRotatingFileDestination.swift (v5.0.1) compiling in Xcode 9.

    opened by pbible 10
  • Distribution as a CocoaPod

    Distribution as a CocoaPod

    I am looking for a logging framework and your project looks like a great tool! Unfortunately you are currently not offering the framework as a CocoaPod, which is my dependency management application.

    Are you planing on including your framework to the CocoaPod project soon?

    opened by steilerDev 10
  • Build XCGLogger 5.0.1 with Carthage: Fix => image not found

    Build XCGLogger 5.0.1 with Carthage: Fix => image not found

    Hi,

    I know this is probably a misconfiguration on my side but since I updated to 5.0.1 with Carthage, I am unable to launch the app.

    I actually noticed that we discussed this issue in #195, it is possible that some faulty commits have been brought over?

    dyld: Library not loaded: @rpath/ObjcExceptionBridging.framework/ObjcExceptionBridging Referenced from: /Users/Library/Developer/CoreSimulator/Devices/data/Containers/Bundle/Application//.app/Frameworks/XCGLogger.framework/XCGLogger Reason: image not found

    I do not have the framework in embedded binaries, (neither i had it with 4.0.0) because carthage asks to use a copy-framework script instead

    It always worked before and all other frameworks are working fine.


    UPDATE: I tested with a clean repository and I still encounter this issue.

    opened by racer1988 9
  • Setup XCGLogger fails on iOS 10.3 emulator

    Setup XCGLogger fails on iOS 10.3 emulator

    Hello, I'm trying to initialize the logger with the below code:

    let logPath: URL = appDelegate.cacheDirectory.appendingPathComponent("XCGLogger_Log.txt")
    log.setup(level: .verbose, showThreadName: true, showLevel: true, showFileNames: true, showLineNumbers: true, writeToFile: logPath)
    

    The app gets stuck on log.setup instruction. This is not the case when passing writeToFile as nil. I was wondering if that has anything to do with the new Apple File System APFS pushed in iOS 10.3.

    opened by sohayb 9
  • Rolling Frequency, File Size etc...

    Rolling Frequency, File Size etc...

    Hi,

    It's really great class for logging, but i feel like it would be nice if we have option to set rolling frequency, file limit etc... like CocoaLumberjack..

    opened by pavm035 9
  • Overlapping accesses to 'data' (Xcode 10 beta, Swift 4.2)

    Overlapping accesses to 'data' (Xcode 10 beta, Swift 4.2)

    In Xcode 10 beta with Swift 4.2 there are two build errors, in URL+XCGAdditions.swift (line 26 and 64):

    Overlapping accesses to 'data', but modification requires exclusive access; consider copying to a local variable

    image

    I think the issue is that you are referring to data inside of the withUnsafeMutableBytes block. The block is reading the data variable (with data.count) while it is modifying the data variable.

    A potential fix would be to replace data with $0.pointee, but I'm not sure if that is just hiding the problem. Perhaps it would be better to extract the data.count into a separate variable before you enter the block and use that inside the block.

    opened by yvbeek 8
  • Supporting Windows platforms?

    Supporting Windows platforms?

    Hello!

    I'm trying to use Swift from Windows platform since Toolchain released, and I know this project doesn't support Windows officially, but I tried.

    so well, I try to build XCGLogger on Windows platform, and ObjcExceptionBridging cause errors like:

    error: #import of type library is an unsupported Microsoft feature
    error: unknown type name 'NS_INLINE'
    error: expected expression
        @try {
    
    etc...
    

    I assume error causes because ObjcExceptionBridging is written in Obj-C.

    However, I wonder is there any plan for supporting Windows platform? Thanks in advance.

    opened by CenoX 0
  • Crash on Linux

    Crash on Linux

    Swift: 5.3.3 XCGLogger: 7.0.1

    <module-includes>:1:10: note: in file included from <module-includes>:1:
    #include ".build/checkouts/XCGLogger/Sources/ObjcExceptionBridging/include/ObjcExceptionBridging.h"
             ^
    .build/checkouts/XCGLogger/Sources/ObjcExceptionBridging/include/ObjcExceptionBridging.h:10:9: error: 'Foundation/Foundation.h' file not found
    #import <Foundation/Foundation.h>
            ^
    .build/checkouts/XCGLogger/Sources/XCGLogger/Misc/HelperFunctions.swift:11:8: error: could not build C module 'ObjcExceptionBridging'
    import ObjcExceptionBridging
           ^
    [8/1246] Compiling v3_utl.c
    Makefile:7: recipe for target 'server_build' failed
    make: *** [server_build] Error 1
    
    opened by bordunosp 0
  • Type of Logger

    Type of Logger

    Many other libraries expect as an argument "Logging.Logger" When I create new instance XCGLogger, I cant put this logger to the "PostgresKit" or any other libs because they w8 "Logger" type, not "XCGLogger"

    To solve this problem I need install some other lib: https://github.com/crspybits/swift-log-file/blob/main/Sources/FileLogging/swift_log_xcglogger.swift

    I like the minimum number of dependent packages (: Can u add a wrapper out of the box?

    opened by bordunosp 0
  • Updated swift documentation for AutoRotatingFileDestination

    Updated swift documentation for AutoRotatingFileDestination

    Updated class and constructor documentation to help others avoid two problems I experienced:

    (a) not understanding how files are "grouped" using .identifier, and how this affects "grouping" of files when sending multiple Destinations to a single logging directory

    (b) not understanding that omitting the .maxTimeInterval uses a (very short!) default of 10 minutes, and does not mean "no limit" as I had expected

    opened by driftwoodstudio 1
Owner
Dave Wood
iOS/macOS/Android developer at Cerebral Gardens. https://davewood.com/
Dave Wood
Customizable login screen, written in Swift 🔶

LFLoginController Customizable login screen, written in Swift Creating Login screens is boring and repetitive. What about implementing and customizing

Awesome Labs 152 Oct 30, 2022
Plug-n-Play login system for iOS written in Swift

Prounounced Cell-Lee Cely’s goal is to add a login system into your app in under 30 seconds! Overview Requirements Usage API Installation License Over

null 164 Nov 15, 2022
LoginKit is a quick and easy way to add a Login/Signup UX to your iOS app.

LoginKit About LoginKit is a quick and easy way to add Facebook and email Login/Signup UI to your app. If you need to quickly prototype an app, create

Icalia Labs 653 Dec 17, 2022
Alby-installer-macos - The Extension and Companion Installer for Alby

Alby macOS Installer This is the Extension and Companion Installer for Alby. Cli

Alby 4 Mar 4, 2022
Example on how to print a NSTableView from your app but then also add text to the print-out.

NSTableView Printing Test This is a demo project so you can check out how printing a table could work. The goal here is to show tabular data on screen

Clean Cocoa 3 Mar 29, 2022
A lightweight Swift logger, uses `print` in development and `NSLog` in production. Support colourful and formatted output.

Loggerithm A lightweight Swift logger, uses print in Debug and NSLog in Production with colourful output. Why In Swift, we usually use print to log in

HongHao Zhang 270 Oct 8, 2022
Automate box any value! Print log without any format control symbol! Change debug habit thoroughly!

LxDBAnything Automate box any value! Print log without any format control symbol! Change debug habit thoroughly! Installation You only need drag LxD

DeveloperLx 433 Sep 7, 2022
Visualize your dividend growth. DivRise tracks dividend prices of your stocks, gives you in-depth information about dividend paying stocks like the next dividend date and allows you to log your monthly dividend income.

DivRise DivRise is an iOS app written in Pure SwiftUI that tracks dividend prices of your stocks, gives you in-depth information about dividend paying

Kevin Li 78 Oct 17, 2022
XCLog is a Swift extension that helps you print something in console when debugging your projects.

XCLog XCLog is a Swift extension that helps you print something in console when debugging your projects. Installation Open Xcode > File > Add Packages

null 1 Jan 9, 2022
TextFieldFormatter - Simple Text Formatter (Credit Card Number, Phone Number, Serial Number etc.)

TextFieldFormatter Simple Text Formatter (Credit Card Number, Phone Number, Seri

Anıl ORUÇ 4 Apr 4, 2022
Customizable Console UI overlay with debug log on top of your iOS App

AEConsole Customizable Console UI overlay with debug log on top of your iOS App AEConsole is built on top of AELog, so you should probably see that fi

Marko Tadić 142 Dec 21, 2022
Customizable Console UI overlay with debug log on top of your iOS App

AEConsole Customizable Console UI overlay with debug log on top of your iOS App AEConsole is built on top of AELog, so you should probably see that fi

Marko Tadić 142 Dec 21, 2022
LinkedLog is a Xcode plugin that includes a Xcode PCH header file template that adds the macros `LLog` and `LLogF` and parses their output to link from the console to the corresponding file and line.

LinkedLog Xcode Plugin LinkedLog is a Xcode plugin that includes a Xcode PCH file template that adds the macros LLog and LLogF. The LLog macro will wo

Julian F. Weinert 22 Nov 14, 2022
Matft is Numpy-like library in Swift. Function name and usage is similar to Numpy.

Numpy-like library in swift. (Multi-dimensional Array, ndarray, matrix and vector library)

null 80 Dec 21, 2022
📱💬🚦 TinyConsole is a micro-console that can help you log and display information inside an iOS application, where having a connection to a development computer is not possible.

TinyConsole TinyConsole is a tiny log console to display information while using your iOS app and written in Swift. Usage Wrap your Main ViewControlle

Devran Cosmo Uenal 2k Jan 3, 2023
Pavel Surový 0 Jan 1, 2022
Scan the MRZ code of a passport and extract the firstname, lastname, passport number, nationality, date of birth, expiration date and personal numer.

PassportScanner Works with 2 and 3 line identity documents. What is this With PassportScanner you can use your camera to scan the MRZ code of a passpo

Edwin Vermeer 441 Dec 24, 2022
ips2crash is a macOS command line too to convert a .ips file to a legacy .crash log file.

Synopsis ips2crash is a macOS command line too to convert a .ips file to a legacy .crash log file. Motivation It should be possible to read .ips file

null 36 Nov 25, 2022
Automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code based on Swift. Just like God opened his eyes

GodEye Automaticly display Log,Crash,Network,ANR,Leak,CPU,RAM,FPS,NetFlow,Folder and etc with one line of code based on Swift. Just like God opened hi

陈奕龙(子循) 3.7k Dec 23, 2022