Skip to content

fix: use select for ParseLiveQuery when fields are not present #377

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 4 commits into from
Jul 2, 2022
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/4.7.0...main)
* _Contributing to this repo? Add info about your change here to be included in the next release_

__Fixes__
- Use select for ParseLiveQuery when fields are not present ([#376](https://github.com/parse-community/Parse-Swift/pull/376)), thanks to [Corey Baker](https://github.com/cbaker6).

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ ParseLiveQuery.client?.sendPing { error in
var query2 = GameScore.query("points" > 50)

//: Select the fields you are interested in receiving.
query2.fields("points")
query2.select("points")

//: Subscribe to your new query.
let subscription2 = query2.subscribeCallback!
Expand Down
4 changes: 3 additions & 1 deletion Sources/ParseSwift/LiveQuery/Messages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ struct SubscribeMessage<T: ParseObject>: LiveQueryable, Encodable {
self.op = operation
self.requestId = requestId.value
if let query = query {
self.query = SubscribeQuery(className: query.className, where: query.where, fields: query.fields)
self.query = SubscribeQuery(className: query.className,
where: query.where,
fields: query.fields ?? query.keys)
}
self.sessionToken = BaseParseUser.currentContainer?.sessionToken
}
Expand Down
4 changes: 3 additions & 1 deletion Sources/ParseSwift/LiveQuery/ParseLiveQuery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,9 @@ extension ParseLiveQuery {
public func subscribe<T>(_ handler: T) throws -> T where T: QuerySubscribable {

let requestId = requestIdGenerator()
let message = SubscribeMessage<T.Object>(operation: .subscribe, requestId: requestId, query: handler.query)
let message = SubscribeMessage<T.Object>(operation: .subscribe,
requestId: requestId,
query: handler.query)
guard let subscriptionRecord = SubscriptionRecord(
query: handler.query,
message: message,
Expand Down
16 changes: 13 additions & 3 deletions Sources/ParseSwift/Types/Query.swift
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,11 @@ public struct Query<T>: ParseTypeable where T: ParseObject {
/**
Make the query restrict the fields of the returned `ParseObject`s to include only the provided keys.
If this is called multiple times, then all of the keys specified in each of the calls will be included.
- parameter keys: A variadic list of keys include in the result.
- parameter keys: A variadic list of keys to include in the result.
- returns: The mutated instance of query for easy chaining.
- warning: Requires Parse Server 5.0.0+.
- note: When using the `Query` for `ParseLiveQuery`, setting `fields` will take precedence
over `select`. If `fields` are not set, the `select` keys will be used.
*/
public func select(_ keys: String...) -> Query<T> {
self.select(keys)
Expand All @@ -367,6 +369,8 @@ public struct Query<T>: ParseTypeable where T: ParseObject {
- parameter keys: An array of keys to include in the result.
- returns: The mutated instance of query for easy chaining.
- warning: Requires Parse Server 5.0.0+.
- note: When using the `Query` for `ParseLiveQuery`, setting `fields` will take precedence
over `select`. If `fields` are not set, the `select` keys will be used.
*/
public func select(_ keys: [String]) -> Query<T> {
var mutableQuery = self
Expand Down Expand Up @@ -399,13 +403,16 @@ public struct Query<T>: ParseTypeable where T: ParseObject {
}

/**
A variadic list of fields to receive when receiving a `ParseLiveQuery`.
A variadic list of selected fields to receive updates on when the `Query` is used as a
`ParseLiveQuery`.

Suppose the `ParseObject` Player contains three fields name, id and age.
If you are only interested in the change of the name field, you can set `query.fields` to "name".
In this situation, when the change of a Player `ParseObject` fulfills the subscription, only the
name field will be sent to the clients instead of the full Player `ParseObject`.
If this is called multiple times, then all of the keys specified in each of the calls will be received.
- note: Setting `fields` will take precedence over `select`. If `fields` are not set, the
`select` keys will be used.
- warning: This is only for `ParseLiveQuery`.
- parameter keys: A variadic list of fields to receive back instead of the whole `ParseObject`.
- returns: The mutated instance of query for easy chaining.
Expand All @@ -415,13 +422,16 @@ public struct Query<T>: ParseTypeable where T: ParseObject {
}

/**
A list of fields to receive when receiving a `ParseLiveQuery`.
A list of fields to receive updates on when the `Query` is used as a
`ParseLiveQuery`.

Suppose the `ParseObject` Player contains three fields name, id and age.
If you are only interested in the change of the name field, you can set `query.fields` to "name".
In this situation, when the change of a Player `ParseObject` fulfills the subscription, only the
name field will be sent to the clients instead of the full Player `ParseObject`.
If this is called multiple times, then all of the keys specified in each of the calls will be received.
- note: Setting `fields` will take precedence over `select`. If `fields` are not set, the
`select` keys will be used.
- warning: This is only for `ParseLiveQuery`.
- parameter keys: An array of fields to receive back instead of the whole `ParseObject`.
- returns: The mutated instance of query for easy chaining.
Expand Down
18 changes: 17 additions & 1 deletion Tests/ParseSwiftTests/ParseLiveQueryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,27 @@ class ParseLiveQueryTests: XCTestCase {
XCTAssertEqual(decoded, expected)
}

func testSubscribeMessageEncoding() throws {
func testSubscribeMessageFieldsEncoding() throws {
// swiftlint:disable:next line_length
let expected = "{\"op\":\"subscribe\",\"query\":{\"className\":\"GameScore\",\"fields\":[\"points\"],\"where\":{\"points\":{\"$gt\":9}}},\"requestId\":1}"
let query = GameScore.query("points" > 9)
.fields(["points"])
.select(["talk"])
let message = SubscribeMessage(operation: .subscribe,
requestId: RequestId(value: 1),
query: query,
additionalProperties: true)
let encoded = try ParseCoding.jsonEncoder()
.encode(message)
let decoded = try XCTUnwrap(String(data: encoded, encoding: .utf8))
XCTAssertEqual(decoded, expected)
}

func testSubscribeMessageSelectEncoding() throws {
// swiftlint:disable:next line_length
let expected = "{\"op\":\"subscribe\",\"query\":{\"className\":\"GameScore\",\"fields\":[\"points\"],\"where\":{\"points\":{\"$gt\":9}}},\"requestId\":1}"
let query = GameScore.query("points" > 9)
.select(["points"])
let message = SubscribeMessage(operation: .subscribe,
requestId: RequestId(value: 1),
query: query,
Expand Down