Compare commits

...

3 Commits

Author SHA1 Message Date
Nikita Semenov cce06d57af fix: code review notes 2022-12-29 21:45:18 +03:00
Nikita Semenov 57d40f18ef docs: added documentation to TILogging 2022-12-29 17:33:08 +03:00
Nikita Semenov 71306b695b fix: passing of arguments to a logging message 2022-12-29 17:30:30 +03:00
28 changed files with 240 additions and 34 deletions

View File

@ -1,5 +1,10 @@
# Changelog
### 1.30.1
- **Fix**: `TILogging` bug with passing arguments to a logging message with wrapped `os_log` function;
- **Added**: Documentation for `TILogging`.
### 1.30.0
- **Added**: Base classes for encryption and decryption user token with pin code or biometry

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "LeadKit"
s.version = "1.30.0"
s.version = "1.30.1"
s.summary = "iOS framework with a bunch of tools for rapid development"
s.homepage = "https://github.com/TouchInstinct/LeadKit"
s.license = "Apache License, Version 2.0"

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIAppleMapUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of helpers for map objects clustering and interacting using Apple MapKit.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIAuth'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Login, registration, confirmation and other related actions'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIEcommerce'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Cart, products, promocodes, bonuses and other related actions'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIFoundationUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of helpers for Foundation framework classes.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIGoogleMapUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of helpers for map objects clustering and interacting using Google Maps SDK.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIKeychainUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of helpers for Keychain classes.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

24
TILogging/README.md Normal file
View File

@ -0,0 +1,24 @@
# TILogging
## Logger usage
```swift
let logger = TILogger.defaultLogger
// string interpolation
logger.log(type: .default, "🐈 Hello from \(someName), I'm machine number \(someNumer)")
// passing CVarArgs
logger.log("🐈 Hello from %@, I'm machine number %i", type: .default, someName, someNumber)
```
To pass arguments to a logging string it is essantial to pass valid formatting specifiers
| Specifier | Type | Usage |
| --------- | ---- | ----- |
| `%i`, `%d` | `Int` | `logger.verbose("🎉 int %i", 1)` |
| `%f` | `Float` | `logger.verbose("🎉 float %f", Float(1.23))` |
| `%f` | `Double` | `logger.verbose("🎉 double %f", Double(1.23))` |
| `%@` | `String` | `logger.verbose("🎉 string %@", "String")` |
> For more information about string format specifiers check the [documentation](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html)

View File

@ -0,0 +1,45 @@
//
// Copyright (c) 2022 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import os
public struct DefaultLoggerHandler: LogHandler {
public var logInfo: OSLog
public var logger: LogOutputStream?
public init(logInfo: OSLog) {
self.logInfo = logInfo
if #available(iOS 14, *) {
self.logger = Logger(logInfo)
} else {
self.logger = DefaultOutputStream()
}
}
// MARK: - LogHandler
public func log(type: OSLogType, log: OSLog?, _ message: String) {
logger?.log(type: type, log: log, message)
}
}

View File

@ -22,6 +22,6 @@
import os
public protocol LoggerRepresentable {
func log(_ message: StaticString, log: OSLog?, type: OSLogType, _ arguments: CVarArg...)
public protocol LogHandler {
func log(type: OSLogType, log: OSLog?, _ message: String)
}

View File

@ -23,7 +23,7 @@
import Foundation
import os
public struct TILogger: LoggerRepresentable {
public struct TILogger {
// MARK: - Properties
@ -31,44 +31,75 @@ public struct TILogger: LoggerRepresentable {
public static let defaultLogger = TILogger(subsystem: .defaultSubsystem ?? "", category: .pointsOfInterest)
public let logInfo: OSLog
public var loggerHandler: LogHandler?
// MARK: - Init
public init(subsystem: String, category: String) {
self.logInfo = .init(subsystem: subsystem, category: category)
self.loggerHandler = DefaultLoggerHandler(logInfo: logInfo)
}
@available(iOS 12, *)
public init(subsystem: String, category: OSLog.Category) {
self.logInfo = .init(subsystem: subsystem, category: category)
}
// MARK: - LoggerRepresentable
public func log(_ message: StaticString, log: OSLog?, type: OSLogType, _ arguments: CVarArg...) {
os_log(message, log: log ?? logInfo, type: type, arguments)
self.loggerHandler = DefaultLoggerHandler(logInfo: logInfo)
}
// MARK: - Public methods
public func log(_ message: StaticString, log: OSLog? = nil, type: OSLogType, _ arguments: CVarArg...) {
let stringMessage = String(format: "\(message)", arguments: arguments)
self.log(type: type, log: log, stringMessage)
}
public func log(type: OSLogType, log: OSLog? = nil, _ message: String) {
loggerHandler?.log(type: type, log: log ?? logInfo, message)
}
public func verbose(_ message: StaticString, _ arguments: CVarArg...) {
self.log(message, log: logInfo, type: .default, arguments)
let stringMessage = String(format: "\(message)", arguments: arguments)
self.log(type: .default, stringMessage)
}
public func verbose(_ message: String) {
self.log(type: .default, message)
}
public func info(_ message: StaticString, _ arguments: CVarArg...) {
self.log(message, log: logInfo, type: .info, arguments)
let stringMessage = String(format: "\(message)", arguments: arguments)
self.log(type: .info, stringMessage)
}
public func info(_ message: String) {
self.log(type: .info, message)
}
public func debug(_ message: StaticString, _ arguments: CVarArg...) {
self.log(message, log: logInfo, type: .debug, arguments)
let stringMessage = String(format: "\(message)", arguments: arguments)
self.log(type: .debug, stringMessage)
}
public func debug(_ message: String) {
self.log(type: .debug, message)
}
public func error(_ message: StaticString, _ arguments: CVarArg...) {
self.log(message, log: logInfo, type: .error, arguments)
let stringMessage = String(format: "\(message)", arguments: arguments)
self.log(type: .error, stringMessage)
}
public func error(_ message: String) {
self.log(type: .error, message)
}
public func fault(_ message: StaticString, _ arguments: CVarArg...) {
self.log(message, log: logInfo, type: .fault, arguments)
let stringMessage = String(format: "\(message)", arguments: arguments)
self.log(type: .fault, stringMessage)
}
public func fault(_ message: String) {
self.log(type: .fault, message)
}
}

View File

@ -0,0 +1,44 @@
//
// Copyright (c) 2022 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import os
import _SwiftOSOverlayShims
public struct DefaultOutputStream: LogOutputStream {
public func log(type: OSLogType, log: OSLog?, _ message: String) {
guard let logInfo = log, logInfo.isEnabled(type: type) else {
return
}
let ra = _swift_os_log_return_address()
var mutableMessage = message
mutableMessage.withUTF8 { (buf: UnsafeBufferPointer<UInt8>) in
buf.baseAddress?.withMemoryRebound(to: CChar.self, capacity: buf.count) { str in
withVaList([]) { valist in
_swift_os_log(#dsohandle, ra, logInfo, type, str, valist)
}
}
}
}
}

View File

@ -0,0 +1,27 @@
//
// Copyright (c) 2022 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import os
public protocol LogOutputStream {
func log(type: OSLogType, log: OSLog?, _ message: String)
}

View File

@ -0,0 +1,30 @@
//
// Copyright (c) 2022 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import os
@available(iOS 14.0, *)
extension Logger: LogOutputStream {
public func log(type: OSLogType, log: OSLog?, _ message: String) {
self.log(level: type, "\(message)")
}
}

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TILogging'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Logging API'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIMapUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of helpers for map objects clustering and interacting.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIMoyaNetworking'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Moya + Swagger network service.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TINetworking'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Swagger-frendly networking layer helpers.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TINetworkingCache'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Caching results of EndpointRequests.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIPagination'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Generic pagination component.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TISwiftUICore'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Core UI elements: protocols, views and helpers.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TISwiftUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Bunch of useful helpers for Swift development.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TITableKitUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of helpers for TableKit classes.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TITransitions'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of custom transitions to present controller. '
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIUIElements'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Bunch of useful protocols and views.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIUIKitCore'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Core UI elements: protocols, views and helpers.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIYandexMapUtils'
s.version = '1.30.0'
s.version = '1.30.1'
s.summary = 'Set of helpers for map objects clustering and interacting using Yandex Maps SDK.'
s.homepage = 'https://github.com/TouchInstinct/LeadKit/tree/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }