I'm asking this question because all answers I've found online are either outdated or not working for me.
I'm working with a customers framework and for some reason they require me to use CocoaLumberjack in the project so any suggestions on other Log-tools are useless for me, at least for this project, thank you in advance for understanding
The question:
How do I get the logs from users? I am not that familiar to logging so this is all new to me.
I've written some code with the help of numerous SO-answers and CocoaLumberjacks documentation on Github.
I'm pretty sure that I am actually logging because I can get the logs from Xcode when I run my app on a real device by doing: Xcode -> Window -> Devices and Simulators -> Select the device (and app) -> Download Container.
From the container I can see the logs. But how can I see the logs from user that are not physically here with their device?
AppDelegate.swift :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let formatter = LogFormatter()
DDTTYLogger.sharedInstance.logFormatter = formatter
return true
}
my logformatter is from StackOverflow https://stackoverflow.com/a/14000342/4189589
class LogFormatter: NSObject, DDLogFormatter {
let dateFormatter: DateFormatter
static let sharedInstance = LogFormatter()
override init() {
dateFormatter = DateFormatter()
dateFormatter.formatterBehavior = .behavior10_4
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss:SSS"
DDLog.add(DDOSLogger.sharedInstance) // Uses os_log
let fileLogger: DDFileLogger = DDFileLogger() // File Logger
fileLogger.rollingFrequency = 60 * 60 * 24 // 24 hours
fileLogger.logFileManager.maximumNumberOfLogFiles = 7
DDLog.add(fileLogger)
DDLogDebug("Debug")
DDLogVerbose("Verbose")
DDLogInfo("Info")
DDLogWarn("Warn")
DDLogError("Error")
super.init()
}
func format(message logMessage: DDLogMessage) -> String? {
let dateAndTime = dateFormatter.string(from: logMessage.timestamp)
return "\(dateAndTime) [\(logMessage.fileName):\(logMessage.line)]: \(logMessage.message)"
}
var ddFileLogger: DDFileLogger!
var logFileDataArray: [NSData] {
get {
let logFilePaths = ddFileLogger.logFileManager.sortedLogFilePaths
var logFileDataArray = [NSData]()
for logFilePath in logFilePaths {
let fileURL = NSURL(fileURLWithPath: logFilePath)
if let logFileData = try? NSData(contentsOf: fileURL as URL, options: NSData.ReadingOptions.mappedIfSafe) {
// Insert at front to reverse the order, so that oldest logs appear first.
logFileDataArray.insert(logFileData, at: 0)
}
}
return logFileDataArray
}
}
}
And then I want to email the logs with a button (from same SO-answer)
func emailLogsTo(email: String) {
if MFMailComposeViewController.canSendMail() {
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
// Configure the fields of the interface.
composeVC.setToRecipients([email])
composeVC.setSubject("Feedback for app")
composeVC.setMessageBody("", isHTML: false)
let attachmentData = NSMutableData()
for logFileData in LogFormatter.sharedInstance.logFileDataArray {
attachmentData.append(logFileData as Data)
}
composeVC.addAttachmentData(attachmentData as Data, mimeType: "text/plain", fileName: "diagnostic.log")
self.present(composeVC, animated: true, completion: nil)
} else {
// Tell user about not able to send email directly.
}
}
What happens when I call the function to send the email is that I get an "unexpectedly found nil while implicitly unwrapping an Optional value"-error on
let logFilePaths = ddFileLogger.logFileManager.sortedLogFilePaths
in LogFormatter()
What am I doing wrong?