Skip to content

Commit

Permalink
🐱 [1.3.0] Add logcat feature (#3)
Browse files Browse the repository at this point in the history
* Can display logcat and scroll to bottom

* refacto

* Bump version

* Update appcast.xml
  • Loading branch information
ThomasBernard03 authored May 15, 2024
1 parent c7af68e commit 6c4d747
Show file tree
Hide file tree
Showing 14 changed files with 147 additions and 165 deletions.
8 changes: 4 additions & 4 deletions AndroidTools/AndroidTools.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_ASSET_PATHS = "\"AndroidTools/Preview Content\"";
DEVELOPMENT_TEAM = H9DTPYA8RY;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -687,7 +687,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.2.0;
MARKETING_VERSION = 1.3.0;
PRODUCT_BUNDLE_IDENTIFIER = fr.thomasbernard03.AndroidTools;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand All @@ -705,7 +705,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 3;
CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_ASSET_PATHS = "\"AndroidTools/Preview Content\"";
DEVELOPMENT_TEAM = H9DTPYA8RY;
ENABLE_HARDENED_RUNTIME = YES;
Expand All @@ -719,7 +719,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.2.0;
MARKETING_VERSION = 1.3.0;
PRODUCT_BUNDLE_IDENTIFIER = fr.thomasbernard03.AndroidTools;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.992",
"green" : "0.904",
"red" : "0.829"
"blue" : "0.820",
"green" : "0.614",
"red" : "0.337"
}
},
"idiom" : "universal"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.353",
"green" : "0.385",
"red" : "0.755"
"blue" : "0.102",
"green" : "0.151",
"red" : "0.739"
}
},
"idiom" : "universal"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "231",
"green" : "244",
"red" : "235"
"blue" : "111",
"green" : "166",
"red" : "109"
}
},
"idiom" : "universal"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.839",
"green" : "0.839",
"red" : "0.839"
"blue" : "0.000",
"green" : "0.000",
"red" : "0.000"
}
},
"idiom" : "universal"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.773",
"green" : "0.920",
"red" : "0.952"
"blue" : "0.106",
"green" : "0.340",
"red" : "0.383"
}
},
"idiom" : "universal"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
import SwiftUI

extension LogLevel {
func backgroundColor() -> Color {
func color() -> Color {
switch(self){
case .verbose:
Color("VerboseLogLevel")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,38 @@ extension String {

return items
}

/**
Exemples :
05-13 17:54:38.765 26819 27857 I okhttp.OkHttpClient: {
05-13 17:54:38.554 26819 27857 I okhttp.OkHttpClient: --> END GET
05-13 17:54:37.995 1684 1700 W android.os.Debug: failed to get memory consumption info: -1
*/
func toLogcatEntry() -> LogEntryModel? {
let components = self.split(separator: " ", maxSplits: 5)

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd HH:mm:ss.SSS"
guard let date = dateFormatter.date(from: "\(components[0]) \(components[1])") else {
return nil
}

guard let processId = Int(components[2]), let threadId = Int(components[3]) else {
return nil
}

guard let level = LogLevel(rawValue: String(components[4])) else {
return nil
}

let tagAndMessage = components[5].split(separator: ":", maxSplits: 1, omittingEmptySubsequences: false)
guard let tag = tagAndMessage.first?.trimmingCharacters(in: .whitespaces),
let message = tagAndMessage.last?.trimmingCharacters(in: .whitespaces) else {
return nil
}


return LogEntryModel(datetime: date, processID: processId, threadID: threadId, level: level, tag: tag, message: message)
}

}
3 changes: 1 addition & 2 deletions AndroidTools/AndroidTools/Domain/Models/LogEntryModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@
import Foundation


struct LogEntryModel : Identifiable {
struct LogEntryModel : Identifiable, Hashable {
let id : UUID = UUID()

var datetime: Date
var processID: Int
var threadID: Int
var level: LogLevel
var packageName : String
var tag: String
var message: String
}
33 changes: 13 additions & 20 deletions AndroidTools/AndroidTools/Presentation/Logcat/LogEntryItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,50 @@ struct LogEntryItem: View {
let processId : Int
let threadId : Int
let tag : String
let packageName : String
let level : LogLevel
let message : String

private var dateFormatter : DateFormatter {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .short
formatter.dateFormat = "dd/MM/yy HH:mm:ss.SSS"
return formatter
}

var body: some View {
HStack {
Text("\(date, formatter: dateFormatter)")
.frame(width: 120)
.frame(width: 150, alignment: .leading)

Text("\(processId)-\(threadId)")
.frame(width: 85)
.frame(width: 90)

Text(tag)
.frame(width:120)

Text(packageName)
.frame(width: 200)
.frame(width:150)

Text(level.rawValue)
.frame(width: 26, height: 26)
.background(level.backgroundColor())


.background(level.color().opacity(0.3))



Text(message)
.foregroundColor(level.backgroundColor())
.fixedSize(horizontal: false, vertical:true)
.foregroundColor(level.color())
.fixedSize(horizontal: true, vertical:true)
}
.lineLimit(1)
}
}

#Preview {
VStack(alignment:.leading, spacing:0) {
LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", packageName: "fr.thomasbernard03.rickandmorty", level: .debug, message: "Here !!")
LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", level: .debug, message: "Here !!")

LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", packageName: "fr.thomasbernard03.rickandmorty", level: .info, message: "Here !!")
LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", level: .info, message: "Here !!")

LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", packageName: "fr.thomasbernard03.rickandmorty", level: .error, message: "Error")
LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", level: .error, message: "Error")

LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", packageName: "fr.thomasbernard03.rickandmorty", level: .warning, message: "Here !!")
LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", level: .warning, message: "Here !!")

LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", packageName: "fr.thomasbernard03.rickandmorty", level: .verbose, message: "Here !!")
LogEntryItem(date: Date.now, processId: 10755, threadId: 11341, tag: "EGL_emulation", level: .verbose, message: "Here !!")
}

}
99 changes: 40 additions & 59 deletions AndroidTools/AndroidTools/Presentation/Logcat/LogcatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,80 +12,61 @@ struct LogcatView: View {

@StateObject private var viewModel = LogcatViewModel()

private func dateStyleFormatter() -> Date.FormatStyle {
return Date.FormatStyle(date: .numeric, time: .standard)
}


var body: some View {
VStack {
HStack {
Menu(viewModel.filterPackage ?? "All packages") {
Button("Display all packages") {
viewModel.filterPackage = nil
ZStack(alignment:.bottom) {
VStack {
ScrollViewReader { proxy in
List(viewModel.logEntries){
LogEntryItem(date: $0.datetime, processId: $0.processID, threadId: $0.threadID, tag: $0.tag, level: $0.level, message: $0.message)
.listRowSeparator(.hidden)
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
}

Divider()

ForEach(Array(viewModel.pidToPackageMap.keys), id: \.self) { pid in
// Obtenir le nom du package à partir du dictionnaire en utilisant le PID
if let packageName = viewModel.pidToPackageMap[pid] {
Button("\(packageName) (\(pid))") {
// Mise à jour du filtre pour afficher uniquement les logs de ce package
viewModel.filterPackage = packageName

.onChange(of: viewModel.stickyList, { _, sticky in
if let lastId = viewModel.logEntries.last?.id {
withAnimation {
proxy.scrollTo(lastId, anchor: .bottom)
}
}
}


})
.onChange(of: viewModel.logEntries, { _, _ in
if viewModel.stickyList {
if let lastId = viewModel.logEntries.last?.id {
withAnimation {
proxy.scrollTo(lastId, anchor: .bottom)
}
}
}
})
}


TextField("Package", text: $viewModel.package)



}
.padding()

// Table(viewModel.logEntries){
// TableColumn("Date") { entry in
// Text("\(entry.datetime.ISO8601Format())")
// }
// TableColumn("ProcessId-ThreadId") { entry in
// Text("\(entry.processID)-\(entry.threadID)")
// }
// TableColumn("Tag") { entry in
// Text(entry.tag)
// }
// TableColumn("Package") { entry in
// Text(entry.packageName)
// }
// TableColumn("Level") { entry in
// Text(entry.level.rawValue)
// }
// TableColumn("Message") { entry in
// Text(entry.message)
// }
// }

List(viewModel.logEntries){
LogEntryItem(date: $0.datetime, processId: $0.processID, threadId: $0.threadID, tag: $0.tag, packageName: $0.packageName, level: $0.level, message: $0.message)
.listRowSeparator(.hidden)
.listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
if viewModel.loading {
ProgressView()
.progressViewStyle(.linear)
.offset(y:8)
}





}
.onAppear {
viewModel.getLogcat(deviceId: deviceId)
}
.toolbar {
Button { } label: {
Label("Stick", systemImage: "arrow.down")
if viewModel.stickyList {
Button { viewModel.stickyList.toggle() } label: {
Label("Stick", systemImage: "arrow.down")
}
.background(.black.opacity(0.1))
.cornerRadius(6)

}
else {
Button { viewModel.stickyList.toggle() } label: {
Label("Stick", systemImage: "arrow.down")
}
}


Button { } label: {
Label("Refresh", systemImage: "arrow.clockwise")
Expand Down
Loading

0 comments on commit 6c4d747

Please sign in to comment.