You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This folder contains the Swift sources for ObjectBox. This is the API you primarily touch when working with ObjectBox.
4
4
5
5
These Swift classes internally use [ObjectBox's C API](https://github.com/objectbox/objectbox-c), implemented by the libObjectBoxCore library.
6
6
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.
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).
14
12
15
13
**Scripts** and how they depend on each other (subject to future simplifications):
16
14
15
+
-`ios-framework/Makefile`: combines `fetch_dependencies.command` and a Carthage build to create the Swift framework.
17
16
-`fetch_dependencies.command`: populates `external/objectbox-static` with libObjectBoxCore.
18
17
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`
21
18
-`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
+
31
22
ObjectBox comes with a couple of tests of different categories:
32
23
33
24
* Unit tests: `ios-framework/CommonTests`, based on XCTestCase
@@ -39,71 +30,50 @@ ObjectBox comes with a couple of tests of different categories:
39
30
* External integration test project: https://github.com/objectbox/objectbox-swift-integration-test
40
31
runs "real projects" with "full ObjectBox round-trip" on internal CI and CircleCI
41
32
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
75
34
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)).
77
41
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.
79
43
80
-
$ carthage build --no-skip-current
44
+
From the command line:
81
45
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/
84
49
85
-
To generate the Carthage-compatible release:
50
+
# Build the generator
51
+
make build_generator
52
+
# Build the framework
53
+
make build_framework
86
54
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
+
```
90
61
91
-
##Build without Carthage
62
+
### Generate the Documentation
92
63
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):
94
65
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
+
```
96
70
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.
100
72
101
-
Find the result in `ios-framework/ObjectBox-iOS-Aggregate.build/`
73
+
The result is stored inside `ios-framework/docs/swift_output/`.
102
74
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
104
76
105
-
Swift Framework Project Organization
106
-
------------------------------------
107
77
You look at and build the framework itself via `ios-framework/ObjectBox.xcodeproj`.
108
78
109
79
*`ObjectBox.xcproject` targets
@@ -122,79 +92,11 @@ You look at and build the framework itself via `ios-framework/ObjectBox.xcodepro
122
92
*`ObjectBox-macOS` contains macOS-specific files, including the framework's Info.plist
123
93
*`ObjectBox-iOS` contains iOS-specific files, including the framework's Info.plist
* Edit .swiftlint-macOS.yml file to customize (e.g. "id" is OK despite less than 3 chars)
129
99
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
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.
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