Skip to content

Commit

Permalink
Merge pull request #5 from kvyatkovskys/feature/sendable
Browse files Browse the repository at this point in the history
sendable feature
  • Loading branch information
kvyatkovskys authored Mar 19, 2024
2 parents 04def1d + 2104dbe commit 423eb88
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 40 deletions.
6 changes: 5 additions & 1 deletion DemoLogger/DemoLogger.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1420;
LastUpgradeCheck = 1420;
LastUpgradeCheck = 1530;
TargetAttributes = {
F95AA60F29867BC90089D3EA = {
CreatedOnToolsVersion = 14.2;
Expand Down Expand Up @@ -208,6 +208,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
Expand All @@ -229,6 +230,7 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_STRICT_CONCURRENCY = complete;
};
name = Debug;
};
Expand Down Expand Up @@ -268,6 +270,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
Expand All @@ -282,6 +285,7 @@
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_STRICT_CONCURRENCY = complete;
VALIDATE_PRODUCT = YES;
};
name = Release;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1530"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F95AA60F29867BC90089D3EA"
BuildableName = "DemoLogger.app"
BlueprintName = "DemoLogger"
ReferencedContainer = "container:DemoLogger.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F95AA60F29867BC90089D3EA"
BuildableName = "DemoLogger.app"
BlueprintName = "DemoLogger"
ReferencedContainer = "container:DemoLogger.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "IDEPreferLogStreaming"
value = "YES"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F95AA60F29867BC90089D3EA"
BuildableName = "DemoLogger.app"
BlueprintName = "DemoLogger"
ReferencedContainer = "container:DemoLogger.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
15 changes: 5 additions & 10 deletions DemoLogger/DemoLogger/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ struct ContentView: View {
type: .os)
}
Button("Print network request") {
Task {
await writeManyStringToLog()
}
writeManyStringToLog()
}
Button("Show console (Modal)") {
isOpenedConsole = true
Expand All @@ -55,7 +53,7 @@ struct ContentView: View {
.padding()
}

func writeManyStringToLog() async {
@MainActor func writeManyStringToLog() {
let text = """
POST https://practiceapp-dev.symplast.com/AppActions/Stats (200)BODY: {
actionId = "362713CB-34EF-4C13-ABC4-6A2599643667";
Expand Down Expand Up @@ -273,12 +271,9 @@ POST https://practiceapp-dev.symplast.com/AppActions/Stats (200)BODY: {
}
[Result]: success(5941 bytes)
"""
await withTaskGroup(of: Void.self) { group in
for _ in 0..<50 {
group.addTask {
await KVKLogger.shared.network(text, type: .os)
}
}

for _ in 0..<50 {
KVKLogger.shared.network(text, type: .os)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/KVKLogger/KVKLogger+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import Foundation
import OSLog

extension Logger {
private static var subsystem = Bundle.main.bundleIdentifier ?? "kvk.logger.com"
extension Logger: @unchecked Sendable {
private static let subsystem = Bundle.main.bundleIdentifier ?? "kvk.logger.com"

static let logs = Logger(subsystem: subsystem, category: "logs")
static let networks = Logger(subsystem: subsystem, category: "networks")
Expand Down
56 changes: 37 additions & 19 deletions Sources/KVKLogger/KVKLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,33 @@ import SwiftUI
import CoreData
import OSLog

open class KVKLogger {
open class KVKLogger: @unchecked Sendable {

let store: KVKPersistenceСontroller

private var availabeSaveNetworkLogs = true


public static let shared = KVKLogger()
/// Debug Mode
/// if #DEBUG isn't setup in a project
public var isDebugMode: Bool?

public weak var delegate: KVKLoggerDelegate?
public var isEnableSaveIntoDB: Bool = true

@ObservedObject var vm = KVKLoggerVM()

public init() {
private var availabeSaveNetworkLogs = true
private init() {
store = KVKPersistenceСontroller()
}

public func configure(availabeSaveNetworkLogs: Bool = true) {
self.availabeSaveNetworkLogs = availabeSaveNetworkLogs

let urls = store.container.persistentStoreDescriptions
.compactMap({ $0.url?.lastPathComponent })
.joined(separator: ", ")
if urls.isEmpty {
debugPrint("Problem with configuring local DB!")
return
}
debugPrint("Local DB: [\(urls)] is configured!")
debugPrint("KVKLogger DB: [\(urls)] is configured!")
}

public func log(_ items: Any...,
Expand All @@ -54,7 +51,11 @@ open class KVKLogger {
let itemsTxt = items.reduce("") { (acc, item) in
acc + "\(item) "
}
handleLog(itemsTxt, type: .common, status: status, logType: type, details: details)
handleLog(itemsTxt,
type: .common,
status: status,
logType: type,
details: details)
}

public func network(_ items: Any...,
Expand All @@ -70,7 +71,12 @@ open class KVKLogger {
let itemsTxt = items.reduce("") { (acc, item) in
acc + "\(item) "
}
handleLog(itemsTxt, data: data, type: .network, status: .debug, logType: type, details: details)
handleLog(itemsTxt,
data: data,
type: .network,
status: .debug,
logType: type,
details: details)
}

private func handleLog(_ items: String,
Expand All @@ -97,7 +103,7 @@ open class KVKLogger {
break
}

if isDebugMode != false {
if let isDebugMode, isDebugMode {
printLog(items, details: details, itemType: type, status: status, type: logType, date: date)
} else {
#if DEBUG
Expand All @@ -119,27 +125,39 @@ open class KVKLogger {
date: Date) {
let iso8601Date = date.formatted(.iso8601)
let icon = "\(status.icon) "
let iconWithDate = "\(icon)\(iso8601Date)"

switch type {
case .os:
let txt: String
if let details {
status.saveOSLog("\(icon)\(iso8601Date) \(String(describing: items)) \(details)", type: itemType)
txt = "\(icon)\(iso8601Date) \(String(describing: items)) \(details)"
} else {
status.saveOSLog("\(icon)\(iso8601Date) \(String(describing: items))", type: itemType)
txt = "\(icon)\(iso8601Date) \(String(describing: items))"
}
status.saveOSLog(txt, type: itemType)
delegate?.didLog(txt)
case .debug:
if let details {
debugPrint("\(icon)\(iso8601Date)", items, details)
debugPrint(iconWithDate, items, details)
delegate?.didLog(iconWithDate, items, details)
} else {
debugPrint("\(icon)\(iso8601Date)", items)
debugPrint(iconWithDate, items)
delegate?.didLog(iconWithDate, items)
}
case .print:
if let details {
print("\(icon)\(iso8601Date)", items, details)
print(iconWithDate, items, details)
delegate?.didLog(iconWithDate, items, details)
} else {
print("\(icon)\(iso8601Date)", items)
print(iconWithDate, items)
delegate?.didLog(iconWithDate, items)
}
}
}

}

public protocol KVKLoggerDelegate: AnyObject {
func didLog(_ items: Any...)
}
6 changes: 2 additions & 4 deletions Sources/KVKLogger/KVKLoggerProxyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ struct KVKLoggerProxyView: View {

@Environment(\.managedObjectContext) private var viewContext
@Environment(\.presentationMode) private var presentationMode
@FetchRequest(fetchRequest: ItemLog.fecth(), animation: .default)

private var logs: FetchedResults<ItemLog>
@ObservedObject private var vm = KVKLoggerVM()
@FetchRequest(fetchRequest: ItemLog.request, animation: .none) private var logs: FetchedResults<ItemLog>
@StateObject private var vm = KVKLoggerVM()

var body: some View {
navigationView
Expand Down
7 changes: 7 additions & 0 deletions Sources/KVKLogger/KVKModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,13 @@ extension ItemLog {
return request
}

static var request: NSFetchRequest<ItemLog> {
let request = NSFetchRequest<ItemLog>(entityName: ItemLog.entityName)
request.predicate = NSPredicate(value: true)
request.sortDescriptors = [NSSortDescriptor(keyPath: \ItemLog.createdAt_, ascending: false)]
return request
}

static func delete(at offsets: IndexSet, for items: [ItemLog]) {
if let first = items.first, let context = first.managedObjectContext {
offsets.map { items[$0] }.forEach(context.delete)
Expand Down
8 changes: 5 additions & 3 deletions Sources/KVKLogger/KVKPersistenceСontroller.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@

import CoreData

final class KVKPersistenceСontroller {
final class KVKPersistenceСontroller: Sendable {

let container: NSPersistentContainer
let backgroundContext: NSManagedObjectContext
var viewContext: NSManagedObjectContext {
container.viewContext
}

//private let updateContext: NSManagedObjectContext
private var cacheDBURL: URL?
private let cacheDBURL: URL?

init(inMemory: Bool = false) {
let url = dataBaseURL
Expand Down Expand Up @@ -140,6 +139,9 @@ final class KVKPersistenceСontroller {

}

extension NSManagedObjectContext: @unchecked Sendable {}
extension NSManagedObjectModel: @unchecked Sendable {}

extension NSEntityDescription {
convenience init<T>(class customClass: T.Type) where T: NSManagedObject {
self.init()
Expand Down
2 changes: 1 addition & 1 deletion Sources/KVKLogger/KVKSharedData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import SwiftUI

final class KVKSharedData {
final class KVKSharedData: @unchecked Sendable {

static let shared = KVKSharedData()

Expand Down

0 comments on commit 423eb88

Please sign in to comment.