Skip to content

Instantly share code, notes, and snippets.

@notoroid
Created January 3, 2021 06:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notoroid/83df312608408d1da44dc40139f49c21 to your computer and use it in GitHub Desktop.
Save notoroid/83df312608408d1da44dc40139f49c21 to your computer and use it in GitHub Desktop.
Apple M1 chip archive benchmark for macOS app
import SwiftUI
import Combine
import AppleArchive
import System
enum ArchiveBenchResult {
case failureError(error: Error)
case notExistsSourceFile
case notOpenReadFileStream
case notOpenWriteFileStream
case notOpenCompressionStream
case success(timeinterval: TimeInterval)
func description() -> String {
switch self {
case .failureError(let error): return "エラー: " + error.localizedDescription
case .notExistsSourceFile: return "アーカイブ元ファイルが見つかりません"
case .notOpenReadFileStream: return "ReadFileStreamの作成に失敗しました"
case .notOpenWriteFileStream: return "WriteFileStreamの作成に失敗しました"
case .notOpenCompressionStream: return "CompressionStreamの作成に失敗しました"
case .success(let timeinterval): return "\(timeinterval)"
}
}
}
// for macOS app project, not working iPhone simulator
struct ContentView: View {
static let archivedFileURL = FileManager.default.temporaryDirectory.appendingPathComponent("archiveBenchmark.lzfse")
@State var informationString = "下部の矩形にファイルをドロップしてください。"
@State var resultString = ""
@State private var dragOver = false
func postResult(_ result: ArchiveBenchResult) -> Void { DispatchQueue.main.async { self.resultString = result.description() } }
var body: some View {
HStack {
Spacer()
VStack {
Spacer()
Text(self.informationString)
Rectangle()
.frame(width: 200, height: 150)
.foregroundColor(.gray)
.onDrop(of: ["public.file-url"], isTargeted: $dragOver) { providers -> Bool in
providers.first?.loadDataRepresentation(forTypeIdentifier: "public.file-url", completionHandler: { (data, error) in
if let data = data, let path = NSString(data: data, encoding: 4), let sourceFileURL = URL(string: path as String) {
DispatchQueue.main.async {
self.informationString = sourceFileURL.path
}
guard FileManager.default.fileExists(atPath: sourceFileURL.path) else {
self.postResult(.notExistsSourceFile)
return
}
if FileManager.default.fileExists(atPath: Self.archivedFileURL.path) {
do {
try FileManager.default.removeItem(atPath: Self.archivedFileURL.path)
} catch (let error) {
self.postResult(.failureError(error: error))
return
}
}
let sourceFilePath = FilePath(sourceFileURL.path)
guard let readFileStream = ArchiveByteStream.fileStream(path: sourceFilePath, mode: .readOnly, options: [ ], permissions: FilePermissions(rawValue: 0o644)) else {
self.postResult(.notOpenReadFileStream)
return
}
defer { try? readFileStream.close() }
let archiveFilePath = FilePath(Self.archivedFileURL.path)
guard let writeFileStream = ArchiveByteStream.fileStream(path: archiveFilePath, mode: .writeOnly, options: [ .create ], permissions: FilePermissions(rawValue: 0o644)) else {
self.postResult(.notOpenWriteFileStream)
return
}
defer { try? writeFileStream.close() }
guard let compressStream = ArchiveByteStream.compressionStream( using: .lzfse, writingTo: writeFileStream) else {
self.postResult(.notOpenCompressionStream)
return
}
defer { try? compressStream.close() }
do {
let now = NSDate()
_ = try ArchiveByteStream.process(readingFrom: readFileStream, writingTo: compressStream)
_ = try? FileManager.default.removeItem(atPath: Self.archivedFileURL.path)
self.postResult(.success(timeinterval: abs(now.timeIntervalSinceNow)))
} catch (let error) {
self.postResult(.failureError(error: error))
}
}
})
return true
}
HStack {
Text("計測結果(秒):")
TextField("計測結果が反映されます", text: self.$resultString)
Spacer()
}
Spacer()
}
Spacer()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment