Skip to content

VakhoKontridze/VCore

Repository files navigation

VCore

Table of Contents

Intro

VCore is a Swift collection containing objects, functions, and extensions that I use in my projects.

Structure

Package files are grouped as:

  • API. Objects used for interfacing from you app/package with VCore. For instance, VCoreLocalizationManager.

  • Core

    • Extensions. Extensions.

    • Global Functions. Global functions. For instance, FIXME(_:) and TODO(_:).

    • Macros. Macros. For instance, CodingKeysGeneration.

    • Services. Services, managers, and controllers. For instance, MultiPartFormDataBuilder.

    • Utilities. Utilities. For instance, GenericStates and GenericStateModels.

  • Presentation. Views, UIViews, and UIViewControllers. For instance, SwiftUIBaseButton.

Package incudes folder Extra, which contains:

  • File Templates. File templates that can be used for accelerating workflow.

Project includes folder Documentation, which contains:

  • Various documentation

Showcase

Modal Presenter

API that allows for creating and presentation of custom modals.

For additional info, refer to "Modal Presenter" documentation.

Multipart/Form-Data Builder

MultipartFormDataBuilder with a Dictionary-based file API:

let json: [String: Any] = [
    "key": "value"
]

let files: [String: (some AnyMultipartFormDataFile)?] = [
    "profile": MultipartFormDataFile(
        mimeType: "image/jpeg",
        data: profileImage?.jpegData(compressionQuality: 0.25)
    ),

    "gallery": galleryImages?.enumerated().compactMap { (index, image) in
        MultipartFormDataFile(
            filename: "IMG_\(index).jpg",
            mimeType: "image/jpeg",
            data: image?.jpegData(compressionQuality: 0.25)
        )
    }
]

let (boundary, httpData): (String, Data) = try MultipartFormDataBuilder().build(
    json: json,
    files: files
)

let url: URL = #url("https://website.com/api/endpoint")

var request: URLRequest = .init(url: url)
request.httpMethod = "POST"
try request.addHTTPHeaderFields(
    object: MultipartFormDataAuthorizedRequestHeaderFields(
        boundary: boundary,
        token: "token"
    )
)
request.httpBody = httpData.nonEmpty

let (data, response): (Data, URLResponse) = try await URLSession.shared.data(for: request)

...

Keychain Service

KeychainService that supports custom queries, and has a dedicated property wrapper:

KeychainService.default.getData(key: "key")
KeychainService.default.setData(key: "key", value: data)
KeychainService.default.deleteData(key: "key")
@KeychainStorage("AccessToken") var accessToken: String?

Various Utilities

DigitalTimeFormatter with various configurations:

let formatter: DigitalTimeFormatter = .init()
formatter.string(from: 905_048) // "10:11:24:08"

Various SwiftUI Views

AlignedGridLayout that justifies collection of views with an alignment:

private let strings: [String] = [
    "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday",
    "Sunday"
]

var body: some View {
    AlignedGridLayout(horizontalAlignment: .center, spacing: 5) {
        ForEach(strings, id: \.self) { string in
            Text(string)
                .background(Color.accentColor.opacity(0.5))
        }
    }
    .padding()
}

Various Extensions

Initializing AttributedString with child AttributedStrings:

var body: some View {
    Text(
        AttributedString(
            string: "Lorem <a>ipsum dolor</a> sit amet, <b>consectetur adipiscing</b> elit",
            attributeContainers: [
                "a": {
                    var container: AttributeContainer = .init()
                    container.foregroundColor = Color.red
                    container.font = Font.title.weight(.ultraLight)
                    return container
                }(),
                "b": {
                    var container: AttributeContainer = .init()
                    container.foregroundColor = Color.blue
                    container.font = Font.callout.weight(.bold)
                    return container
                }()
            ]
        )
    )
    .multilineTextAlignment(.center)
    .foregroundStyle(.primary)
    .font(.body)
    .padding(.horizontal)
}

Various Global Functions

Function that calls fatalError because feature is not implemented:

func doSomething() {
    FIXME()
}

Various Macros

Macro that adds CodingKeys to a declaration:

@CodingKeysGeneration
nonisolated struct GetPostGatewayOutput: Decodable {
    @CKGProperty let id: Int
    @CKGProperty("userId") let userID: Int
    @CKGProperty let title: String
    @CKGProperty let body: String
    
    var attributes: [String: Any] = [:]
}

// Generates
internal nonsiolated enum CodingKeys: String, CodingKey {
    case id = "id"
    case userID = "userId"
    case title = "title"
    case body = "body"
}

Installation

Swift Package Manager

Add https://github.com/VakhoKontridze/VCore as a Swift Package in Xcode and follow the instructions.

Compatibility

Platform and Version Support

Package provides limited macOS, tvOS, watchOS, and visionOS support.

Versions with different majors are not directly compatible. When a new major is released, deprecated symbols are removed.

Versioning

Major. Major changes, such as big overhauls

Minor. Minor changes, such as new objects, functions, and extensions

Patch. Bug fixes and improvements

History

Version Release Date Swift SDK Comment
8.0 2026 04 09 6.3 iOS 17.0
macOS 14.0
tvOS 17.0
watchOS 10.0
visionOS 1.0
New SDK.
API changes.
7.0 2024 09 20 6.1
(7.5.2 – 7.x.x)
6.0
(7.0.1 - 7.5.1)
iOS 16.0
macOS 13.0
tvOS 16.0
watchOS 9.0
visionOS 1.0
New SDK.
API changes.
6.0 2024 02 18 5.10
(6.0.1 - 6.x.x)
5.9
(6.0.0)
iOS 15.0
macOS 12.0
tvOS 15.0
watchOS 8.0
visionOS 1.0
visionOS support.
API changes.
5.0 2023 10 08 5.9 iOS 15.0
macOS 12.0
tvOS 15.0
watchOS 8.0
New SDK.
API changes.
4.0 2022 09 14 5.8
(4.7.0 - 4.x.x)
5.7
(4.0.0 - 4.6.1)
iOS 13.0
macOS 10.15
tvOS 13.0
watchOS 6.0
API changes.
3.0 2022 05 17 5.6 iOS 13.0
macOS 10.15
tvOS 13.0
watchOS 6.0
Multiplatform support.
SPM support.
2.0 2021 12 28 5.3 iOS 13.0 iOS 13.0 support.
1.0 2021 10 07 5.3 iOS 14.0 -

For additional info, refer to the CHANGELOG.

Contact

e-mail: vakhtang.kontridze@gmail.com