Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions LoopFollow/Log/LogArchiver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// LoopFollow
// LogArchiver.swift

import Foundation

enum LogArchiver {
/// Copies `files` into a folder named `archiveName` and returns a zip archive
/// of that folder in the temporary directory.
static func zip(files: [URL], archiveName: String) throws -> URL {
let fileManager = FileManager.default
let staging = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true)
let folder = staging.appendingPathComponent(archiveName, isDirectory: true)
try fileManager.createDirectory(at: folder, withIntermediateDirectories: true)
defer { try? fileManager.removeItem(at: staging) }

for file in files {
try fileManager.copyItem(at: file, to: folder.appendingPathComponent(file.lastPathComponent))
}

let destination = fileManager.temporaryDirectory.appendingPathComponent("\(archiveName).zip")
try? fileManager.removeItem(at: destination)

var coordinationError: NSError?
var copyError: Error?
NSFileCoordinator().coordinate(readingItemAt: folder, options: .forUploading, error: &coordinationError) { zipURL in
do {
try fileManager.copyItem(at: zipURL, to: destination)
} catch {
copyError = error
}
}
if let coordinationError { throw coordinationError }
if let copyError { throw copyError }
return destination
}
}
30 changes: 21 additions & 9 deletions LoopFollow/ViewControllers/MoreMenuView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -287,19 +287,31 @@ struct MoreMenuView: View {
}

private func presentLogShareSheet(noticeText: String, logFiles: [URL]) {
var items: [Any] = logFiles
if let noticeURL = writeShareNoticeFile(text: noticeText) {
items.insert(noticeURL, at: 0)
}
let avc = UIActivityViewController(activityItems: items, applicationActivities: nil)
UIApplication.shared.topMost?.present(avc, animated: true)
}

private func writeShareNoticeFile(text: String) -> URL? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd_HHmm"
let timestamp = formatter.string(from: Date())

var files = logFiles
if let noticeURL = writeShareNoticeFile(text: noticeText, timestamp: timestamp) {
files.insert(noticeURL, at: 0)
}

DispatchQueue.global(qos: .userInitiated).async {
let items: [Any]
do {
items = try [LogArchiver.zip(files: files, archiveName: "LoopFollow Logs \(timestamp)")]
} catch {
LogManager.shared.log(category: .general, message: "Failed to zip log files, sharing them uncompressed: \(error)")
items = files
}
DispatchQueue.main.async {
let avc = UIActivityViewController(activityItems: items, applicationActivities: nil)
UIApplication.shared.topMost?.present(avc, animated: true)
}
}
}

private func writeShareNoticeFile(text: String, timestamp: String) -> URL? {
let version = AppVersionManager().version()
let branchAndSha = BuildDetails.default.branchAndSha

Expand Down
Loading