Skip to content

Commit 5cfb76b

Browse files
author
Clément Le Provost
committed
Add Jazzy support for the offline mode
1 parent f3808af commit 5cfb76b

File tree

8 files changed

+289
-27
lines changed

8 files changed

+289
-27
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,8 @@ DerivedData
1616
*.hmap
1717
*.ipa
1818
*.xcuserstate
19+
20+
# Cocoapods
21+
/*.xcworkspace
22+
/Pods
23+

AlgoliaSearch.xcodeproj/project.pbxproj

Lines changed: 196 additions & 0 deletions
Large diffs are not rendered by default.

Podfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# NOTE: This Podfile is used to draw dependencies when building the project independently (e.g. for unit tests).
2+
3+
use_frameworks!
4+
5+
target "AlgoliaSearch-Offline-iOS" do
6+
pod 'AlgoliaSearchOfflineCore-iOS', '~> 0.2'
7+
end

Podfile.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
PODS:
2+
- AlgoliaSearchOfflineCore-iOS (0.2)
3+
4+
DEPENDENCIES:
5+
- AlgoliaSearchOfflineCore-iOS (~> 0.2)
6+
7+
SPEC CHECKSUMS:
8+
AlgoliaSearchOfflineCore-iOS: 5cfeb295c4e8412182cc7450b0487806901472ec
9+
10+
PODFILE CHECKSUM: 70f8e7e3ce3a1a02df550109e528d546a9555548
11+
12+
COCOAPODS: 1.0.1

Source/Offline/MirroredIndex.swift

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,16 @@ import AlgoliaSearchOfflineCore
2525
import Foundation
2626

2727

28-
/// A data selection query.
28+
/// A data selection query, used to select data to be mirrored locally by a `MirroredIndex`.
29+
///
2930
@objc public class DataSelectionQuery: NSObject {
31+
/// Query used to select data.
3032
@objc public let query: Query
31-
@objc public let maxObjects: Int
3233

34+
/// Maximum number of objects to retrieve with this query.
35+
@objc public let maxObjects: Int
36+
37+
/// Create a new data selection query.
3338
@objc public init(query: Query, maxObjects: Int) {
3439
self.query = query
3540
self.maxObjects = maxObjects
@@ -46,19 +51,19 @@ import Foundation
4651

4752
/// An online index that can also be mirrored locally.
4853
///
49-
/// When created, an instance of this class has its <code>mirrored</code> flag set to false, and behaves like a normal,
54+
/// When created, an instance of this class has its `mirrored` flag set to false, and behaves like a normal,
5055
/// online `Index`. When the `mirrored` flag is set to true, the index becomes capable of acting upon local data.
5156
///
52-
/// It is a programming error to call methods acting on the local data when `mirrored` is false. Doing so
57+
/// + Warning: It is a programming error to call methods acting on the local data when `mirrored` is false. Doing so
5358
/// will result in an assertion error being raised.
5459
///
5560
/// Native resources are lazily instantiated at the first method call requiring them. They are released when the
5661
/// object is released. Although the client guards against concurrent accesses, it is strongly discouraged
5762
/// to create more than one `MirroredIndex` instance pointing to the same index, as that would duplicate
5863
/// native resources.
5964
///
60-
/// NOTE: Requires Algolia's SDK. The `OfflineClient.enableOfflineMode()` method must be called with a valid license
61-
/// key prior to calling any offline-related method.
65+
/// + Note: Requires Algolia's SDK. The `OfflineClient.enableOfflineMode(...)` method must be called with a valid
66+
/// license key prior to calling any offline-related method.
6267
///
6368
/// ### Request strategy
6469
///
@@ -68,10 +73,10 @@ import Foundation
6873
/// `FallbackOnFailure`, which will always target the online API first, then fallback to the offline mirror in case of
6974
/// failure (including network unavailability).
7075
///
71-
/// NOTE: If you want to explicitly target either the online API or the offline mirror, doing so is always possible
72-
/// using the `searchOnline()` or `searchOffline()` methods.
76+
/// + Note: If you want to explicitly target either the online API or the offline mirror, doing so is always possible
77+
/// using the `searchOnline(...)` or `searchOffline(...)` methods.
7378
///
74-
/// NOTE: The strategy applies both to `search()` and `searchDisjunctiveFaceting()`.
79+
/// + Note: The strategy applies both to `search(...)` and `searchDisjunctiveFaceting(...)`.
7580
///
7681
@objc public class MirroredIndex : Index {
7782

@@ -102,9 +107,9 @@ import Foundation
102107
// MARK: Properties
103108
// ----------------------------------------------------------------------
104109

105-
/// Getter returning covariant-typed client.
106-
// IMPLEMENTATION NOTE: Could not find a way to implement proper covariant properties in Swift.
110+
/// The offline client used by this index.
107111
@objc public var offlineClient: OfflineClient {
112+
// IMPLEMENTATION NOTE: Could not find a way to implement proper covariant properties in Swift.
108113
return self.client as! OfflineClient
109114
}
110115

@@ -157,7 +162,7 @@ import Foundation
157162
// MARK: - Init
158163
// ----------------------------------------------------------------------
159164

160-
@objc public override init(client: Client, indexName: String) {
165+
@objc override internal init(client: Client, indexName: String) {
161166
assert(client is OfflineClient);
162167
super.init(client: client, indexName: indexName)
163168
}
@@ -167,7 +172,9 @@ import Foundation
167172
// ----------------------------------------------------------------------
168173

169174
/// Syncing indicator.
170-
/// NOTE: To prevent concurrent access to this variable, we always access it from the build (serial) queue.
175+
///
176+
/// + Note: To prevent concurrent access to this variable, we always access it from the build (serial) queue.
177+
///
171178
private var syncing: Bool = false
172179

173180
/// Path to the temporary directory for the current sync.
@@ -203,7 +210,9 @@ import Foundation
203210

204211
/// Add a data selection query to the local mirror.
205212
/// The query is not run immediately. It will be run during the subsequent refreshes.
206-
/// @pre The index must have been marked as mirrored.
213+
///
214+
/// + Precondition: Mirroring must have been activated on this index (see the `mirrored` property).
215+
///
207216
@objc public func addDataSelectionQuery(query: DataSelectionQuery) {
208217
assert(mirrored);
209218
mirrorSettings.queries.append(query)
@@ -213,7 +222,9 @@ import Foundation
213222

214223
/// Add any number of data selection queries to the local mirror.
215224
/// The query is not run immediately. It will be run during the subsequent refreshes.
216-
/// @pre The index must have been marked as mirrored.
225+
///
226+
/// + Precondition: Mirroring must have been activated on this index (see the `mirrored` property).
227+
///
217228
@objc public func addDataSelectionQueries(queries: [DataSelectionQuery]) {
218229
assert(mirrored);
219230
mirrorSettings.queries.appendContentsOf(queries)
@@ -224,6 +235,8 @@ import Foundation
224235
/// Launch a sync.
225236
/// This unconditionally launches a sync, unless one is already running.
226237
///
238+
/// + Precondition: Mirroring must have been activated on this index (see the `mirrored` property).
239+
///
227240
@objc public func sync() {
228241
assert(self.mirrored, "Mirroring not activated on this index")
229242
offlineClient.buildQueue.addOperationWithBlock() {
@@ -234,6 +247,8 @@ import Foundation
234247
/// Launch a sync if needed.
235248
/// This takes into account the delay between syncs.
236249
///
250+
/// + Precondition: Mirroring must have been activated on this index (see the `mirrored` property).
251+
///
237252
@objc public func syncIfNeeded() {
238253
assert(self.mirrored, "Mirroring not activated on this index")
239254
if self.isSyncDelayExpired() || self.isMirrorSettingsDirty() {
@@ -431,7 +446,7 @@ import Foundation
431446
/// Search online only.
432447
/// The search will fail when the API can't be reached.
433448
///
434-
/// NOTE: You might consider that this defeats the purpose of having a mirror in the first place... But this
449+
/// + Note: You might consider that this defeats the purpose of having a mirror in the first place... But this
435450
/// is intended for applications wanting to manually manage their policy.
436451
///
437452
case OnlineOnly = 0
@@ -460,7 +475,7 @@ import Foundation
460475

461476
/// Timeout used to control offline fallback.
462477
///
463-
/// NOTE: Only used by the `FallbackOnTimeout` strategy.
478+
/// + Note: Only used by the `FallbackOnTimeout` strategy.
464479
///
465480
@objc public var offlineFallbackTimeout: NSTimeInterval = 1.0
466481

@@ -815,7 +830,7 @@ import Foundation
815830
// fall back could only work for the first query.
816831

817832
/// Browse the local mirror (initial call).
818-
/// Same semantics as `Index.browse()`.
833+
/// Same semantics as `Index.browse(...)`.
819834
///
820835
@objc public func browseMirror(query: Query, completionHandler: CompletionHandler) -> NSOperation {
821836
assert(self.mirrored, "Mirroring not activated on this index")
@@ -835,7 +850,7 @@ import Foundation
835850
}
836851

837852
/// Browse the index from a cursor.
838-
/// Same semantics as `Index.browseFrom()`.
853+
/// Same semantics as `Index.browseFrom(...)`.
839854
///
840855
@objc public func browseMirrorFrom(cursor: String, completionHandler: CompletionHandler) -> NSOperation {
841856
assert(self.mirrored, "Mirroring not activated on this index")

Source/Offline/OfflineClient.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ import Foundation
2727

2828
/// An API client that adds offline features on top of the regular online API client.
2929
///
30-
/// NOTE: Requires Algolia's SDK. The `enableOfflineMode()` method must be called with a valid license key prior to
31-
/// calling any offline-related method.
32-
//
30+
/// + Note: Requires Algolia's Offline Core SDK. The `enableOfflineMode(...)` method must be called with a valid license
31+
/// key prior to calling any offline-related method.
32+
///
3333
@objc public class OfflineClient : Client {
34-
/// Algolia Search initialization.
34+
/// Create a new offline-capable Algolia Search client.
35+
///
36+
/// + Note: Offline mode is disabled by default, until you call `enableOfflineMode(...)`.
3537
///
3638
/// - parameter appID: the application ID you have in your admin interface
3739
/// - parameter apiKey: a valid API key for the service
40+
///
3841
@objc public override init(appID: String, apiKey: String) {
3942
buildQueue.name = "AlgoliaSearch-Build"
4043
buildQueue.maxConcurrentOperationCount = 1
@@ -49,9 +52,9 @@ import Foundation
4952

5053
/// Path to directory where the local data is stored.
5154
/// Defaults to an `algolia` sub-directory inside the `Library/Application Support` directory.
52-
/// If you set it to another value, do so *before* calling `enableOfflineMode()`.
55+
/// If you set it to another value, do so *before* calling `enableOfflineMode(...)`.
5356
///
54-
/// WARNING: This directory will be explicitly excluded from iCloud/iTunes backup.
57+
/// + Warning: This directory will be explicitly excluded from iCloud/iTunes backup.
5558
///
5659
@objc public var rootDataDir: String
5760

@@ -92,7 +95,9 @@ import Foundation
9295
}
9396

9497
/// Create a new index.
95-
/// NOTE: The offline client returns mirror-capable indices.
98+
///
99+
/// + Note: The offline client returns mirror-capable indices.
100+
///
96101
@objc public override func getIndex(indexName: String) -> MirroredIndex {
97102
return MirroredIndex(client: self, indexName: indexName)
98103
}

doc/maintenance.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,15 @@ keep versioning aligned (there is only one version number for both flavors).
7979

8080
Documentation is generated by [Jazzy](https://github.com/realm/jazzy). Of course you will need to install it first: `sudo gem install jazzy` should do the trick.
8181

82-
Generating the documentation is as simple as running:
82+
For the online mode, generating the documentation is as simple as running:
8383

8484
```
8585
jazzy --clean
8686
```
87+
88+
For the offline mode, it is a little more complicated. We use Cocoapods to draw the dependencies. The Cocoapods-generated workspace is then used to build the documentation:
89+
90+
```
91+
pod update
92+
jazzy --config offline.jazzy.yaml --clean
93+
```

offline.jazzy.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# In the case of the offline flavor, the Xcode project is not standalone: we need the Cocoapods-generated workspace
2+
# to draw dependencies.
3+
xcodebuild_arguments:
4+
- -workspace
5+
- AlgoliaSearch.xcworkspace
6+
- -scheme
7+
- AlgoliaSearch-Offline-iOS
8+
documentation:
9+
- doc/offline-mode.md
10+
output: build/doc
11+
# Avoid putting the DocSet within the HTML docs.
12+
# WARNING: The path is relative to the output directory.
13+
docset_path: ../docset
14+
hide_documentation_coverage: true
15+
skip_undocumented: true

0 commit comments

Comments
 (0)