5 Commits

Author SHA1 Message Date
a659a9399c Merge pull request 'Update LCEssentials+API.swift' (#8) from fix/api/mainactor-session-hang into main
Reviewed-on: #8
2026-07-07 13:21:09 -03:00
Daniel Arantes Loverde
03044604fd Update LCEssentials+API.swift 2026-07-07 13:15:45 -03:00
Daniel Arantes Loverde
2c781fbac6 Update LCEssentials+API.swift 2026-06-06 11:00:08 -03:00
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
7 changed files with 51 additions and 22 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.DS_Store
/.build
/build
/Packages
xcuserdata/
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,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Autor: Daniel Arantes Loverde

View File

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

View File

@@ -2,7 +2,7 @@
import PackageDescription
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 cryptoPackageURL = isLocalDevelopment

View File

@@ -59,12 +59,11 @@ And then import `LCEssentials ` wherever you import UIKit or SwiftUI
import LCEssentials
```
Author:
----
Any question or doubts, please send thru email
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 "Loverde Co. Github")](https://github.com/loverde-co)
Autor: Daniel Arantes Loverde

View File

@@ -26,10 +26,8 @@ import Foundation
import Security
#endif
#if canImport(UIKit)
#if canImport(UIKit)
import UIKit
#endif
#endif
/// A generic `Result` enumeration to represent either a success `Value` or a failure `Error`.
public enum Result<Value, Error: Swift.Error> {
@@ -47,6 +45,8 @@ public enum httpMethod: String {
case get = "GET"
/// The PUT method.
case put = "PUT"
/// The PATCH method.
case patch = "PATCH"
/// The DELETE method.
case delete = "DELETE"
}
@@ -90,7 +90,7 @@ public struct API {
/// - Parameters:
/// - 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.
/// - 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.
/// - 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`.
@@ -110,8 +110,8 @@ public struct API {
persistConnection: Bool = false) async throws -> T {
if let urlReq = URL(string: url.replaceURL(params as? [String: Any] ?? [:] )) {
var request = URLRequest(url: urlReq, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 30)
if method == .post || method == .put || method == .delete {
var request = URLRequest(url: urlReq, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: timeoutInterval)
if method == .post || method == .put || method == .delete || method == .patch {
if let params = params as? [String: Any],
let pathFile = params["file"] as? String,
let fileURL = URL(string: pathFile) {
@@ -194,14 +194,31 @@ public struct API {
API.requestLOG(method: method, request: request)
}
let session = URLSession(
configuration: .default,
delegate: URLSessionDelegateHandler(
certData: API.certData,
password: API.certPassword
),
delegateQueue: nil
)
// Only spin up a dedicated session (with its own @MainActor
// delegate hop for every TLS/auth challenge) when client
// certificate auth is actually configured. Creating one of
// these per request unconditionally and never invalidating
// it could stall the async challenge callback waiting on an
// already-busy MainActor, hanging the request indefinitely with
// no timeout or error ever surfacing. The common case (no
// client cert) uses the shared session, which has none of this
// risk and is what URLSession is designed to be reused as.
let usesCertSession = API.certData != nil
let session: URLSession = usesCertSession
? URLSession(
configuration: .default,
delegate: URLSessionDelegateHandler(
certData: API.certData,
password: API.certPassword
),
delegateQueue: nil
)
: URLSession.shared
defer {
if usesCertSession {
session.finishTasksAndInvalidate()
}
}
do {
let (data, response) = try await session.data(for: request)

View File

@@ -47,6 +47,8 @@ class LCENavigationState: ObservableObject {
@Published var title: (any View) = Text("")
/// The subtitle view of the navigation bar.
@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.
@@ -79,7 +81,7 @@ public struct LCENavigationView<Content: View>: View {
/// The body of the `LCENavigationView`.
public var body: some View {
VStack {
VStack(spacing: 0) {
if !state.hideNavigationBar {
NavigationBarView
}
@@ -100,7 +102,7 @@ public struct LCENavigationView<Content: View>: View {
.font(.headline)
.padding()
.background {
Color.clear.ignoresSafeArea(edges: .top)
state.navigationBarBackgroundColor.ignoresSafeArea(edges: .top)
}
}
@@ -217,6 +219,14 @@ public struct LCENavigationView<Content: View>: View {
state.hideNavigationBar = hide
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.