Skip to content

Commit a8ce5d0

Browse files
authored
Merge 3e0fdda into fb61b78
2 parents fb61b78 + 3e0fdda commit a8ce5d0

34 files changed

+393
-138
lines changed

ParseSwift.playground/Pages/12 - Roles and Relations.xcplaygroundpage/Contents.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ do {
211211
print(error)
212212
}
213213

214-
//: All `ParseObjects` have a `ParseRelation` attribute that be used on instances.
214+
//: All `ParseObject`s have a `ParseRelation` attribute that be used on instances.
215215
//: For example, the User has:
216216
let relation = User.current!.relation
217217

ParseSwift.playground/Pages/13 - Operations.xcplaygroundpage/Contents.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ do {
5959
print(error)
6060
}
6161

62-
//: There are other operations: add/remove/delete objects from `ParseObjects`.
62+
//: There are other operations: add/remove/delete objects from `ParseObject`s.
6363
//: In fact, the `users` and `roles` relations from `ParseRoles` used the add/remove operations.
6464
let operations = savedScore.operation
6565

ParseSwift.playground/Pages/4 - User - Continued.xcplaygroundpage/Contents.swift

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,29 @@ struct User: ParseUser {
2222

2323
//: Your custom keys.
2424
var customKey: String?
25+
var score: GameScore?
26+
var targetScore: GameScore?
27+
}
28+
29+
//: Create your own value typed `ParseObject`.
30+
struct GameScore: ParseObject {
31+
//: Those are required for Object
32+
var objectId: String?
33+
var createdAt: Date?
34+
var updatedAt: Date?
35+
var ACL: ParseACL?
36+
37+
//: Your own properties.
38+
var score: Int? = 0
39+
40+
//: Custom initializer.
41+
init(score: Int) {
42+
self.score = score
43+
}
44+
45+
init(objectId: String?) {
46+
self.objectId = objectId
47+
}
2548
}
2649

2750
/*: Save your first customKey value to your `ParseUser`
@@ -30,11 +53,13 @@ struct User: ParseUser {
3053
If no callbackQueue is specified it returns to main queue.
3154
*/
3255
User.current?.customKey = "myCustom"
56+
User.current?.score = GameScore(score: 12)
57+
User.current?.targetScore = GameScore(score: 100)
3358
User.current?.save { results in
3459

3560
switch results {
3661
case .success(let updatedUser):
37-
print("Successfully save myCustomKey to ParseServer: \(updatedUser)")
62+
print("Successfully save custom fields of User to ParseServer: \(updatedUser)")
3863
case .failure(let error):
3964
print("Failed to update user: \(error)")
4065
}
@@ -69,6 +94,29 @@ User.login(username: "hello", password: "world") { results in
6994
}
7095
}
7196

97+
//: Looking at the output of user from the previous login, it only has
98+
//: a pointer to the `score`and `targetScore` fields. You can fetch using `include` to
99+
//: get the score.
100+
User.current?.fetch(includeKeys: ["score"]) { result in
101+
switch result {
102+
case .success:
103+
print("Successfully fetched user with score key: \(User.current)")
104+
case .failure(let error):
105+
print("Error fetching score: \(error)")
106+
}
107+
}
108+
109+
//: The `target` score is still missing. You can get all pointer fields at
110+
//: once by including `["*"]`.
111+
User.current?.fetch(includeKeys: ["*"]) { result in
112+
switch result {
113+
case .success:
114+
print("Successfully fetched user with all keys: \(User.current)")
115+
case .failure(let error):
116+
print("Error fetching score: \(error)")
117+
}
118+
}
119+
72120
//: Logging out - synchronously.
73121
do {
74122
try User.logout()

ParseSwift.playground/Pages/6 - Installation.xcplaygroundpage/Contents.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ DispatchQueue.main.async {
4646
case .success(let updatedInstallation):
4747
print("Successfully save myCustomInstallationKey to ParseServer: \(updatedInstallation)")
4848
case .failure(let error):
49-
assertionFailure("Failed to update installation: \(error)")
49+
print("Failed to update installation: \(error)")
5050
}
5151
}
5252
}

Sources/ParseSwift/API/API+Commands.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ internal extension API {
240240
}
241241
}
242242
urlRequest.httpMethod = method.rawValue
243-
244243
return .success(urlRequest)
245244
}
246245

@@ -383,14 +382,21 @@ internal extension API.Command {
383382
}
384383

385384
// MARK: Fetching
386-
static func fetchCommand<T>(_ object: T) throws -> API.Command<T, T> where T: ParseObject {
385+
static func fetchCommand<T>(_ object: T, include: [String]?) throws -> API.Command<T, T> where T: ParseObject {
387386
guard object.isSaved else {
388387
throw ParseError(code: .unknownError, message: "Cannot Fetch an object without id")
389388
}
390389

390+
var params: [String: String]?
391+
if let includeParams = include {
392+
let joined = includeParams.joined(separator: ",")
393+
params = ["include": joined]
394+
}
395+
391396
return API.Command<T, T>(
392397
method: .GET,
393-
path: object.endpoint
398+
path: object.endpoint,
399+
params: params
394400
) { (data) -> T in
395401
try ParseCoding.jsonDecoder().decode(T.self, from: data)
396402
}

Sources/ParseSwift/Objects/ParseInstallation+combine.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@ public extension ParseInstallation {
1818
/**
1919
Fetches the `ParseInstallation` *aynchronously* with the current data from the server
2020
and sets an error if one occurs. Publishes when complete.
21-
21+
- parameter includeKeys: The name(s) of the key(s) to include that are
22+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
23+
`includeAll` for `Query`.
2224
- parameter options: A set of header options sent to the server. Defaults to an empty set.
2325
- returns: A publisher that eventually produces a single value and then finishes or fails.
2426
- important: If an object fetched has the same objectId as current, it will automatically update the current.
2527
*/
26-
func fetchPublisher(options: API.Options = []) -> Future<Self, ParseError> {
28+
func fetchPublisher(includeKeys: [String]? = nil,
29+
options: API.Options = []) -> Future<Self, ParseError> {
2730
Future { promise in
28-
self.fetch(options: options,
31+
self.fetch(includeKeys: includeKeys,
32+
options: options,
2933
completion: promise)
3034
}
3135
}
@@ -66,14 +70,18 @@ public extension Sequence where Element: ParseInstallation {
6670
/**
6771
Fetches a collection of installations *aynchronously* with the current data from the server and sets
6872
an error if one occurs. Publishes when complete.
69-
73+
- parameter includeKeys: The name(s) of the key(s) to include that are
74+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
75+
`includeAll` for `Query`.
7076
- parameter options: A set of header options sent to the server. Defaults to an empty set.
7177
- returns: A publisher that eventually produces a single value and then finishes or fails.
7278
- important: If an object fetched has the same objectId as current, it will automatically update the current.
7379
*/
74-
func fetchAllPublisher(options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
80+
func fetchAllPublisher(includeKeys: [String]? = nil,
81+
options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
7582
Future { promise in
76-
self.fetchAll(options: options,
83+
self.fetchAll(includeKeys: includeKeys,
84+
options: options,
7785
completion: promise)
7886
}
7987
}

Sources/ParseSwift/Objects/ParseInstallation.swift

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -338,21 +338,26 @@ extension ParseInstallation {
338338
/**
339339
Fetches the `ParseInstallation` *synchronously* with the current data from the server
340340
and sets an error if one occurs.
341-
341+
- parameter includeKeys: The name(s) of the key(s) to include that are
342+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
343+
`includeAll` for `Query`.
342344
- parameter options: A set of header options sent to the server. Defaults to an empty set.
343345
- throws: An error of `ParseError` type.
344346
- important: If an object fetched has the same objectId as current, it will automatically update the current.
345347
*/
346-
public func fetch(options: API.Options = []) throws -> Self {
347-
let result: Self = try fetchCommand()
348+
public func fetch(includeKeys: [String]? = nil,
349+
options: API.Options = []) throws -> Self {
350+
let result: Self = try fetchCommand(include: includeKeys)
348351
.execute(options: options, callbackQueue: .main)
349352
Self.updateKeychainIfNeeded([result])
350353
return result
351354
}
352355

353356
/**
354357
Fetches the `ParseInstallation` *asynchronously* and executes the given callback block.
355-
358+
- parameter includeKeys: The name(s) of the key(s) to include that are
359+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
360+
`includeAll` for `Query`.
356361
- parameter options: A set of header options sent to the server. Defaults to an empty set.
357362
- parameter callbackQueue: The queue to return to after completion. Default
358363
value of .main.
@@ -361,12 +366,13 @@ extension ParseInstallation {
361366
- important: If an object fetched has the same objectId as current, it will automatically update the current.
362367
*/
363368
public func fetch(
369+
includeKeys: [String]? = nil,
364370
options: API.Options = [],
365371
callbackQueue: DispatchQueue = .main,
366372
completion: @escaping (Result<Self, ParseError>) -> Void
367373
) {
368374
do {
369-
try fetchCommand()
375+
try fetchCommand(include: includeKeys)
370376
.executeAsync(options: options,
371377
callbackQueue: callbackQueue) { result in
372378
callbackQueue.async {
@@ -387,13 +393,20 @@ extension ParseInstallation {
387393
}
388394
}
389395

390-
func fetchCommand() throws -> API.Command<Self, Self> {
396+
func fetchCommand(include: [String]?) throws -> API.Command<Self, Self> {
391397
guard isSaved else {
392398
throw ParseError(code: .unknownError, message: "Cannot fetch an object without id")
393399
}
394400

401+
var params: [String: String]?
402+
if let includeParams = include {
403+
let joined = includeParams.joined(separator: ",")
404+
params = ["include": joined]
405+
}
406+
395407
return API.Command(method: .GET,
396-
path: endpoint) { (data) -> Self in
408+
path: endpoint,
409+
params: params) { (data) -> Self in
397410
try ParseCoding.jsonDecoder().decode(Self.self, from: data)
398411
}
399412
}
@@ -756,7 +769,9 @@ public extension Sequence where Element: ParseInstallation {
756769

757770
/**
758771
Fetches a collection of installations *synchronously* all at once and throws an error if necessary.
759-
772+
- parameter includeKeys: The name(s) of the key(s) to include that are
773+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
774+
`includeAll` for `Query`.
760775
- parameter options: A set of header options sent to the server. Defaults to an empty set.
761776

762777
- returns: Returns a Result enum with the object if a fetch was successful or a `ParseError` if it failed.
@@ -765,12 +780,18 @@ public extension Sequence where Element: ParseInstallation {
765780
- warning: The order in which installations are returned are not guarenteed. You shouldn't expect results in
766781
any particular order.
767782
*/
768-
func fetchAll(options: API.Options = []) throws -> [(Result<Self.Element, ParseError>)] {
783+
func fetchAll(includeKeys: [String]? = nil,
784+
options: API.Options = []) throws -> [(Result<Self.Element, ParseError>)] {
769785

770786
if (allSatisfy { $0.className == Self.Element.className}) {
771787
let uniqueObjectIds = Set(compactMap { $0.objectId })
772-
let query = Self.Element.query(containedIn(key: "objectId", array: [uniqueObjectIds]))
788+
var query = Self.Element.query(containedIn(key: "objectId", array: [uniqueObjectIds]))
773789
.limit(uniqueObjectIds.count)
790+
791+
if let include = includeKeys {
792+
query = query.include(include)
793+
}
794+
774795
let fetchedObjects = try query.find(options: options)
775796
var fetchedObjectsToReturn = [(Result<Self.Element, ParseError>)]()
776797

@@ -793,7 +814,9 @@ public extension Sequence where Element: ParseInstallation {
793814

794815
/**
795816
Fetches a collection of installations all at once *asynchronously* and executes the completion block when done.
796-
817+
- parameter includeKeys: The name(s) of the key(s) to include that are
818+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
819+
`includeAll` for `Query`.
797820
- parameter options: A set of header options sent to the server. Defaults to an empty set.
798821
- parameter callbackQueue: The queue to return to after completion. Default value of .main.
799822
- parameter completion: The block to execute.
@@ -803,13 +826,17 @@ public extension Sequence where Element: ParseInstallation {
803826
any particular order.
804827
*/
805828
func fetchAll(
829+
includeKeys: [String]? = nil,
806830
options: API.Options = [],
807831
callbackQueue: DispatchQueue = .main,
808832
completion: @escaping (Result<[(Result<Element, ParseError>)], ParseError>) -> Void
809833
) {
810834
if (allSatisfy { $0.className == Self.Element.className}) {
811835
let uniqueObjectIds = Set(compactMap { $0.objectId })
812-
let query = Self.Element.query(containedIn(key: "objectId", array: [uniqueObjectIds]))
836+
var query = Self.Element.query(containedIn(key: "objectId", array: [uniqueObjectIds]))
837+
if let include = includeKeys {
838+
query = query.include(include)
839+
}
813840
query.find(options: options, callbackQueue: callbackQueue) { result in
814841
switch result {
815842

Sources/ParseSwift/Objects/ParseObject+combine.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@ public extension ParseObject {
1717
/**
1818
Fetches the `ParseObject` *aynchronously* with the current data from the server and sets an error if one occurs.
1919
Publishes when complete.
20-
20+
- parameter includeKeys: The name(s) of the key(s) to include that are
21+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
22+
`includeAll` for `Query`.
2123
- parameter options: A set of header options sent to the server. Defaults to an empty set.
2224
- returns: A publisher that eventually produces a single value and then finishes or fails.
2325
- important: If an object fetched has the same objectId as current, it will automatically update the current.
2426
*/
25-
func fetchPublisher(options: API.Options = []) -> Future<Self, ParseError> {
27+
func fetchPublisher(includeKeys: [String]? = nil,
28+
options: API.Options = []) -> Future<Self, ParseError> {
2629
Future { promise in
27-
self.fetch(options: options,
30+
self.fetch(includeKeys: includeKeys,
31+
options: options,
2832
completion: promise)
2933
}
3034
}
@@ -63,14 +67,18 @@ public extension Sequence where Element: ParseObject {
6367
/**
6468
Fetches a collection of objects *aynchronously* with the current data from the server and sets
6569
an error if one occurs. Publishes when complete.
66-
70+
- parameter includeKeys: The name(s) of the key(s) to include that are
71+
`ParseObject`s. Use `["*"]` to include all keys. This is similar to `include` and
72+
`includeAll` for `Query`.
6773
- parameter options: A set of header options sent to the server. Defaults to an empty set.
6874
- returns: A publisher that eventually produces a single value and then finishes or fails.
6975
- important: If an object fetched has the same objectId as current, it will automatically update the current.
7076
*/
71-
func fetchAllPublisher(options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
77+
func fetchAllPublisher(includeKeys: [String]? = nil,
78+
options: API.Options = []) -> Future<[(Result<Self.Element, ParseError>)], ParseError> {
7279
Future { promise in
73-
self.fetchAll(options: options,
80+
self.fetchAll(includeKeys: includeKeys,
81+
options: options,
7482
completion: promise)
7583
}
7684
}

0 commit comments

Comments
 (0)