I am Using cocoaLumberjack logging framework for iOS logging. For storing logs in a file I used this code.
DDFileLogger* fileLogger = [[DDFileLogger alloc] i
I don't know if this might help somebody else... I took the previous answers and passed it to Swift 5. Apart from getting all the paths, it prints the content.
let logFileLogger = DDFileLogger()
print(logFileLogger.logFileManager.logsDirectory)
for path in logFileLogger.logFileManager.sortedLogFilePaths {
do {
let content = try String(contentsOfFile: path, encoding: .utf8)
print(content)
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
}
Send log files from app through email, in Objective-C
Objective-C code:
In you header:
#import <MessageUI/MessageUI.h>
#import "DDLog.h"
#import "DDFileLogger.h"
In your implementation:
- (NSMutableArray *)errorLogData {
DDFileLogger *ddFileLogger = [DDFileLogger new];
NSArray <NSString *> *logFilePaths = [ddFileLogger.logFileManager sortedLogFilePaths];
NSMutableArray <NSData *> *logFileDataArray = [NSMutableArray new];
for (NSString* logFilePath in logFilePaths) {
NSURL *fileUrl = [NSURL fileURLWithPath:logFilePath];
NSData *logFileData = [NSData dataWithContentsOfURL:fileUrl options:NSDataReadingMappedIfSafe error:nil];
if (logFileData) {
[logFileDataArray insertObject:logFileData atIndex:0];
}
}
return logFileDataArray;
}
- (void)composeEmailWithDebugAttachment {
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
NSMutableData *errorLogData = [NSMutableData data];
for (NSData *errorLogFileData in [self errorLogData]) {
[errorLogData appendData:errorLogFileData];
}
[mailViewController addAttachmentData:errorLogData mimeType:@"text/plain" fileName:@"filename.log"];
[mailViewController setSubject:NSLocalizedString(@"LogFile Subject", @"")];
[mailViewController setToRecipients:[NSArray arrayWithObject:@"email@email.com"]];
[self presentViewController:mailViewController animated:YES completion:nil];
} else {
NSString *message = NSLocalizedString(@"Sorry, your issue can't be reported right now. This is most likely because no mail accounts are set up on your mobile device.", @"");
[[[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", @"") otherButtonTitles: nil] show];
}
}
- (void)mailComposeController:(MFMailComposeViewController *)mailer didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self becomeFirstResponder];
[mailer dismissViewControllerAnimated:YES completion:nil];
}
Here is how you could add something in your Log-file:
DDLogError(@"This is an error.");
DDLogWarn(@"This is a warning.");
DDLogInfo(@"This is just a message.");
DDLogVerbose(@"This is a verbose message.");
Don't forget to set your ddLogLevel
in your Constants-file.
Constants.h :
extern NSUInteger const ddLogLevel;
Comstants.m :
NSUInteger const ddLogLevel =
#ifdef DEBUG
LOG_LEVEL_VERBOSE;
#else
LOG_LEVEL_ERROR;
#endif
It is very obvious but don't forget to configure CocoaLumberjack in your AppDelegate.m file.
[DDLog addLogger:[DDASLLogger sharedInstance]];
[DDLog addLogger:[DDTTYLogger sharedInstance]];
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
[fileLogger setMaximumFileSize:(1024 * 1024)];
[fileLogger setRollingFrequency:(3600.0 * 24.0)];
[[fileLogger logFileManager] setMaximumNumberOfLogFiles:7];
[DDLog addLogger:fileLogger];
The best place to paste this code is - (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
in your AppDelegate.m file.
Also you should add this line of code in your AppDelegate.m header:
#import <CocoaLumberjack/CocoaLumberjack.h>
Hope it will help.
Found this to be the latest:
DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
fileLogger.logFileManager.logsDirectory;//THIS
From the official code:
Default log file manager.
All log files are placed inside the logsDirectory. If a specific logsDirectory isn't specified, the default directory is used. On Mac, this is in ~/Library/Logs/. On iPhone, this is in ~/Library/Caches/Logs. Log files are named "log-.txt", where uuid is a 6 character hexadecimal consisting of the set [0123456789ABCDEF]. Archived log files are automatically deleted according to the maximumNumberOfLogFiles property.
I had to rewrite it a little to be compatible with Swift 4...
var logFileDataArray: [Data] {
let logFilePaths = delegate.fileLogger.logFileManager.sortedLogFilePaths
var logFileDataArray = [Data]()
for logFilePath in logFilePaths {
let fileURL = URL(fileURLWithPath: logFilePath)
if let logFileData =
try? Data(contentsOf: fileURL, options: Data.ReadingOptions.mappedIfSafe) {
logFileDataArray.insert(logFileData, at: 0)
}
}
return logFileDataArray
}
func sendApplicationLog(text: String) {
if MFMailComposeViewController.canSendMail() {
let controller = MFMailComposeViewController()
controller.mailComposeDelegate = self
controller.setToRecipients(["dohan.rene@gmail.com"])
controller.setSubject("Log of motorkari iOS")
controller.setMessageBody(text, isHTML: false)
var attachmentData = Data()
for logFileData in logFileDataArray { attachmentData.append(logFileData) }
controller.addAttachmentData(attachmentData, mimeType: "text/plain",
fileName: "motorkari_ios_application.log")
present(controller, animated: true, completion: nil)
} else {
showMessage("Log cannot be send !")
}
}
Got the answer
It is stored in Library/Appication Support/Iphone Simulator/#version no#/applications/#your application#/documents/logs/log-3hex no>
You can download the log files from connected device, or you can send directly from app. Both approaches are described below.
Write this in the class where you have a reference to DDFileLogger. I would put this in a custom logger class e.g. MyLogger.swift
var ddFileLogger: DDFileLogger!
var logFileDataArray: [NSData] {
get {
let logFilePaths = ddFileLogger.logFileManager.sortedLogFilePaths() as! [String]
var logFileDataArray = [NSData]()
for logFilePath in logFilePaths {
let fileURL = NSURL(fileURLWithPath: logFilePath)
if let logFileData = try? NSData(contentsOfURL: fileURL, options: NSDataReadingOptions.DataReadingMappedIfSafe) {
// Insert at front to reverse the order, so that oldest logs appear first.
logFileDataArray.insert(logFileData, atIndex: 0)
}
}
return logFileDataArray
}
}
Then, when user taps on a button to indicate that they want to send the logs,
// Required by MFMailComposeViewController
import MessageUI
@IBAction func writeEmailTapped(sender: AnyObject) {
if MFMailComposeViewController.canSendMail() {
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
// Configure the fields of the interface.
composeVC.setToRecipients(["your-email@company.com"])
composeVC.setSubject("Feedback for app")
composeVC.setMessageBody("", isHTML: false)
let attachmentData = NSMutableData()
for logFileData in MyLogger.sharedInstance.logFileDataArray {
attachmentData.appendData(logFileData)
}
composeVC.addAttachmentData(attachmentData, mimeType: "text/plain", fileName: "diagnostic.log")
self.presentViewController(composeVC, animated: true, completion: nil)
} else {
// Tell user about not able to send email directly.
}
}
This results in a compose email pop-up with an attachment file named diagnostic.log
, which is all the log files concatenated together.
Special thanks - This is pretty much a Swift translation from the Objective-C version given by the other answer.
If you want to get the log files that your app created while running on device,
/AppData/Library/Caches/Logs/
Up-vote would be nice if this is helpful to you!