# ObjectBox Swift Sources This folder contains the Swift sources for ObjectBox. This is the API you primarily touch when working with ObjectBox. These Swift classes internally use [ObjectBox's C API](https://github.com/objectbox/objectbox-c), implemented by the libObjectBoxCore library. ## Repository Contents - `ios-framework/`: The ObjectBox Swift framework. Uses a special static ObjectBox C library for macOS/iOS, see `fetch_dependencies.command` below. - `external/`: git submodule and/or pre-built binary container. This contains the ObjectBoxCore static libraries and the [ObjectBox Swift code generator](https://github.com/objectbox/objectbox-swift-generator). **Scripts** and how they depend on each other (subject to future simplifications): - `ios-framework/Makefile`: combines `fetch_dependencies.command` and a Carthage build to create the Swift framework. - `fetch_dependencies.command`: populates `external/objectbox-static` with libObjectBoxCore. libObjectBoxCore is a crucial requirement build the Swift framework. - `create-xcframework.sh`: builds the multi-platform archive containing binaries for multiple platforms and architectures. ### Tests ObjectBox comes with a couple of tests of different categories: * Unit tests: `ios-framework/CommonTests`, based on XCTestCase * Integration tests "CodeGen": `ios-framework/CodeGenTests` run via script (for now only via Xcode/xcodebuild); uses a separate Xcode project and an ObjectBox generator executable to generate actual binding classes. [README](ios-framework/CodeGenTests/README.md) * Integration tests "IntegrationTests": `ios-framework/IntegrationTests`, currently not maintained, run via script; somewhat similar to CodeGen; subject to a general clean up; see also its [README](ios-framework/IntegrationTests/Readme.md) * External integration test project: https://github.com/objectbox/objectbox-swift-integration-test runs "real projects" with "full ObjectBox round-trip" on internal CI and CircleCI ## Development * Ensure the latest Xcode is installed (Swift 5.3+, command line tools should be included). * Ensure [homebrew](https://brew.sh/) is installed, e.g. setup.sh uses it. * Ensure [rbenv](https://github.com/rbenv/rbenv) and ruby is installed, see section below. * Run `./setup.sh` or see [setup.sh](setup.sh) and only run what is needed. * Runs `brew bundle` to install or update basic build tools including [Carthage](https://github.com/Carthage/Carthage) (see [Brewfile](Brewfile)). * Runs `bundle install` to install or update cocoapods and jazzy (see [Gemfile](Gemfile)). Open the Xcode project in `ios-framework/ObjectBox.xcodeproj`. See section below on how it is organized. From the command line: ```shell # Enter the framework directory cd ios-framework/ # Build the generator make build_generator # Build the framework make build_framework # Execute all tests make test # Execute specific tests make unit_tests make integration_tests ``` ### Generate the Documentation Inside `ios-framework/` jazzy is configured inside [Makefile](ios-framework/Makefile): ```shell cd ios-framework/ make generate_docs ``` Jazzy uses the [README.md](ios-framework/README.md) as a front page. The result is stored inside `ios-framework/docs/swift_output/`. ### Xcode Project Organization You look at and build the framework itself via `ios-framework/ObjectBox.xcodeproj`. * `ObjectBox.xcproject` targets * `ObjectBox-macOS` builds the `ObjectBox.framework` for the macOS platform * `ObjectBoxTests-macOS` builds the unit tests for the macOS framework * `ObjectBox-iOS` builds the `ObjectBox.framework` for the iOS platform * `ObjectBoxTests-iOS` builds the unit tests for the iOS framework * `iOS-Fat-Framework` builds a universal binary of the iOS framework needed for distribution, with code both for device and simulator * `CodeGenTests` Runs a shell script that performs integration tests for various features. This will run the Sourcery code generator over files and then compile the result against the framework. * `ObjectBox.xcproject` main groups and directories * `CommonSource` contains all code to be shared by the framework of the macOS and iOS platforms. * `ObjectBox.h` is the framework umbrella header where all public C and ObjC header files are listed. These are either intended for use by app developers, or required to be visible for the Swift extensions. * `ObjectBoxC.h` is a modified version of the C API's `objectbox.h` header generated by the `generate_ObjectBoxC_header.rb` script so it can be imported into Swift and doesn't have a name collision with `ObjectBox.h` on case-insensitive file systems. * The directory itself contains general purpose types like `Store` and `Box`. The important sub-groups are `Entities`, `Relation`, and `Query`. * `CommonTests` contains all code to be shared by tests for the macOS and iOS platforms * `ObjectBox-macOS` contains macOS-specific files, including the framework's Info.plist * `ObjectBox-iOS` contains iOS-specific files, including the framework's Info.plist ### Build notes * SwiftLint (macOS build only): calls `swiftlint lint --config .swiftlint-macOS.yml` * Edit .swiftlint-macOS.yml file to customize (e.g. "id" is OK despite less than 3 chars) ## Caveats To make to-one relations and their backlinks work, the `Entity` protocol was extended to require (1) an `EntityType` typealias, and (2) an `_id` property. The former was needed to disambiguate which concrete entity we're talking about when all we have is the protocol type, and this in turn is needed to specify the generic type requirement of `Id`. Since the `Entity` protocol itself is intended to be no more than a convenient code annotation (which Sourcery can filter on), it's advised to get rid of this as soon as possible and find a different way to get the data needed for associations in Swift, for example using an `IdGetter` like we do in Java and injecting it into `EntityInfo` from generated code.