Skip to content

Commit b954ce8

Browse files
Merge branch '255-clean-up-docs' into 'dev'
Source: Clean internal details from README, add required setup files See merge request objectbox/objectbox-swift-public!12
2 parents 5ff0d80 + 3b82e9a commit b954ce8

File tree

5 files changed

+118
-340
lines changed

5 files changed

+118
-340
lines changed

Source/.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.0.5

Source/Brewfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
brew "swiftlint"
2+
brew "carthage"
3+
brew "cmake"
4+
brew "ccache"

Source/README.md

Lines changed: 45 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
1-
ObjectBox Swift Sources
2-
=======================
1+
# ObjectBox Swift Sources
2+
33
This folder contains the Swift sources for ObjectBox. This is the API you primarily touch when working with ObjectBox.
44

55
These Swift classes internally use [ObjectBox's C API](https://github.com/objectbox/objectbox-c), implemented by the libObjectBoxCore library.
66

7-
Repository Contents
8-
-------------------
9-
- `ios-framework/`: The Cocoa Swift framework.
10-
- `docs/swift_output/`: The generated framework documentation.
7+
## Repository Contents
8+
9+
- `ios-framework/`: The ObjectBox Swift framework. Uses a special static ObjectBox C library for macOS/iOS, see `fetch_dependencies.command` below.
1110
- `external/`: git submodule and/or pre-built binary container.
12-
This contains the ObjectBoxCore static libraries and our code generator.
13-
- `docs/`: Documentation and discussion of concepts, ideas, and approaches to bring ObjectBox to Swift.
11+
This contains the ObjectBoxCore static libraries and the [ObjectBox Swift code generator](https://github.com/objectbox/objectbox-swift-generator).
1412

1513
**Scripts** and how they depend on each other (subject to future simplifications):
1614

15+
- `ios-framework/Makefile`: combines `fetch_dependencies.command` and a Carthage build to create the Swift framework.
1716
- `fetch_dependencies.command`: populates `external/objectbox-static` with libObjectBoxCore.
1817
libObjectBoxCore is a crucial requirement build the Swift framework.
19-
- `ios-framework/Makefile`: combines `fetch_dependencies.command` and a Carthage build to create the Swift framework.
20-
- `.gitlab-ci.yml` calls make targets of `ios-framework/Makefile`
2118
- `create-xcframework.sh`: builds the multi-platform archive containing binaries for multiple platforms and architectures.
22-
- `ios-framework/cocoapod/make-release.command`: prepares a Cocoapods deployment.
23-
- Builds ObjectBox Generator (based on Sourcery)
24-
- Builds the Swift framework using `ios-framework/Makefile`
25-
- Creates deployable zips
26-
- Creates ObjectBox.podspec & Package.swift
27-
- Optionally pushes the pod to the Cocoapods repo (staging or trunk)
28-
29-
Tests
30-
-----
19+
20+
### Tests
21+
3122
ObjectBox comes with a couple of tests of different categories:
3223

3324
* Unit tests: `ios-framework/CommonTests`, based on XCTestCase
@@ -39,71 +30,50 @@ ObjectBox comes with a couple of tests of different categories:
3930
* External integration test project: https://github.com/objectbox/objectbox-swift-integration-test
4031
runs "real projects" with "full ObjectBox round-trip" on internal CI and CircleCI
4132

42-
Setup
43-
-----
44-
* Install latest Xcode (Swift 5.3+) with command line tools prepared to build from the shell
45-
* Note: After Xcode updates, you may have to reinstall the CLI tools via `xcode-select --install`
46-
* Ensure you have homebrew (e.g. setup.sh uses it to install [Carthage](https://github.com/Carthage/Carthage))
47-
* Using homebrew, install basic build tools like cmake and ccache
48-
* Run `./setup.sh` (see the [setup.sh](setup.sh) file for more comments if you want)
49-
* Open Xcode project in ios-framework/ObjectBox.xcodeproj
50-
51-
To build the project for release:
52-
53-
* Run `cd ios-framework/; make all` to build the frameworks from source with Carthage
54-
* The `ios-framework/cocoapod/make-release.command` script can be double-clicked to build a release-ready archive and Podspec & SPM files.
55-
56-
### Generate the Documentation
57-
58-
You need to have [jazzy](https://github.com/realm/jazzy) installed to generate documentation from the Swift code:
59-
60-
* Install jazzy. Run `bundle install` from the project root to install jazzy as a local dependency.
61-
* Inside `ios-framework/`, jazzy is configured inside [Makefile](ios-framework/Makefile).
62-
Run `make generate_swift_docs`, which will execute `bundle exec jazzy` with all the configuration options set for you.
63-
* Jazzy uses the [README.md](ios-framework/README.md) as a front page
64-
* The result is stored inside `ios-framework/docs/swift_output/`.
65-
66-
Distributing the Framework
67-
--------------------------
68-
See also the [how-to release document](docs/how-to-release-objectbox-swift.md).
69-
70-
Distribution of the framework as closed source works across these channels:
71-
72-
- **CocoaPods**, by setting the `.podspec`'s `vendored_frameworks` to point to the build products of the macOS and iOS framework targets.
73-
(The `make-release.command` script takes care of this)
74-
- **Carthage**, by uploading a `.zip` of the frameworks as binary attachments to a GitHub's release.
33+
## Development
7534

76-
## Build with Carthage
35+
* Ensure the latest Xcode is installed (Swift 5.3+, command line tools should be included).
36+
* Ensure [homebrew](https://brew.sh/) is installed, e.g. setup.sh uses it.
37+
* Ensure [rbenv](https://github.com/rbenv/rbenv) and ruby is installed, see section below.
38+
* Run `./setup.sh` or see [setup.sh](setup.sh) and only run what is needed.
39+
* Runs `brew bundle` to install or update basic build tools including [Carthage](https://github.com/Carthage/Carthage) (see [Brewfile](Brewfile)).
40+
* Runs `bundle install` to install or update cocoapods and jazzy (see [Gemfile](Gemfile)).
7741

78-
The easiest way to build the framework is using the dependency manager [Carthage][] as a build tool:
42+
Open the Xcode project in `ios-framework/ObjectBox.xcodeproj`. See section below on how it is organized.
7943

80-
$ carthage build --no-skip-current
44+
From the command line:
8145

82-
In addition to building the dependencies (there are none), the `--no-skip-current` flag ensures the current project itself is built.
83-
That's what we'll be shipping with both Carthage and CocoaPods.
46+
```shell
47+
# Enter the framework directory
48+
cd ios-framework/
8449

85-
To generate the Carthage-compatible release:
50+
# Build the generator
51+
make build_generator
52+
# Build the framework
53+
make build_framework
8654

87-
$ carthage archive ObjectBox
88-
89-
This will put all build products in a `.zip`. On client machines, Carthage downloads and unzips the contents into their local framework build directory next to other dependencies that may be built from source.
55+
# Execute all tests
56+
make test
57+
# Execute specific tests
58+
make unit_tests
59+
make integration_tests
60+
```
9061

91-
## Build without Carthage
62+
### Generate the Documentation
9263

93-
You need a "fat" framework that works both on the iPhone Simulator on macOS (x64) and real devices (arm64).
64+
Inside `ios-framework/` jazzy is configured inside [Makefile](ios-framework/Makefile):
9465

95-
The `iOS-Fat-Framework` target compiles for both architectures and merges the results into a single build product: a single framework, and a single dSYM file.
66+
```shell
67+
cd ios-framework/
68+
make generate_docs
69+
```
9670

97-
- Select the `iOS-Fat-Framework` scheme.
98-
- Make sure the scheme's Build Configuration is set to "Release".
99-
- Make sure the target device is "Generic iOS Device" or a real device, not a simulator. (Or else you only get a `-iphonesimulator` build and `lipo` fails.)
71+
Jazzy uses the [README.md](ios-framework/README.md) as a front page.
10072

101-
Find the result in `ios-framework/ObjectBox-iOS-Aggregate.build/`
73+
The result is stored inside `ios-framework/docs/swift_output/`.
10274

103-
This is essentially what comes for free with Carthage. Xcode 10 changed the build system a bit. The build script is adjusted accordingly. But you may have to adjust the script a bit for future Xcode versions; that's another point of failure you wouldn't have to worry about with Carthage.
75+
### Xcode Project Organization
10476

105-
Swift Framework Project Organization
106-
------------------------------------
10777
You look at and build the framework itself via `ios-framework/ObjectBox.xcodeproj`.
10878

10979
* `ObjectBox.xcproject` targets
@@ -122,79 +92,11 @@ You look at and build the framework itself via `ios-framework/ObjectBox.xcodepro
12292
* `ObjectBox-macOS` contains macOS-specific files, including the framework's Info.plist
12393
* `ObjectBox-iOS` contains iOS-specific files, including the framework's Info.plist
12494

125-
Build notes
126-
-----------
95+
### Build notes
96+
12797
* SwiftLint (macOS build only): calls `swiftlint lint --config .swiftlint-macOS.yml`
12898
* Edit .swiftlint-macOS.yml file to customize (e.g. "id" is OK despite less than 3 chars)
12999

130-
Caveats
131-
-------
132-
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<T>`. 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<T>` like we do in Java and injecting it into `EntityInfo` from generated code.
133-
134-
How to Use the Framework
135-
------------------------
136-
- The example project in this repository is a good starting point to see how to interact with the framework.
137-
- Have a look at the `ios-framework/CommonTests/Test Entities/RelatedEntities.swift` file to see how self-contained entity code & generated cursor code look. You should be able to copy and paste the contents into a test app if you want. This should also help in case you cannot get the code generator running in 2024 :)
138-
139-
## How to Write App Code
140-
141-
Define entities:
142-
143-
import ObjectBox
144-
final class Person: Entity {
145-
var id: Id<Person> = 0
146-
var age: Int
147-
var name: String
148-
var birthdate: Date
149-
150-
required init() {
151-
self.name = ""
152-
self.age = 0
153-
self.birthdate = Date()
154-
}
155-
}
156-
157-
Properties have to be mutable so they can be set after initialization in generated code.
158-
159-
Run the code generator. This will configure a `ModelBuilder` and get the `Data` representation of it. It also generates an `EntityBinding` implementation for each entity with the property offsets calculated for you. Doing this manually is error-prone and tedious.
160-
161-
Create and set up the ObjectBox types:
162-
163-
let directory: String = "/path/to/the/store"
164-
let store: Store = try! Store(directoryPath: directory)
165-
let personBox: Box<Person> = store.box(for: Person.self)
166-
167-
This will call into the the generated (!) initializer that uses the private model builder's `modelBytes()` automatically.
168-
169-
Then you're all set to use entities with ObjectBox:
170-
171-
let person = Person(name: "Fry", age: 28, birthdate: Date(timeIntervalSince1970: 123456))
172-
assert(person.id.value == 0) // Initial value
173-
174-
let personId = try personBox.put(person)
175-
assert(person.id == personId) // ID is set after put
176-
177-
// Get by ID
178-
assert(personBox.get(personId) != nil)
179-
180-
// Get collections of entities
181-
_ = personBox.all()
182-
_ = personBox.query({ Person.name == "Fry" }).build().find()
183-
184-
That's it, it works now!
185-
186-
Testing from commandline
187-
------------------------
188-
To execute all unit tests:
189-
```shell script
190-
cd ios-framework
191-
make unit_test
192-
```
193-
194-
To execute a specific test. Change the last argument to specify your test. You can also execute a group/class by removing the last one/two parts of the filter.
195-
Note: `xcpretty` cleans up the output so you wan't see all the compiler calls but it also hides failed tests output. So once you see a failure, run without `xcpretty` to read the error.
196-
```shell script
197-
xcodebuild -derivedDataPath ./DerivedData test -project ObjectBox.xcodeproj -scheme ObjectBox-macOS -destination 'platform=OS X,arch=x86_64' -only-testing ObjectBoxTests-macOS/StoreTests/test32vs64BitForOs | xcpretty
198-
xcodebuild -derivedDataPath ./DerivedData test -project ObjectBox.xcodeproj -scheme ObjectBox-iOS -destination 'platform=iOS Simulator,name=iPhone 11' -only-testing ObjectBoxTests-iOS/StoreTests/test32vs64BitForOs | xcpretty
199-
```
100+
## Caveats
200101

102+
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<T>`. 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<T>` like we do in Java and injecting it into `EntityInfo` from generated code.

0 commit comments

Comments
 (0)