Skip to content

fix: improve equatable comparison of QueryConstraint #275

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 2 commits into from
Nov 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@

### main

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

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

__Fixes__
- Improve equatable comparison of QueryConstraint ([#275](https://github.com/parse-community/Parse-Swift/pull/275)), thanks to [Corey Baker](https://github.com/cbaker6).

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

__Fixes__
- Set the default cache policy for `ParseFile` to the default policy set when initializing the SDK ([#274](https://github.com/parse-community/Parse-Swift/pull/274)), thanks to [Corey Baker](https://github.com/cbaker6).
- Set the default cache policy for ParseFile to the default policy set when initializing the SDK ([#274](https://github.com/parse-community/Parse-Swift/pull/274)), thanks to [Corey Baker](https://github.com/cbaker6).

### 2.2.0
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.1.0...2.2.0)
Expand All @@ -18,7 +24,7 @@ __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).
- 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
122 changes: 70 additions & 52 deletions ParseSwift.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

61 changes: 0 additions & 61 deletions Sources/ParseSwift/Coding/Extensions.swift

This file was deleted.

42 changes: 42 additions & 0 deletions Sources/ParseSwift/Coding/ParseCoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,48 @@ extension ParseCoding {
}
}

// MARK: Coding
public extension ParseObject {

/// The Parse encoder is used to JSON encode all `ParseObject`s and
/// types in a way meaninful for a Parse Server to consume.
static func getEncoder() -> ParseEncoder {
return ParseCoding.parseEncoder()
}

/// The Parse encoder is used to JSON encode all `ParseObject`s and
/// types in a way meaninful for a Parse Server to consume.
func getEncoder() -> ParseEncoder {
return Self.getEncoder()
}

/// The JSON encoder setup with the correct `dateEncodingStrategy`
/// strategy to send data to a Parse Server.
static func getJSONEncoder() -> JSONEncoder {
return ParseCoding.jsonEncoder()
}

/// The JSON encoder setup with the correct `dateEncodingStrategy`
/// strategy to send data to a Parse Server.
func getJSONEncoder() -> JSONEncoder {
return Self.getJSONEncoder()
}

/// The JSON decoder setup with the correct `dateDecodingStrategy`
/// strategy to decode data from a Parse Server. This encoder is used to decode all data received
/// from the server.
static func getDecoder() -> JSONDecoder {
ParseCoding.jsonDecoder()
}

/// The JSON decoder setup with the correct `dateDecodingStrategy`
/// strategy to decode data from a Parse Server. This encoder is used to decode all data received
/// from the server.
func getDecoder() -> JSONDecoder {
Self.getDecoder()
}
}

// MARK: Dates
extension ParseCoding {
enum DateEncodingKeys: String, CodingKey {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Data+hexString.swift
// Data.swift
// ParseSwift
//
// Created by Corey Baker on 2/14/21.
Expand Down
20 changes: 20 additions & 0 deletions Sources/ParseSwift/Extensions/Date.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Date.swift
// ParseSwift
//
// Created by Corey Baker on 11/4/21.
// Copyright © 2021 Parse Community. All rights reserved.
//

import Foundation

// MARK: Date
internal extension Date {
func parseFormatted() -> String {
return ParseCoding.dateFormatter.string(from: self)
}

var parseRepresentation: [String: String] {
return ["__type": "Date", "iso": parseFormatted()]
}
}
21 changes: 21 additions & 0 deletions Sources/ParseSwift/Extensions/Encodable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Encodable.swift
// ParseSwift
//
// Created by Corey Baker on 11/4/21.
// Copyright © 2021 Parse Community. All rights reserved.
//

import Foundation

internal extension Encodable {
func isEqual(_ other: Encodable) -> Bool {
guard let lhsData = try? ParseCoding.parseEncoder().encode(self),
let lhsString = String(data: lhsData, encoding: .utf8),
let rhsData = try? ParseCoding.parseEncoder().encode(other),
let rhsString = String(data: rhsData, encoding: .utf8) else {
return false
}
return lhsString == rhsString
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// URLCache+extensions.swift
// URLCache.swift
// ParseSwift
//
// Created by Corey Baker on 7/17/21.
Expand All @@ -11,7 +11,7 @@ import Foundation
import FoundationNetworking
#endif

extension URLCache {
internal extension URLCache {
static let parse: URLCache = {
guard let cacheURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else {
return URLCache(memoryCapacity: ParseSwift.configuration.cacheMemoryCapacity,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//
// URLSession+extensions.swift
// URLSession.swift
// ParseSwift
//
// Original file, URLSession+sync.swift, created by Florent Vilmart on 17-09-24.
// Name change to URLSession+extensions.swift and support for sync/async by Corey Baker on 7/25/20.
// Name change to URLSession.swift and support for sync/async by Corey Baker on 7/25/20.
// Copyright © 2020 Parse Community. All rights reserved.
//

Expand All @@ -12,7 +12,7 @@ import Foundation
import FoundationNetworking
#endif

extension URLSession {
internal extension URLSession {
static let parse: URLSession = {
if !ParseSwift.configuration.isTestingSDK {
let configuration = URLSessionConfiguration.default
Expand All @@ -29,11 +29,11 @@ extension URLSession {
}
}()

internal func makeResult<U>(request: URLRequest,
responseData: Data?,
urlResponse: URLResponse?,
responseError: Error?,
mapper: @escaping (Data) throws -> U) -> Result<U, ParseError> {
func makeResult<U>(request: URLRequest,
responseData: Data?,
urlResponse: URLResponse?,
responseError: Error?,
mapper: @escaping (Data) throws -> U) -> Result<U, ParseError> {
guard let response = urlResponse else {
guard let parseError = responseError as? ParseError else {
return .failure(ParseError(code: .unknownError,
Expand Down Expand Up @@ -87,11 +87,11 @@ extension URLSession {
message: "Unable to sync with parse-server: \(String(describing: urlResponse))."))
}

internal func makeResult<U>(request: URLRequest,
location: URL?,
urlResponse: URLResponse?,
responseError: Error?,
mapper: @escaping (Data) throws -> U) -> Result<U, ParseError> {
func makeResult<U>(request: URLRequest,
location: URL?,
urlResponse: URLResponse?,
responseError: Error?,
mapper: @escaping (Data) throws -> U) -> Result<U, ParseError> {
guard let response = urlResponse else {
guard let parseError = responseError as? ParseError else {
return .failure(ParseError(code: .unknownError,
Expand Down Expand Up @@ -125,7 +125,7 @@ extension URLSession {
message: "Unable to sync with parse-server: \(response)."))
}

internal func dataTask<U>(
func dataTask<U>(
with request: URLRequest,
mapper: @escaping (Data) throws -> U,
completion: @escaping(Result<U, ParseError>) -> Void
Expand All @@ -141,8 +141,8 @@ extension URLSession {
}
}

extension URLSession {
internal func uploadTask<U>( // swiftlint:disable:this function_parameter_count
internal extension URLSession {
func uploadTask<U>( // swiftlint:disable:this function_parameter_count
callbackQueue: DispatchQueue,
with request: URLRequest,
from data: Data?,
Expand Down Expand Up @@ -176,7 +176,7 @@ extension URLSession {
}
}

internal func downloadTask<U>(
func downloadTask<U>(
callbackQueue: DispatchQueue,
with request: URLRequest,
progress: ((URLSessionDownloadTask, Int64, Int64, Int64) -> Void)?,
Expand Down Expand Up @@ -210,7 +210,7 @@ extension URLSession {
task.resume()
}

internal func downloadTask<U>(
func downloadTask<U>(
with request: URLRequest,
mapper: @escaping (Data) throws -> U,
completion: @escaping(Result<U, ParseError>) -> Void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

import Foundation

struct BaseConfig: ParseConfig { }
struct BaseConfig: ParseConfig {}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation
You can use this protocol on any custom class of yours, instead of `Subscription` or
`SubscriptionCallback`, if it fits your use case better.
*/
public protocol QuerySubscribable: AnyObject {
public protocol QuerySubscribable: AnyObject {

/// The `ParseObject` associated with this subscription.
associatedtype Object: ParseObject
Expand Down
1 change: 0 additions & 1 deletion Sources/ParseSwift/Objects/ParseSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ extension ParseSession {
if let objectId = objectId {
return .session(objectId: objectId)
}

return .sessions
}
}
2 changes: 1 addition & 1 deletion Sources/ParseSwift/ParseConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

enum ParseConstants {
static let sdk = "swift"
static let version = "2.2.1"
static let version = "2.2.2"
static let fileManagementDirectory = "parse/"
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
static let fileManagementLibraryDirectory = "Library/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import Foundation
For example, setting, deleting, or incrementing a value are all `ParseOperation`'s.
`ParseOperation` themselves can be considered to be immutable.

In most cases, you should not call this class directly as a `ParseOperation` can be
indirectly created from any `ParseObject` by using its `operation` property.
In most cases, you do not need to create an instance of `ParseOperation` directly as it can be
indirectly created from any `ParseObject` by using the respective `operation` property.
*/
public struct ParseOperation<T>: Savable where T: ParseObject {

Expand All @@ -38,7 +38,7 @@ public struct ParseOperation<T>: Savable where T: ParseObject {
throw ParseError(code: .unknownError, message: "Target shouldn't be nil")
}
var mutableOperation = self
if !isEqual(target[keyPath: key.1], to: value) {
if !target[keyPath: key.1].isEqual(value) {
mutableOperation.operations[key.0] = value
mutableOperation.target?[keyPath: key.1] = value
}
Expand Down Expand Up @@ -397,16 +397,6 @@ public struct ParseOperation<T>: Savable where T: ParseObject {
try value.encode(to: encoder)
}
}

func isEqual(_ lhs: Encodable, to rhs: Encodable) -> Bool {
guard let lhsData = try? ParseCoding.parseEncoder().encode(lhs),
let lhsString = String(data: lhsData, encoding: .utf8),
let rhsData = try? ParseCoding.parseEncoder().encode(rhs),
let rhsString = String(data: rhsData, encoding: .utf8) else {
return false
}
return lhsString == rhsString
}
}

// MARK: Savable
Expand Down
3 changes: 3 additions & 0 deletions Sources/ParseSwift/Types/ParseRelation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import Foundation
/**
The `ParseRelation` class that is used to access all of the children of a many-to-many relationship.
Each instance of `ParseRelation` is associated with a particular parent object and key.

In most cases, you do not need to create an instance of `ParseOperation` directly as it can be
indirectly created from any `ParseObject` by using the respective `relation` property.
*/
public struct ParseRelation<T>: Codable, Hashable where T: ParseObject {
internal let __type: String = "Relation" // swiftlint:disable:this identifier_name
Expand Down
6 changes: 2 additions & 4 deletions Sources/ParseSwift/Types/Query.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,10 @@ public struct QueryConstraint: Encodable, Equatable {

public static func == (lhs: QueryConstraint, rhs: QueryConstraint) -> Bool {
guard lhs.key == rhs.key,
lhs.comparator == rhs.comparator,
let lhsObject = lhs.value as? NSObject,
let rhsObject = rhs.value as? NSObject else {
lhs.comparator == rhs.comparator else {
return false
}
return lhsObject == rhsObject
return lhs.value.isEqual(rhs.value)
}
}

Expand Down