5 Commits
1.0.6 ... 1.0.9

Author SHA1 Message Date
Daniel Arantes Loverde
966b439277 Update LCEssentials+API.swift 2026-06-06 10:53:16 -03:00
Daniel Arantes Loverde
a24b79f443 only remote crypto kit 2026-05-24 10:26:25 -03:00
c0eb5f95c6 Merge pull request 'fix: update keyboard notification handling for Swift concurrency' (#7) from bugfix/snackbar_for_iOS26 into main
Reviewed-on: #7
2026-04-07 11:22:02 -03:00
a15d95ed59 Merge branch 'main' into bugfix/snackbar_for_iOS26 2026-04-07 11:21:55 -03:00
Daniel Arantes Loverde
40581d791a fix: update keyboard notification handling for Swift concurrency
Keep snackbar keyboard animations on the main actor and read UIKit keyboard values using the expected notification payload types.

Made-with: Cursor
2026-04-07 11:19:39 -03:00
8 changed files with 51 additions and 55 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.DS_Store .DS_Store
/.build /.build
/build
/Packages /Packages
xcuserdata/ xcuserdata/
DerivedData/ DerivedData/

View File

@@ -22,3 +22,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
Autor: Daniel Arantes Loverde

View File

@@ -3,8 +3,8 @@
"pins" : [ "pins" : [
{ {
"identity" : "lcecryptokitbinary", "identity" : "lcecryptokitbinary",
"kind" : "localSourceControl", "kind" : "remoteSourceControl",
"location" : "/Users/loverde_co/Documents/Loverde_JOBs/Producao/Loverde Co/GIT/XCODE/Repositorios/LCECryptoKit/PrivateLib/LCECryptoKitBinary", "location" : "https://60c260c85d3a2fe840411b0ff98f521b5eca3c56@git.loverde.com.br/Loverde-Company-LTDA/LCECryptoKitBinary.git",
"state" : { "state" : {
"revision" : "2c5c47cebef40a8adc5557d071a35be405c05e30", "revision" : "2c5c47cebef40a8adc5557d071a35be405c05e30",
"version" : "1.0.2" "version" : "1.0.2"

View File

@@ -2,7 +2,7 @@
import PackageDescription import PackageDescription
import Foundation import Foundation
let isLocalDevelopment = FileManager.default.fileExists(atPath: "../LCECryptoKit/PrivateLib/LCECryptoKitBinary") let isLocalDevelopment = false //FileManager.default.fileExists(atPath: "../LCECryptoKit/PrivateLib/LCECryptoKitBinary")
let enableCryptoBinary = ProcessInfo.processInfo.environment["LCE_ENABLE_CRYPTO_BINARY"] != "0" let enableCryptoBinary = ProcessInfo.processInfo.environment["LCE_ENABLE_CRYPTO_BINARY"] != "0"
let cryptoPackageURL = isLocalDevelopment let cryptoPackageURL = isLocalDevelopment

View File

@@ -59,12 +59,11 @@ And then import `LCEssentials ` wherever you import UIKit or SwiftUI
import LCEssentials import LCEssentials
``` ```
Author:
----
Any question or doubts, please send thru email Any question or doubts, please send thru email
Daniel Arantes Loverde - <daniel@loverde.com.br> Daniel Arantes Loverde - <daniel@loverde.com.br>
[![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "My Resume")](https://github.com/loverde-co/resume/) [![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "My Resume")](https://github.com/loverde-co/resume/)
[![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "Loverde Co. Github")](https://github.com/loverde-co) [![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "Loverde Co. Github")](https://github.com/loverde-co)
Autor: Daniel Arantes Loverde

View File

@@ -26,7 +26,6 @@ import Foundation
import Security import Security
#endif #endif
#if canImport(UIKit) #if canImport(UIKit)
#if canImport(UIKit)
import UIKit import UIKit
#endif #endif
#endif #endif
@@ -47,6 +46,8 @@ public enum httpMethod: String {
case get = "GET" case get = "GET"
/// The PUT method. /// The PUT method.
case put = "PUT" case put = "PUT"
/// The PATCH method.
case patch = "PATCH"
/// The DELETE method. /// The DELETE method.
case delete = "DELETE" case delete = "DELETE"
} }
@@ -90,7 +91,7 @@ public struct API {
/// - Parameters: /// - Parameters:
/// - url: The URL string for the request. /// - url: The URL string for the request.
/// - params: Optional parameters for the request. Can be `[String: Any]` for JSON/form-data, or `Data` for raw body. /// - params: Optional parameters for the request. Can be `[String: Any]` for JSON/form-data, or `Data` for raw body.
/// - method: The HTTP method to use for the request (`.get`, `.post`, `.put`, `.delete`). /// - method: The HTTP method to use for the request (`.get`, `.post`, `.put`, `.delete`,`.patch` ).
/// - headers: Optional custom HTTP headers to be added to the request. These override default headers if there are conflicts. /// - headers: Optional custom HTTP headers to be added to the request. These override default headers if there are conflicts.
/// - jsonEncoding: A boolean indicating whether parameters should be JSON encoded. Defaults to `true`. /// - jsonEncoding: A boolean indicating whether parameters should be JSON encoded. Defaults to `true`.
/// - debug: A boolean indicating whether to print debug logs for the request and response. Defaults to `true`. /// - debug: A boolean indicating whether to print debug logs for the request and response. Defaults to `true`.
@@ -110,8 +111,8 @@ public struct API {
persistConnection: Bool = false) async throws -> T { persistConnection: Bool = false) async throws -> T {
if let urlReq = URL(string: url.replaceURL(params as? [String: Any] ?? [:] )) { if let urlReq = URL(string: url.replaceURL(params as? [String: Any] ?? [:] )) {
var request = URLRequest(url: urlReq, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 30) var request = URLRequest(url: urlReq, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: timeoutInterval)
if method == .post || method == .put || method == .delete { if method == .post || method == .put || method == .delete || method == .patch {
if let params = params as? [String: Any], if let params = params as? [String: Any],
let pathFile = params["file"] as? String, let pathFile = params["file"] as? String,
let fileURL = URL(string: pathFile) { let fileURL = URL(string: pathFile) {

View File

@@ -233,54 +233,37 @@ public extension LCSnackBarView {
/// Handles the `keyboardWillShowNotification` to adjust the snackbar's position. /// Handles the `keyboardWillShowNotification` to adjust the snackbar's position.
/// - Parameter notification: The `Notification` object containing keyboard information. /// - Parameter notification: The `Notification` object containing keyboard information.
@objc private func keyboardWillShow(_ notification: Notification?) -> Void { @MainActor
@objc private func keyboardWillShow(_ notification: Notification?) {
if let info = notification?.userInfo { guard let info = notification?.userInfo else { return }
systemKeyboardVisible = true systemKeyboardVisible = true
//
let curveUserInfoKey = UIResponder.keyboardAnimationCurveUserInfoKey
let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey
let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey
//
var animationCurve: UIView.AnimationOptions = .curveEaseOut
var animationDuration: TimeInterval = 0.25
var height:CGFloat = 0.0
// Getting keyboard animation. let animationCurveRaw = (info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue
if let curve = info[curveUserInfoKey] as? UIView.AnimationOptions { ?? UInt(UIView.AnimationCurve.easeOut.rawValue)
animationCurve = curve let animationDuration = (info[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue
} ?? 0.25
let keyboardFrame = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
?? .zero
let height = keyboardFrame.height
let animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw << 16)
// Getting keyboard animation duration UIView.animate(
if let duration = info[durationUserInfoKey] as? TimeInterval { withDuration: animationDuration,
animationDuration = duration
}
// Getting UIKeyboardSize.
if let kbFrame = info[frameEndUserInfoKey] as? CGRect {
height = kbFrame.size.height
}
DispatchQueue.main.async { [weak self] in
UIView.animate(withDuration: animationDuration,
delay: 0, delay: 0,
options: animationCurve, options: animationCurve
animations: { ) { [weak self] in
self?.frame.origin.y += height self?.frame.origin.y += height
})
}
} }
} }
/// Handles the `keyboardWillHideNotification`. /// Handles the `keyboardWillHideNotification`.
/// - Parameter notification: The `Notification` object. /// - Parameter notification: The `Notification` object.
@objc private func keyboardWillHide(_ notification: Notification?) -> Void { @MainActor
DispatchQueue.main.async { [weak self] in @objc private func keyboardWillHide(_ notification: Notification?) {
self?.systemKeyboardVisible = false systemKeyboardVisible = false
// keyboard is hidded // keyboard is hidded
} }
}
/// Updates the snackbar's style properties, such as width and corner radius, based on `_style`. /// Updates the snackbar's style properties, such as width and corner radius, based on `_style`.
private func updateStyle() { private func updateStyle() {

View File

@@ -47,6 +47,8 @@ class LCENavigationState: ObservableObject {
@Published var title: (any View) = Text("") @Published var title: (any View) = Text("")
/// The subtitle view of the navigation bar. /// The subtitle view of the navigation bar.
@Published var subTitle: (any View) = Text("") @Published var subTitle: (any View) = Text("")
/// The background color of the navigation bar.
@Published var navigationBarBackgroundColor: Color = .clear
} }
/// `LCENavigationView` is a SwiftUI `View` that provides a customizable navigation bar. /// `LCENavigationView` is a SwiftUI `View` that provides a customizable navigation bar.
@@ -79,7 +81,7 @@ public struct LCENavigationView<Content: View>: View {
/// The body of the `LCENavigationView`. /// The body of the `LCENavigationView`.
public var body: some View { public var body: some View {
VStack { VStack(spacing: 0) {
if !state.hideNavigationBar { if !state.hideNavigationBar {
NavigationBarView NavigationBarView
} }
@@ -100,7 +102,7 @@ public struct LCENavigationView<Content: View>: View {
.font(.headline) .font(.headline)
.padding() .padding()
.background { .background {
Color.clear.ignoresSafeArea(edges: .top) state.navigationBarBackgroundColor.ignoresSafeArea(edges: .top)
} }
} }
@@ -217,6 +219,14 @@ public struct LCENavigationView<Content: View>: View {
state.hideNavigationBar = hide state.hideNavigationBar = hide
return self return self
} }
/// Sets the background color for the navigation bar.
/// - Parameter color: The color to use as the navigation bar background.
/// - Returns: The `LCENavigationView` instance for chaining.
public func setNavigationBarBackgroundColor(_ color: Color) -> LCENavigationView {
state.navigationBarBackgroundColor = color
return self
}
} }
/// Extension to `FormatStyle` to format any value as a string. /// Extension to `FormatStyle` to format any value as a string.