Skip to content

Commit 321905d

Browse files
vdkdamiancbaker6
andauthored
feat: add ParseObjectMutable protocol (#270)
* • Updatable * Requested changes * Requested changes + Line length * Requested changes * Requested changes Co-authored-by: Corey <[email protected]>
1 parent 126f4f6 commit 321905d

File tree

10 files changed

+160
-112
lines changed

10 files changed

+160
-112
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
__Improvements__
1212
- Make ParseUser.current, ParseInstallation.current, ParseConfig.current immutable. This prevents accidently setting to nil. When developers want to make changes, they should make mutable copies, mutate, then save ([#266](https://github.com/parse-community/Parse-Swift/pull/266)), thanks to [Corey Baker](https://github.com/cbaker6).
13+
- Added the ParseObjectMutable protocol to make emptyObject more developer friendly ([#270](https://github.com/parse-community/Parse-Swift/pull/270)), thanks to [Damian Van de Kauter](https://github.com/novemTeam).
14+
1315

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

ParseSwift.playground/Pages/1 - Your first Object.xcplaygroundpage/Contents.swift

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ do {
3030
}
3131

3232
//: Create your own value typed `ParseObject`.
33-
struct GameScore: ParseObject {
33+
struct GameScore: ParseObject, ParseObjectMutable {
3434
//: These are required by ParseObject
3535
var objectId: String?
3636
var createdAt: Date?
@@ -39,20 +39,6 @@ struct GameScore: ParseObject {
3939

4040
//: Your own properties.
4141
var score: Int = 0
42-
43-
/*:
44-
It's recommended the developer adds the emptyObject computed property or similar.
45-
Gets an empty version of the respective object. This can be used when you only need to update a
46-
a subset of the fields of an object as oppose to updating every field of an object. Using an
47-
empty object and updating a subset of the fields reduces the amount of data sent between
48-
client and server when using `save` and `saveAll` to update objects.
49-
*/
50-
var emptyObject: Self {
51-
var object = Self()
52-
object.objectId = objectId
53-
object.createdAt = createdAt
54-
return object
55-
}
5642
}
5743

5844
//: It's recommended to place custom initializers in an extension
@@ -110,11 +96,11 @@ score.save { result in
11096
assert(savedScore.score == 10)
11197

11298
/*: To modify, need to make it a var as the value type
113-
was initialized as immutable. Using `emptyObject`
99+
was initialized as immutable. Using `mutable`
114100
allows you to only send the updated keys to the
115101
parse server as opposed to the whole object.
116102
*/
117-
var changedScore = savedScore.emptyObject
103+
var changedScore = savedScore.mutable
118104
changedScore.score = 200
119105
changedScore.save { result in
120106
switch result {
@@ -202,11 +188,11 @@ assert(savedScore?.updatedAt != nil)
202188
assert(savedScore?.score == 10)
203189

204190
/*: To modify, need to make it a var as the value type
205-
was initialized as immutable. Using `emptyObject`
191+
was initialized as immutable. Using `mutable`
206192
allows you to only send the updated keys to the
207193
parse server as opposed to the whole object.
208194
*/
209-
guard var changedScore = savedScore?.emptyObject else {
195+
guard var changedScore = savedScore?.mutable else {
210196
fatalError()
211197
}
212198
changedScore.score = 200

ParseSwift.playground/Pages/15 - Custom ObjectId.xcplaygroundpage/Contents.swift

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ npm start -- --appId applicationId --clientKey clientKey --masterKey masterKey -
2121
initializeParseCustomObjectId()
2222

2323
//: Create your own value typed `ParseObject`.
24-
struct GameScore: ParseObject {
24+
struct GameScore: ParseObject, ParseObjectMutable {
2525
//: These are required by ParseObject
2626
var objectId: String?
2727
var createdAt: Date?
@@ -30,20 +30,6 @@ struct GameScore: ParseObject {
3030

3131
//: Your own properties.
3232
var score: Int = 0
33-
34-
/*:
35-
It's recommended the developer adds the emptyObject computed property or similar.
36-
Gets an empty version of the respective object. This can be used when you only need to update a
37-
a subset of the fields of an object as oppose to updating every field of an object. Using an
38-
empty object and updating a subset of the fields reduces the amount of data sent between
39-
client and server when using `save` and `saveAll` to update objects.
40-
*/
41-
var emptyObject: Self {
42-
var object = Self()
43-
object.objectId = objectId
44-
object.createdAt = createdAt
45-
return object
46-
}
4733
}
4834

4935
//: It's recommended to place custom initializers in an extension
@@ -82,11 +68,11 @@ score.save { result in
8268
print("Saved score: \(savedScore)")
8369

8470
/*: To modify, need to make it a var as the value type
85-
was initialized as immutable. Using `emptyObject`
71+
was initialized as immutable. Using `mutable`
8672
allows you to only send the updated keys to the
8773
parse server as opposed to the whole object.
8874
*/
89-
var changedScore = savedScore.emptyObject
75+
var changedScore = savedScore.mutable
9076
changedScore.score = 200
9177
changedScore.save { result in
9278
switch result {

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

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import ParseSwift
1313
PlaygroundPage.current.needsIndefiniteExecution = true
1414
initializeParse()
1515

16-
struct User: ParseUser {
16+
struct User: ParseUser, ParseObjectMutable {
1717
//: These are required by `ParseObject`.
1818
var objectId: String?
1919
var createdAt: Date?
@@ -32,20 +32,6 @@ struct User: ParseUser {
3232
var score: GameScore?
3333
var targetScore: GameScore?
3434
var allScores: [GameScore]?
35-
36-
/*:
37-
It's recommended the developer adds the emptyObject computed property or similar.
38-
Gets an empty version of the respective object. This can be used when you only need to update a
39-
a subset of the fields of an object as oppose to updating every field of an object. Using an
40-
empty object and updating a subset of the fields reduces the amount of data sent between
41-
client and server when using `save` and `saveAll` to update objects.
42-
*/
43-
var emptyObject: Self {
44-
var object = Self()
45-
object.objectId = objectId
46-
object.createdAt = createdAt
47-
return object
48-
}
4935
}
5036

5137
//: It's recommended to place custom initializers in an extension
@@ -117,10 +103,10 @@ User.login(username: "hello", password: "world") { result in
117103
Asynchrounously - Performs work on background
118104
queue and returns to specified callbackQueue.
119105
If no callbackQueue is specified it returns to main queue.
120-
Using `emptyObject` allows you to only send the updated keys to the
106+
Using `mutable` allows you to only send the updated keys to the
121107
parse server as opposed to the whole object.
122108
*/
123-
var currentUser = User.current?.emptyObject
109+
var currentUser = User.current?.mutable
124110
currentUser?.customKey = "myCustom"
125111
currentUser?.score = GameScore(score: 12)
126112
currentUser?.targetScore = GameScore(score: 100)
@@ -224,7 +210,7 @@ User.anonymous.login { result in
224210
}
225211

226212
//: Convert the anonymous user to a real new user.
227-
var currentUser2 = User.current?.emptyObject
213+
var currentUser2 = User.current?.mutable
228214
currentUser2?.username = "bye"
229215
currentUser2?.password = "world"
230216
currentUser2?.signup { result in

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

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import ParseSwift
1313
PlaygroundPage.current.needsIndefiniteExecution = true
1414
initializeParse()
1515

16-
struct Installation: ParseInstallation {
16+
struct Installation: ParseInstallation, ParseObjectMutable {
1717
//: These are required by `ParseObject`.
1818
var objectId: String?
1919
var createdAt: Date?
@@ -35,20 +35,6 @@ struct Installation: ParseInstallation {
3535

3636
//: Your custom keys
3737
var customKey: String?
38-
39-
/*:
40-
It's recommended the developer adds the emptyObject computed property or similar.
41-
Gets an empty version of the respective object. This can be used when you only need to update a
42-
a subset of the fields of an object as oppose to updating every field of an object. Using an
43-
empty object and updating a subset of the fields reduces the amount of data sent between
44-
client and server when using `save` and `saveAll` to update objects.
45-
*/
46-
var emptyObject: Self {
47-
var object = Self()
48-
object.objectId = objectId
49-
object.createdAt = createdAt
50-
return object
51-
}
5238
}
5339

5440
/*: Save your first `customKey` value to your `ParseInstallation`.
@@ -71,11 +57,11 @@ currentInstallation?.save { results in
7157
/*: Update your `ParseInstallation` `customKey` value.
7258
Performs work on background queue and returns to designated on
7359
designated callbackQueue. If no callbackQueue is specified it
74-
returns to main queue. Using `emptyObject` allows you to only
60+
returns to main queue. Using `mutable` allows you to only
7561
send the updated keys to the parse server as opposed to the
7662
whole object.
7763
*/
78-
currentInstallation = currentInstallation?.emptyObject
64+
currentInstallation = currentInstallation?.mutable
7965
currentInstallation?.customKey = "updatedValue"
8066
currentInstallation?.save { results in
8167

ParseSwift.xcodeproj/project.pbxproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,10 @@
587587
91F346C3269B88F7005727B6 /* ParseCloudViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */; };
588588
91F346C4269B88F7005727B6 /* ParseCloudViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */; };
589589
91F346C5269B88F7005727B6 /* ParseCloudViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */; };
590+
CD106A00272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; };
591+
CD106A01272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; };
592+
CD106A02272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; };
593+
CD106A03272D481800939151 /* ParseObjectMutable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1069FF272D481800939151 /* ParseObjectMutable.swift */; };
590594
F971F4F624DE381A006CB79B /* ParseEncoderExtraTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F971F4F524DE381A006CB79B /* ParseEncoderExtraTests.swift */; };
591595
F97B45CE24D9C6F200F4A88B /* ParseCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F97B45B424D9C6F200F4A88B /* ParseCoding.swift */; };
592596
F97B45CF24D9C6F200F4A88B /* ParseCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = F97B45B424D9C6F200F4A88B /* ParseCoding.swift */; };
@@ -961,6 +965,7 @@
961965
91F346B8269B766C005727B6 /* CloudViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudViewModel.swift; sourceTree = "<group>"; };
962966
91F346BD269B77B5005727B6 /* CloudObservable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudObservable.swift; sourceTree = "<group>"; };
963967
91F346C2269B88F7005727B6 /* ParseCloudViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseCloudViewModelTests.swift; sourceTree = "<group>"; };
968+
CD1069FF272D481800939151 /* ParseObjectMutable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseObjectMutable.swift; sourceTree = "<group>"; };
964969
F971F4F524DE381A006CB79B /* ParseEncoderExtraTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseEncoderExtraTests.swift; sourceTree = "<group>"; };
965970
F97B45B424D9C6F200F4A88B /* ParseCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseCoding.swift; sourceTree = "<group>"; };
966971
F97B45B524D9C6F200F4A88B /* AnyDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyDecodable.swift; sourceTree = "<group>"; };
@@ -1287,6 +1292,7 @@
12871292
F97B45C824D9C6F200F4A88B /* Queryable.swift */,
12881293
F97B45C724D9C6F200F4A88B /* Savable.swift */,
12891294
70647E9B259E3A9A004C1004 /* ParseType.swift */,
1295+
CD1069FF272D481800939151 /* ParseObjectMutable.swift */,
12901296
91BB8FCE2690BA70005A6BA5 /* QueryObservable.swift */,
12911297
91F346BD269B77B5005727B6 /* CloudObservable.swift */,
12921298
);
@@ -2084,6 +2090,7 @@
20842090
703B090226BD9652005A112F /* ParseAnalytics+async.swift in Sources */,
20852091
703B093F26BF47AC005A112F /* ParseApple+async.swift in Sources */,
20862092
F97B45E624D9C6F200F4A88B /* Query.swift in Sources */,
2093+
CD106A00272D481800939151 /* ParseObjectMutable.swift in Sources */,
20872094
703B093526BF43D9005A112F /* ParseAnonymous+async.swift in Sources */,
20882095
705D950825BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */,
20892096
70C5509225B4A99100B5DBC2 /* AddRelation.swift in Sources */,
@@ -2293,6 +2300,7 @@
22932300
703B090326BD9652005A112F /* ParseAnalytics+async.swift in Sources */,
22942301
703B094026BF47AC005A112F /* ParseApple+async.swift in Sources */,
22952302
F97B45E724D9C6F200F4A88B /* Query.swift in Sources */,
2303+
CD106A01272D481800939151 /* ParseObjectMutable.swift in Sources */,
22962304
703B093626BF43D9005A112F /* ParseAnonymous+async.swift in Sources */,
22972305
705D950925BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */,
22982306
70C5509325B4A99100B5DBC2 /* AddRelation.swift in Sources */,
@@ -2597,6 +2605,7 @@
25972605
703B090526BD9652005A112F /* ParseAnalytics+async.swift in Sources */,
25982606
703B094226BF47AC005A112F /* ParseApple+async.swift in Sources */,
25992607
F97B466724D9C88600F4A88B /* SecureStorage.swift in Sources */,
2608+
CD106A03272D481800939151 /* ParseObjectMutable.swift in Sources */,
26002609
703B093826BF43D9005A112F /* ParseAnonymous+async.swift in Sources */,
26012610
705D950B25BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */,
26022611
70C5509525B4A99100B5DBC2 /* AddRelation.swift in Sources */,
@@ -2720,6 +2729,7 @@
27202729
703B090426BD9652005A112F /* ParseAnalytics+async.swift in Sources */,
27212730
703B094126BF47AC005A112F /* ParseApple+async.swift in Sources */,
27222731
F97B466624D9C88600F4A88B /* SecureStorage.swift in Sources */,
2732+
CD106A02272D481800939151 /* ParseObjectMutable.swift in Sources */,
27232733
703B093726BF43D9005A112F /* ParseAnonymous+async.swift in Sources */,
27242734
705D950A25BE4C08003EF6F8 /* SubscriptionCallback.swift in Sources */,
27252735
70C5509425B4A99100B5DBC2 /* AddRelation.swift in Sources */,

Sources/ParseSwift/Objects/ParseObject.swift

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,12 @@ import Foundation
1616
If you are using value types the the compiler will assist you with conforming to `ParseObject` protocol. If you
1717
are thinking of using reference types, see the warning.
1818

19-
It's recommended the developer adds the emptyObject computed property or similar.
19+
It's recommended the developer conforms to the `ParseObjectMutable` protocol.
2020
Gets an empty version of the respective object. This can be used when you only need to update a
2121
a subset of the fields of an object as oppose to updating every field of an object. Using an empty object and updating
2222
a subset of the fields reduces the amount of data sent between client and server when using `save` and `saveAll`
23-
to update objects. You should add the following properties in your `ParseObject`'s:
24-
25-
var emptyObject: Self {
26-
var object = Self()
27-
object.objectId = objectId
28-
object.createdAt = createdAt
29-
return object
30-
}
31-
23+
to update objects.
24+
3225
- important: It is recommended that all added properties be optional properties so they can eventually be used as
3326
Parse `Pointer`'s. If a developer really wants to have a required key, they should require it on the server-side or
3427
create methods to check the respective properties on the client-side before saving objects. See

0 commit comments

Comments
 (0)