Skip to content

fix: don't use cache for fetching objects and files by default #272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Nov 3, 2021
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@

### main

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

### 2.1.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.1.0...2.2.0)

__Improvements__
- 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).

__Fixes__
- 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).

### 2.1.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.0.3...2.1.0)

Expand Down
6 changes: 4 additions & 2 deletions Sources/ParseSwift/API/API+Command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,10 @@ internal extension API.Command {
.appendingPathComponent(ParseConstants.fileDownloadsDirectory, isDirectory: true)
try fileManager.createDirectoryIfNeeded(downloadDirectoryPath.relativePath)
let fileLocation = downloadDirectoryPath.appendingPathComponent(object.name)
try? FileManager.default.removeItem(at: fileLocation) //Remove file if it's already present
try FileManager.default.moveItem(at: tempFileLocation, to: fileLocation)
if tempFileLocation != fileLocation {
try? FileManager.default.removeItem(at: fileLocation) //Remove file if it's already present
try FileManager.default.moveItem(at: tempFileLocation, to: fileLocation)
}
var object = object
object.localURL = fileLocation
return object
Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/API/API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public struct API {
}

public static func == (lhs: API.Option, rhs: API.Option) -> Bool {
return AnyEncodable(lhs) == AnyEncodable(rhs)
lhs.hashValue == rhs.hashValue
}
}

Expand Down
29 changes: 20 additions & 9 deletions Sources/ParseSwift/API/URLSession+extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,6 @@ extension URLSession {
if let location = location {
do {
let data = try ParseCoding.jsonEncoder().encode(location)
if URLSession.parse.configuration.urlCache?.cachedResponse(for: request) == nil {
URLSession.parse.configuration.urlCache?.storeCachedResponse(.init(response: response,
data: data),
for: request)
}
return try .success(mapper(data))
} catch {
guard let parseError = error as? ParseError else {
Expand Down Expand Up @@ -189,10 +184,26 @@ extension URLSession {
completion: @escaping(Result<U, ParseError>) -> Void
) {
let task = downloadTask(with: request) { (location, urlResponse, responseError) in
completion(self.makeResult(request: request,
location: location,
urlResponse: urlResponse,
responseError: responseError, mapper: mapper))
let result = self.makeResult(request: request,
location: location,
urlResponse: urlResponse,
responseError: responseError, mapper: mapper)
if case .success(let file) = result {
guard let response = urlResponse,
let parseFile = file as? ParseFile,
let fileLocation = parseFile.localURL,
let data = try? ParseCoding.jsonEncoder().encode(fileLocation) else {
completion(result)
return
}
if URLSession.parse.configuration.urlCache?.cachedResponse(for: request) == nil {
URLSession.parse.configuration.urlCache?
.storeCachedResponse(.init(response: response,
data: data),
for: request)
}
}
completion(result)
}
ParseSwift.sessionDelegate.downloadDelegates[task] = progress
ParseSwift.sessionDelegate.taskCallbackQueues[task] = callbackQueue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ public extension ParseUser {
- throws: An error of type `ParseError`.
- returns: An instance of the logged in `ParseUser`.
If login failed due to either an incorrect password or incorrect username, it throws a `ParseError`.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
static func login(_ type: String,
authData: [String: String],
Expand Down Expand Up @@ -298,6 +300,8 @@ public extension ParseUser {
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
- parameter completion: The block to execute.
It should have the following argument signature: `(Result<Self, ParseError>)`.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func unlink(_ type: String,
options: API.Options = [],
Expand Down Expand Up @@ -347,6 +351,8 @@ public extension ParseUser {
- throws: An error of type `ParseError`.
- returns: An instance of the logged in `ParseUser`.
If login failed due to either an incorrect password or incorrect username, it throws a `ParseError`.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
static func link(_ type: String,
authData: [String: String],
Expand All @@ -371,6 +377,8 @@ public extension ParseUser {
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
- parameter completion: The block to execute.
It should have the following argument signature: `(Result<Self, ParseError>)`.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
static func link(_ type: String,
authData: [String: String],
Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/LiveQuery/Subscription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private func == <T>(lhs: Event<T>, rhs: Event<T>) -> Bool {

#if canImport(Combine)
/**
A default implementation of the `ParseSubscription` protocol. Suitable for `ObjectObserved`
A default implementation of the `QuerySubscribable` protocol. Suitable for `ObjectObserved`
as the subscription can be used as a SwiftUI publisher. Meaning it can serve
indepedently as a ViewModel in MVVM.
*/
Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/LiveQuery/SubscriptionCallback.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

/**
A default implementation of the `ParseSubscription` protocol using closures for callbacks.
A default implementation of the `QuerySubscribable` protocol using closures for callbacks.
*/
open class SubscriptionCallback<T: ParseObject>: QuerySubscribable {

Expand Down
2 changes: 2 additions & 0 deletions Sources/ParseSwift/Objects/ParseInstallation+async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public extension ParseInstallation {
- returns: Returns saved `ParseInstallation`.
- throws: `ParseError`.
- important: If an object fetched has the same objectId as current, it will automatically update the current.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func fetch(includeKeys: [String]? = nil,
options: API.Options = []) async throws -> Self {
Expand Down
2 changes: 2 additions & 0 deletions Sources/ParseSwift/Objects/ParseInstallation+combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public extension ParseInstallation {
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- returns: A publisher that eventually produces a single value and then finishes or fails.
- important: If an object fetched has the same objectId as current, it will automatically update the current.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func fetchPublisher(includeKeys: [String]? = nil,
options: API.Options = []) -> Future<Self, ParseError> {
Expand Down
24 changes: 24 additions & 0 deletions Sources/ParseSwift/Objects/ParseInstallation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,13 @@ extension ParseInstallation {
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- throws: An error of `ParseError` type.
- important: If an object fetched has the same objectId as current, it will automatically update the current.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
public func fetch(includeKeys: [String]? = nil,
options: API.Options = []) throws -> Self {
var options = options
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
let result: Self = try fetchCommand(include: includeKeys)
.execute(options: options, callbackQueue: .main)
try Self.updateKeychainIfNeeded([result])
Expand All @@ -374,13 +378,17 @@ extension ParseInstallation {
- parameter completion: The block to execute when completed.
It should have the following argument signature: `(Result<Self, ParseError>)`.
- important: If an object fetched has the same objectId as current, it will automatically update the current.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
public func fetch(
includeKeys: [String]? = nil,
options: API.Options = [],
callbackQueue: DispatchQueue = .main,
completion: @escaping (Result<Self, ParseError>) -> Void
) {
var options = options
options.insert(.cachePolicy(.reloadIgnoringLocalCacheData))
do {
try fetchCommand(include: includeKeys)
.executeAsync(options: options,
Expand Down Expand Up @@ -469,6 +477,8 @@ extension ParseInstallation {
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
client-side checks are disabled. Developers are responsible for handling such cases.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
public func save(isIgnoreCustomObjectIdConfig: Bool,
options: API.Options = []) throws -> Self {
Expand Down Expand Up @@ -520,6 +530,8 @@ extension ParseInstallation {
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
client-side checks are disabled. Developers are responsible for handling such cases.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
public func save(
isIgnoreCustomObjectIdConfig: Bool = false,
Expand Down Expand Up @@ -615,6 +627,8 @@ extension ParseInstallation {
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- throws: An error of `ParseError` type.
- important: If an object deleted has the same objectId as current, it will automatically update the current.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
public func delete(options: API.Options = []) throws {
var options = options
Expand All @@ -632,6 +646,8 @@ extension ParseInstallation {
- parameter completion: The block to execute when completed.
It should have the following argument signature: `(Result<Void, ParseError>)`.
- important: If an object deleted has the same objectId as current, it will automatically update the current.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
public func delete(
options: API.Options = [],
Expand Down Expand Up @@ -724,6 +740,8 @@ public extension Sequence where Element: ParseInstallation {
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
client-side checks are disabled. Developers are responsible for handling such cases.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func saveAll(batchLimit limit: Int? = nil, // swiftlint:disable:this function_body_length
transaction: Bool = false,
Expand Down Expand Up @@ -825,6 +843,8 @@ public extension Sequence where Element: ParseInstallation {
increase the probability of colliding `objectId`'s as the client and server `objectId`'s may be generated using
different algorithms. This can also lead to overwriting of `ParseObject`'s by accident as the
client-side checks are disabled. Developers are responsible for handling such cases.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func saveAll( // swiftlint:disable:this function_body_length cyclomatic_complexity
batchLimit limit: Int? = nil,
Expand Down Expand Up @@ -1067,6 +1087,8 @@ public extension Sequence where Element: ParseInstallation {
- warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
the transactions can fail.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func deleteAll(batchLimit limit: Int? = nil,
transaction: Bool = false,
Expand Down Expand Up @@ -1117,6 +1139,8 @@ public extension Sequence where Element: ParseInstallation {
- warning: If `transaction = true`, then `batchLimit` will be automatically be set to the amount of the
objects in the transaction. The developer should ensure their respective Parse Servers can handle the limit or else
the transactions can fail.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func deleteAll(
batchLimit limit: Int? = nil,
Expand Down
2 changes: 2 additions & 0 deletions Sources/ParseSwift/Objects/ParseObject+async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public extension ParseObject {
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- returns: A publisher that eventually produces a single value and then finishes or fails.
- throws: `ParseError`.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func fetch(includeKeys: [String]? = nil,
options: API.Options = []) async throws -> Self {
Expand Down
2 changes: 2 additions & 0 deletions Sources/ParseSwift/Objects/ParseObject+combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public extension ParseObject {
`includeAll` for `Query`.
- parameter options: A set of header options sent to the server. Defaults to an empty set.
- returns: A publisher that eventually produces a single value and then finishes or fails.
- note: The default cache policy for this method is `.reloadIgnoringLocalCacheData`. If a developer
desires a different policy, it should be inserted in `options`.
*/
func fetchPublisher(includeKeys: [String]? = nil,
options: API.Options = []) -> Future<Self, ParseError> {
Expand Down
Loading