Skip to content

Commit 72eb7c5

Browse files
authored
fix: don't use cache for fetching objects and files by default (#272)
* Don't use cache for fetching by default * Add back the ability to cache downloaded files properly * Add changelog * Overload Encodable operators * revert * nits * add docs about default cache policy * more doc nits * minor updates on ParseOperation * only move file if new location * don't move file in custom
1 parent a64726f commit 72eb7c5

34 files changed

+323
-56
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,18 @@
22

33
### main
44

5-
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.1.0...main)
5+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.0...main)
66
* _Contributing to this repo? Add info about your change here to be included in the next release_
77

8+
### 2.1.0
9+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.1.0...2.2.0)
10+
11+
__Improvements__
12+
- Added ability to fetch ParsePointer using async/await ([#271](https://github.com/parse-community/Parse-Swift/pull/271)), thanks to [Corey Baker](https://github.com/cbaker6).
13+
14+
__Fixes__
15+
- By default, don't use cache when fetching ParseObject's and `ParseFile`s. Developers can choose to fetch from cache if desired by passing the necessary option while fetching. Fixed a bug when the incorrect file location for a dowloaded ParseFile was being cached ([#272](https://github.com/parse-community/Parse-Swift/pull/272)), thanks to [Corey Baker](https://github.com/cbaker6).
16+
817
### 2.1.0
918
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.0.3...2.1.0)
1019

Sources/ParseSwift/API/API+Command.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,10 @@ internal extension API.Command {
321321
.appendingPathComponent(ParseConstants.fileDownloadsDirectory, isDirectory: true)
322322
try fileManager.createDirectoryIfNeeded(downloadDirectoryPath.relativePath)
323323
let fileLocation = downloadDirectoryPath.appendingPathComponent(object.name)
324-
try? FileManager.default.removeItem(at: fileLocation) //Remove file if it's already present
325-
try FileManager.default.moveItem(at: tempFileLocation, to: fileLocation)
324+
if tempFileLocation != fileLocation {
325+
try? FileManager.default.removeItem(at: fileLocation) //Remove file if it's already present
326+
try FileManager.default.moveItem(at: tempFileLocation, to: fileLocation)
327+
}
326328
var object = object
327329
object.localURL = fileLocation
328330
return object

Sources/ParseSwift/API/API.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public struct API {
164164
}
165165

166166
public static func == (lhs: API.Option, rhs: API.Option) -> Bool {
167-
return AnyEncodable(lhs) == AnyEncodable(rhs)
167+
lhs.hashValue == rhs.hashValue
168168
}
169169
}
170170

Sources/ParseSwift/API/URLSession+extensions.swift

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,6 @@ extension URLSession {
110110
if let location = location {
111111
do {
112112
let data = try ParseCoding.jsonEncoder().encode(location)
113-
if URLSession.parse.configuration.urlCache?.cachedResponse(for: request) == nil {
114-
URLSession.parse.configuration.urlCache?.storeCachedResponse(.init(response: response,
115-
data: data),
116-
for: request)
117-
}
118113
return try .success(mapper(data))
119114
} catch {
120115
guard let parseError = error as? ParseError else {
@@ -189,10 +184,26 @@ extension URLSession {
189184
completion: @escaping(Result<U, ParseError>) -> Void
190185
) {
191186
let task = downloadTask(with: request) { (location, urlResponse, responseError) in
192-
completion(self.makeResult(request: request,
193-
location: location,
194-
urlResponse: urlResponse,
195-
responseError: responseError, mapper: mapper))
187+
let result = self.makeResult(request: request,
188+
location: location,
189+
urlResponse: urlResponse,
190+
responseError: responseError, mapper: mapper)
191+
if case .success(let file) = result {
192+
guard let response = urlResponse,
193+
let parseFile = file as? ParseFile,
194+
let fileLocation = parseFile.localURL,
195+
let data = try? ParseCoding.jsonEncoder().encode(fileLocation) else {
196+
completion(result)
197+
return
198+
}
199+
if URLSession.parse.configuration.urlCache?.cachedResponse(for: request) == nil {
200+
URLSession.parse.configuration.urlCache?
201+
.storeCachedResponse(.init(response: response,
202+
data: data),
203+
for: request)
204+
}
205+
}
206+
completion(result)
196207
}
197208
ParseSwift.sessionDelegate.downloadDelegates[task] = progress
198209
ParseSwift.sessionDelegate.taskCallbackQueues[task] = callbackQueue

Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ public extension ParseUser {
208208
- throws: An error of type `ParseError`.
209209
- returns: An instance of the logged in `ParseUser`.
210210
If login failed due to either an incorrect password or incorrect username, it throws a `ParseError`.
211+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
212+
desires a different policy, it should be inserted in `options`.
211213
*/
212214
static func login(_ type: String,
213215
authData: [String: String],
@@ -298,6 +300,8 @@ public extension ParseUser {
298300
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
299301
- parameter completion: The block to execute.
300302
It should have the following argument signature: `(Result<Self, ParseError>)`.
303+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
304+
desires a different policy, it should be inserted in `options`.
301305
*/
302306
func unlink(_ type: String,
303307
options: API.Options = [],
@@ -347,6 +351,8 @@ public extension ParseUser {
347351
- throws: An error of type `ParseError`.
348352
- returns: An instance of the logged in `ParseUser`.
349353
If login failed due to either an incorrect password or incorrect username, it throws a `ParseError`.
354+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
355+
desires a different policy, it should be inserted in `options`.
350356
*/
351357
static func link(_ type: String,
352358
authData: [String: String],
@@ -371,6 +377,8 @@ public extension ParseUser {
371377
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
372378
- parameter completion: The block to execute.
373379
It should have the following argument signature: `(Result<Self, ParseError>)`.
380+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
381+
desires a different policy, it should be inserted in `options`.
374382
*/
375383
static func link(_ type: String,
376384
authData: [String: String],

Sources/ParseSwift/LiveQuery/Subscription.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ private func == <T>(lhs: Event<T>, rhs: Event<T>) -> Bool {
5858

5959
#if canImport(Combine)
6060
/**
61-
A default implementation of the `ParseSubscription` protocol. Suitable for `ObjectObserved`
61+
A default implementation of the `QuerySubscribable` protocol. Suitable for `ObjectObserved`
6262
as the subscription can be used as a SwiftUI publisher. Meaning it can serve
6363
indepedently as a ViewModel in MVVM.
6464
*/

Sources/ParseSwift/LiveQuery/SubscriptionCallback.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010

1111
/**
12-
A default implementation of the `ParseSubscription` protocol using closures for callbacks.
12+
A default implementation of the `QuerySubscribable` protocol using closures for callbacks.
1313
*/
1414
open class SubscriptionCallback<T: ParseObject>: QuerySubscribable {
1515

Sources/ParseSwift/Objects/ParseInstallation+async.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public extension ParseInstallation {
2323
- returns: Returns saved `ParseInstallation`.
2424
- throws: `ParseError`.
2525
- important: If an object fetched has the same objectId as current, it will automatically update the current.
26+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
27+
desires a different policy, it should be inserted in `options`.
2628
*/
2729
func fetch(includeKeys: [String]? = nil,
2830
options: API.Options = []) async throws -> Self {

Sources/ParseSwift/Objects/ParseInstallation+combine.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public extension ParseInstallation {
2222
- parameter options: A set of header options sent to the server. Defaults to an empty set.
2323
- returns: A publisher that eventually produces a single value and then finishes or fails.
2424
- important: If an object fetched has the same objectId as current, it will automatically update the current.
25+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
26+
desires a different policy, it should be inserted in `options`.
2527
*/
2628
func fetchPublisher(includeKeys: [String]? = nil,
2729
options: API.Options = []) -> Future<Self, ParseError> {

Sources/ParseSwift/Objects/ParseInstallation.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,13 @@ extension ParseInstallation {
354354
- parameter options: A set of header options sent to the server. Defaults to an empty set.
355355
- throws: An error of `ParseError` type.
356356
- important: If an object fetched has the same objectId as current, it will automatically update the current.
357+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
358+
desires a different policy, it should be inserted in `options`.
357359
*/
358360
public func fetch(includeKeys: [String]? = nil,
359361
options: API.Options = []) throws -> Self {
362+
var options = options
363+
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
360364
let result: Self = try fetchCommand(include: includeKeys)
361365
.execute(options: options, callbackQueue: .main)
362366
try Self.updateKeychainIfNeeded([result])
@@ -374,13 +378,17 @@ extension ParseInstallation {
374378
- parameter completion: The block to execute when completed.
375379
It should have the following argument signature: `(Result<Self, ParseError>)`.
376380
- important: If an object fetched has the same objectId as current, it will automatically update the current.
381+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
382+
desires a different policy, it should be inserted in `options`.
377383
*/
378384
public func fetch(
379385
includeKeys: [String]? = nil,
380386
options: API.Options = [],
381387
callbackQueue: DispatchQueue = .main,
382388
completion: @escaping (Result<Self, ParseError>) -> Void
383389
) {
390+
var options = options
391+
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
384392
do {
385393
try fetchCommand(include: includeKeys)
386394
.executeAsync(options: options,
@@ -469,6 +477,8 @@ extension ParseInstallation {
469477
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
470478
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
471479
client-side checks are disabled. Developers are responsible for handling such cases.
480+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
481+
desires a different policy, it should be inserted in `options`.
472482
*/
473483
public func save(isIgnoreCustomObjectIdConfig: Bool,
474484
options: API.Options = []) throws -> Self {
@@ -520,6 +530,8 @@ extension ParseInstallation {
520530
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
521531
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
522532
client-side checks are disabled. Developers are responsible for handling such cases.
533+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
534+
desires a different policy, it should be inserted in `options`.
523535
*/
524536
public func save(
525537
isIgnoreCustomObjectIdConfig: Bool = false,
@@ -615,6 +627,8 @@ extension ParseInstallation {
615627
- parameter options: A set of header options sent to the server. Defaults to an empty set.
616628
- throws: An error of `ParseError` type.
617629
- important: If an object deleted has the same objectId as current, it will automatically update the current.
630+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
631+
desires a different policy, it should be inserted in `options`.
618632
*/
619633
public func delete(options: API.Options = []) throws {
620634
var options = options
@@ -632,6 +646,8 @@ extension ParseInstallation {
632646
- parameter completion: The block to execute when completed.
633647
It should have the following argument signature: `(Result<Void, ParseError>)`.
634648
- important: If an object deleted has the same objectId as current, it will automatically update the current.
649+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
650+
desires a different policy, it should be inserted in `options`.
635651
*/
636652
public func delete(
637653
options: API.Options = [],
@@ -724,6 +740,8 @@ public extension Sequence where Element: ParseInstallation {
724740
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
725741
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
726742
client-side checks are disabled. Developers are responsible for handling such cases.
743+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
744+
desires a different policy, it should be inserted in `options`.
727745
*/
728746
func saveAll(batchLimit limit: Int? = nil, // swiftlint:disable:this function_body_length
729747
transaction: Bool = false,
@@ -825,6 +843,8 @@ public extension Sequence where Element: ParseInstallation {
825843
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
826844
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
827845
client-side checks are disabled. Developers are responsible for handling such cases.
846+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
847+
desires a different policy, it should be inserted in `options`.
828848
*/
829849
func saveAll( // swiftlint:disable:this function_body_length cyclomatic_complexity
830850
batchLimit limit: Int? = nil,
@@ -1067,6 +1087,8 @@ public extension Sequence where Element: ParseInstallation {
10671087
- warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
10681088
objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
10691089
the transactions can fail.
1090+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
1091+
desires a different policy, it should be inserted in `options`.
10701092
*/
10711093
func deleteAll(batchLimit limit: Int? = nil,
10721094
transaction: Bool = false,
@@ -1117,6 +1139,8 @@ public extension Sequence where Element: ParseInstallation {
11171139
- warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
11181140
objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
11191141
the transactions can fail.
1142+
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
1143+
desires a different policy, it should be inserted in `options`.
11201144
*/
11211145
func deleteAll(
11221146
batchLimit limit: Int? = nil,

0 commit comments

Comments
 (0)