0

我问这个问题是因为我在网上找到的所有答案要么已经过时,要么不适合我。

我正在使用客户框架,出于某种原因,他们要求我在项目中使用 CocoaLumberjack,因此对其他 Log-tools 的任何建议对我来说都是无用的,至少对于这个项目而言,提前感谢您的理解

问题:

如何从用户那里获取日志?我对日志记录不太熟悉,所以这对我来说是全新的。

我在 Github 上的大量 SO-answers 和 CocoaLumberjacks 文档的帮助下编写了一些代码。

我很确定我实际上是在记录,因为当我在真实设备上运行我的应用程序时,我可以从 Xcode 获取日志:Xcode -> Window -> Devices and Simulators -> Select the device (and app) ->下载容器。

从容器中我可以看到日志。但是我怎样才能看到他们的设备不在这里的用户的日志呢?

AppDelegate.swift :

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool  {
    let formatter = LogFormatter()
    DDTTYLogger.sharedInstance.logFormatter = formatter

return true
}

我的 logformatter 来自 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
        }
    }
}

然后我想用一个按钮通过电子邮件发送日志(来自同一个 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.
        }
    }

当我调用函数发送电子邮件时会发生什么是“在隐式展开可选值时意外发现 nil”-错误

let logFilePaths = ddFileLogger.logFileManager.sortedLogFilePaths

在 LogFormatter()

我究竟做错了什么?

4

1 回答 1

0

恐怕我只在 Obj-C 中有它:

NSMutableData *logData = [NSMutableData data];
for (NSData *logFileData2 in [self.utilities logfileData]) {
    [logData appendData:logFileData2];
}
[picker addAttachmentData:logData mimeType:@"text/plain" fileName:@"logs.txt"];

然后在我的实用程序类中:

- (NSMutableArray *)logfileData {
    
    NSUInteger maximumLogFilesToReturn = MIN(fileLogger.logFileManager.maximumNumberOfLogFiles, 10);
    NSMutableArray *logFiles = [NSMutableArray arrayWithCapacity:maximumLogFilesToReturn];
    DDFileLogger *logger = fileLogger;
    NSArray *sortedLogFileInfos = [logger.logFileManager sortedLogFileInfos];
    for (NSUInteger i = 0; i < MIN(sortedLogFileInfos.count, maximumLogFilesToReturn); i++) {
        DDLogFileInfo *logFileInfo = [sortedLogFileInfos objectAtIndex:i];
        NSData *fileData = [NSData dataWithContentsOfFile:logFileInfo.filePath];
        [logFiles addObject:fileData];
    }
    return logFiles;
}

所以也许对你来说:

var logFileDataArray: [NSData] {
        get {
            let sortedLogFileInfos = ddFileLogger.logFileManager.sortedLogFileInfos
            var logFileDataArray = [NSData]()
            for logFileInfo in sortedLogFileInfos {
                if let logFileData = try? NSData(contentsOf: logFileInfo.filePath as String, options: NSData.ReadingOptions.mappedIfSafe) {
                    // Insert at front to reverse the order, so that oldest logs appear first.
                    logFileDataArray.insert(logFileData, at: 0)
                }
            }
            return logFileDataArray
        }
    }
于 2020-10-18T08:21:30.727 回答