Skip to content

Commit 0c5d7f6

Browse files
authored
feat: enable query caching by using GET instead of POST (#386)
* feat: add the ability to cache queries * feat: use GET instead of POST for query by default * add the rest of GET queries * fix test build errors * first test * sort url query items for cache * add tests * add changelog
1 parent 7ba4f95 commit 0c5d7f6

File tree

17 files changed

+1487
-178
lines changed

17 files changed

+1487
-178
lines changed

.codecov.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ coverage:
66
status:
77
patch:
88
default:
9-
target: auto
9+
target: 79
1010
changes: false
1111
project:
1212
default:
13-
target: 87
13+
target: 89
1414
comment:
1515
require_changes: true

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
branches: '*'
77
env:
88
CI_XCODE_VER: '/Applications/Xcode_12.5.1.app/Contents/Developer'
9-
CI_XCODE_13: '/Applications/Xcode_13.4.app/Contents/Developer'
9+
CI_XCODE_13: '/Applications/Xcode_13.4.1.app/Contents/Developer'
1010

1111
jobs:
1212
xcode-test-ios:

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ on:
33
release:
44
types: [published]
55
env:
6-
CI_XCODE_13: '/Applications/Xcode_13.4.app/Contents/Developer'
6+
CI_XCODE_13: '/Applications/Xcode_13.4.1.app/Contents/Developer'
77

88
jobs:
99
cocoapods:

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
### main
44

5+
__New features__
6+
- Enable query caching by using GET instead of POST. GET is now used by default. To switch back to POST, set usingPostForQuery = true when initializing the SDK which will automatically disable all query caching ([#386](https://github.com/parse-community/Parse-Swift/pull/386)), thanks to [Corey Baker](https://github.com/cbaker6).
7+
58
__Improvements__
69
- Added discardableResult to allow developers to choose whether or not certain functions should return a result ([#385](https://github.com/parse-community/Parse-Swift/pull/385)), thanks to [Damian Van de Kauter](https://github.com/vdkdamian).
710

ParseSwift.xcodeproj/project.pbxproj

Lines changed: 112 additions & 21 deletions
Large diffs are not rendered by default.

Sources/ParseSwift/API/API+Command.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ internal extension API {
260260
func prepareURLRequest(options: API.Options,
261261
childObjects: [String: PointerType]? = nil,
262262
childFiles: [UUID: ParseFile]? = nil) -> Result<URLRequest, ParseError> {
263-
let params = self.params?.getQueryItems()
263+
let params = self.params?.getURLQueryItems()
264264
var headers = API.getHeaders(options: options)
265265
if method == .GET || method == .DELETE {
266266
headers.removeValue(forKey: "X-Parse-Request-Id")

Sources/ParseSwift/API/API+NonParseBodyCommand.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ internal extension API {
1919
let path: API.Endpoint
2020
let body: T?
2121
let mapper: ((Data) throws -> U)
22+
let params: [String: String?]?
2223

2324
init(method: API.Method,
2425
path: API.Endpoint,
@@ -27,6 +28,7 @@ internal extension API {
2728
mapper: @escaping ((Data) throws -> U)) {
2829
self.method = method
2930
self.path = path
31+
self.params = params
3032
self.body = body
3133
self.mapper = mapper
3234
}
@@ -83,17 +85,23 @@ internal extension API {
8385

8486
// MARK: URL Preperation
8587
func prepareURLRequest(options: API.Options) -> Result<URLRequest, ParseError> {
88+
let params = self.params?.getURLQueryItems()
8689
var headers = API.getHeaders(options: options)
8790
if method == .GET || method == .DELETE {
8891
headers.removeValue(forKey: "X-Parse-Request-Id")
8992
}
9093
let url = ParseSwift.configuration.serverURL.appendingPathComponent(path.urlComponent)
9194

92-
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
93-
let urlComponents = components.url else {
95+
guard var components = URLComponents(url: url, resolvingAgainstBaseURL: false) else {
9496
return .failure(ParseError(code: .unknownError,
9597
message: "couldn't unrwrap url components for \(url)"))
9698
}
99+
components.queryItems = params
100+
101+
guard let urlComponents = components.url else {
102+
return .failure(ParseError(code: .unknownError,
103+
message: "couldn't create url from components for \(components)"))
104+
}
97105

98106
var urlRequest = URLRequest(url: urlComponents)
99107
urlRequest.allHTTPHeaderFields = headers

Sources/ParseSwift/API/API.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -254,11 +254,3 @@ public struct API {
254254
ParseConstants.sdk+ParseConstants.version
255255
}
256256
}
257-
258-
internal extension Dictionary where Key == String, Value == String? {
259-
func getQueryItems() -> [URLQueryItem] {
260-
return map { (key, value) -> URLQueryItem in
261-
return URLQueryItem(name: key, value: value)
262-
}
263-
}
264-
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// Dictionary.swift
3+
// ParseSwift
4+
//
5+
// Created by Corey Baker on 7/14/22.
6+
// Copyright © 2022 Parse Community. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
internal extension Dictionary where Key == String, Value == String? {
12+
func getURLQueryItems() -> [URLQueryItem] {
13+
sorted { $0.key < $1.key }.map { (key, value) -> URLQueryItem in
14+
URLQueryItem(name: key, value: value)
15+
}
16+
}
17+
}

Sources/ParseSwift/Parse.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ public struct ParseConfiguration {
3737
/// - warning: This is known not to work for LiveQuery on Parse Servers <= 5.0.0.
3838
public internal(set) var isUsingEqualQueryConstraint = false
3939

40+
/// Use **POST** instead of **GET** when making query calls.
41+
/// Defaults to **false**.
42+
/// - warning: **POST** calls are not cached and will require all queries to access the
43+
/// server instead of following the `requestCachePolicy`.
44+
public internal(set) var isUsingPostForQuery = false
45+
4046
/// The default caching policy for all http requests that determines when to
4147
/// return a response from the cache. Defaults to `useProtocolCachePolicy`.
4248
/// See Apple's [documentation](https://developer.apple.com/documentation/foundation/url_loading_system/accessing_cached_data)
@@ -85,6 +91,8 @@ public struct ParseConfiguration {
8591
side for each object. Must be enabled on the server to work.
8692
- parameter usingTransactions: Use transactions when saving/updating multiple objects.
8793
- parameter usingEqualQueryConstraint: Use the **$eq** query constraint when querying.
94+
- parameter usingPostForQuery: Use **POST** instead of **GET** when making query calls.
95+
Defaults to **false**.
8896
- parameter keyValueStore: A key/value store that conforms to the `ParseKeyValueStore`
8997
protocol. Defaults to `nil` in which one will be created an memory, but never persisted. For Linux, this
9098
this is the only store available since there is no Keychain. Linux users should replace this store with an
@@ -110,6 +118,7 @@ public struct ParseConfiguration {
110118
See Apple's [documentation](https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate/1411595-urlsession) for more for details.
111119
- warning: `usingTransactions` is experimental.
112120
- warning: It is recomended to only specify `masterKey` when using the SDK on a server. Do not use this key on the client.
121+
- warning: Setting `usingPostForQuery` to **true** will require all queries to access the server instead of following the `requestCachePolicy`.
113122
*/
114123
public init(applicationId: String,
115124
clientKey: String? = nil,
@@ -121,6 +130,7 @@ public struct ParseConfiguration {
121130
allowingCustomObjectIds: Bool = false,
122131
usingTransactions: Bool = false,
123132
usingEqualQueryConstraint: Bool = false,
133+
usingPostForQuery: Bool = false,
124134
keyValueStore: ParseKeyValueStore? = nil,
125135
requestCachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy,
126136
cacheMemoryCapacity: Int = 512_000,
@@ -140,6 +150,7 @@ public struct ParseConfiguration {
140150
self.isAllowingCustomObjectIds = allowingCustomObjectIds
141151
self.isUsingTransactions = usingTransactions
142152
self.isUsingEqualQueryConstraint = usingEqualQueryConstraint
153+
self.isUsingPostForQuery = usingPostForQuery
143154
self.mountPath = "/" + serverURL.pathComponents
144155
.filter { $0 != "/" }
145156
.joined(separator: "/")
@@ -253,6 +264,8 @@ public struct ParseSwift {
253264
side for each object. Must be enabled on the server to work.
254265
- parameter usingTransactions: Use transactions when saving/updating multiple objects.
255266
- parameter usingEqualQueryConstraint: Use the **$eq** query constraint when querying.
267+
- parameter usingPostForQuery: Use **POST** instead of **GET** when making query calls.
268+
Defaults to **false**.
256269
- parameter keyValueStore: A key/value store that conforms to the `ParseKeyValueStore`
257270
protocol. Defaults to `nil` in which one will be created an memory, but never persisted. For Linux, this
258271
this is the only store available since there is no Keychain. Linux users should replace this store with an
@@ -276,6 +289,7 @@ public struct ParseSwift {
276289
See Apple's [documentation](https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate/1411595-urlsession) for more for details.
277290
- warning: `usingTransactions` is experimental.
278291
- warning: It is recomended to only specify `masterKey` when using the SDK on a server. Do not use this key on the client.
292+
- warning: Setting `usingPostForQuery` to **true** will require all queries to access the server instead of following the `requestCachePolicy`.
279293
*/
280294
static public func initialize(
281295
applicationId: String,
@@ -286,6 +300,7 @@ public struct ParseSwift {
286300
allowingCustomObjectIds: Bool = false,
287301
usingTransactions: Bool = false,
288302
usingEqualQueryConstraint: Bool = false,
303+
usingPostForQuery: Bool = false,
289304
keyValueStore: ParseKeyValueStore? = nil,
290305
requestCachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy,
291306
cacheMemoryCapacity: Int = 512_000,
@@ -306,6 +321,7 @@ public struct ParseSwift {
306321
allowingCustomObjectIds: allowingCustomObjectIds,
307322
usingTransactions: usingTransactions,
308323
usingEqualQueryConstraint: usingEqualQueryConstraint,
324+
usingPostForQuery: usingPostForQuery,
309325
keyValueStore: keyValueStore,
310326
requestCachePolicy: requestCachePolicy,
311327
cacheMemoryCapacity: cacheMemoryCapacity,
@@ -325,6 +341,7 @@ public struct ParseSwift {
325341
allowingCustomObjectIds: Bool = false,
326342
usingTransactions: Bool = false,
327343
usingEqualQueryConstraint: Bool = false,
344+
usingPostForQuery: Bool = false,
328345
keyValueStore: ParseKeyValueStore? = nil,
329346
requestCachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy,
330347
cacheMemoryCapacity: Int = 512_000,
@@ -345,6 +362,7 @@ public struct ParseSwift {
345362
allowingCustomObjectIds: allowingCustomObjectIds,
346363
usingTransactions: usingTransactions,
347364
usingEqualQueryConstraint: usingEqualQueryConstraint,
365+
usingPostForQuery: usingPostForQuery,
348366
keyValueStore: keyValueStore,
349367
requestCachePolicy: requestCachePolicy,
350368
cacheMemoryCapacity: cacheMemoryCapacity,

0 commit comments

Comments
 (0)