Skip to content

Commit

Permalink
refactor: Make some ParseObject methods required (#96)
Browse files Browse the repository at this point in the history
* refactor: Make some ParseObject methods and properties required

* nit

* nits

* api nits

* remove unused code
  • Loading branch information
cbaker6 authored May 2, 2023
1 parent a746db0 commit 0e40929
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 130 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
# Parse-Swift Changelog

### main
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.4.2...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift)
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.4.3...main), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/main/documentation/parseswift)
* _Contributing to this repo? Add info about your change here to be included in the next release_

### 5.4.3
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.4.2...5.4.3), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.4.3/documentation/parseswift)

__Fixes__
* Move some ParseObject methods and properties to required to leverage developer implementations ([#96](https://github.com/netreconlab/Parse-Swift/pull/96)), thanks to [Corey Baker](https://github.com/cbaker6).

### 5.4.2
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.4.1...5.4.2), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.4.2/documentation/parseswift)

Expand Down
25 changes: 0 additions & 25 deletions Sources/ParseSwift/API/API+NonParseBodyCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,6 @@ internal extension API {
self.mapper = mapper
}

/*
func execute(options: API.Options) throws -> U {
var responseResult: Result<U, ParseError>?
let synchronizationQueue = DispatchQueue(label: "com.parse.NonParseBodyCommand.sync.\(UUID().uuidString)",
qos: .default,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
let group = DispatchGroup()
group.enter()
self.executeAsync(options: options,
callbackQueue: synchronizationQueue,
allowIntermediateResponses: false) { result in
responseResult = result
group.leave()
}
group.wait()
guard let response = responseResult else {
throw ParseError(code: .otherCause,
message: "Could not unrwrap server response")
}
return try response.get()
} */

// MARK: Asynchronous Execution
func execute(options: API.Options,
callbackQueue: DispatchQueue,
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 @@ -16,7 +16,7 @@ import FoundationNetworking
/// The REST API for communicating with a Parse Server.
public struct API {

internal enum Method: String, Encodable {
public enum Method: String, Encodable {
case GET, POST, PUT, PATCH, DELETE
}

Expand Down
32 changes: 16 additions & 16 deletions Sources/ParseSwift/API/Responses.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

internal struct CreateResponse: Decodable {
struct CreateResponse: Decodable {
var objectId: String
var createdAt: Date
var updatedAt: Date {
Expand All @@ -24,7 +24,7 @@ internal struct CreateResponse: Decodable {
}
}

internal struct ReplaceResponse: Decodable {
struct ReplaceResponse: Decodable {
var createdAt: Date?
var updatedAt: Date?

Expand All @@ -45,7 +45,7 @@ internal struct ReplaceResponse: Decodable {
}
}

internal struct UpdateResponse: Decodable {
struct UpdateResponse: Decodable {
var updatedAt: Date

func apply<T>(to object: T) -> T where T: ParseObject {
Expand All @@ -55,18 +55,18 @@ internal struct UpdateResponse: Decodable {
}
}

internal struct UpdateSessionTokenResponse: Decodable {
struct UpdateSessionTokenResponse: Decodable {
var updatedAt: Date
let sessionToken: String?
}

// MARK: ParseObject Batch
internal struct BatchResponseItem<T>: Codable where T: Codable {
struct BatchResponseItem<T>: Codable where T: Codable {
let success: T?
let error: ParseError?
}

internal struct BatchResponse: Codable {
struct BatchResponse: Codable {
var objectId: String?
var createdAt: Date?
var updatedAt: Date?
Expand Down Expand Up @@ -112,13 +112,13 @@ internal struct BatchResponse: Codable {
}

// MARK: Query
internal struct QueryResponse<T>: Codable where T: ParseObject {
struct QueryResponse<T>: Codable where T: ParseObject {
let results: [T]
let count: Int?
}

// MARK: ParseUser
internal struct LoginSignupResponse: Codable {
struct LoginSignupResponse: Codable {
let createdAt: Date
let objectId: String
let sessionToken: String
Expand All @@ -137,7 +137,7 @@ internal struct LoginSignupResponse: Codable {
}

// MARK: ParseFile
internal struct FileUploadResponse: Codable {
struct FileUploadResponse: Codable {
let name: String
let url: URL

Expand All @@ -150,35 +150,35 @@ internal struct FileUploadResponse: Codable {
}

// MARK: AnyResultResponse
internal struct AnyResultResponse<U: Decodable>: Decodable {
struct AnyResultResponse<U: Decodable>: Decodable {
let result: U
}

// MARK: AnyResultsResponse
internal struct AnyResultsResponse<U: Decodable>: Decodable {
struct AnyResultsResponse<U: Decodable>: Decodable {
let results: [U]
}

internal struct AnyResultsMongoResponse<U: Decodable>: Decodable {
struct AnyResultsMongoResponse<U: Decodable>: Decodable {
let results: U
}

// MARK: ConfigResponse
internal struct ConfigFetchResponse<T>: Codable where T: ParseConfig {
struct ConfigFetchResponse<T>: Codable where T: ParseConfig {
let params: T
}

internal struct BooleanResponse: Codable {
struct BooleanResponse: Codable {
let result: Bool
}

// MARK: HealthResponse
internal struct HealthResponse: Codable {
struct HealthResponse: Codable {
let status: ParseHealth.Status
}

// MARK: PushResponse
internal struct PushResponse: Codable {
struct PushResponse: Codable {
let data: Data
let statusId: String
}
71 changes: 40 additions & 31 deletions Sources/ParseSwift/Objects/ParseObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,30 @@ public protocol ParseObject: ParseTypeable,
*/
init()

/**
Creates a `ParseObject` with a specified `objectId`. Can be used to create references or associations
between `ParseObject`'s.
- warning: It is required that all added properties be optional properties so they can eventually be used as
Parse `Pointer`'s. If a developer really wants to have a required key, they should require it on the server-side or
create methods to check the respective properties on the client-side before saving objects. See
[here](https://github.com/parse-community/Parse-Swift/pull/315#issuecomment-1014701003)
for more information.
*/
init(objectId: String)

/**
Determines if two objects have the same objectId.
- parameter as: Object to compare.
- returns: Returns a **true** if the other object has the same `objectId` or **false** if unsuccessful.
*/
func hasSameObjectId<T: ParseObject>(as other: T) -> Bool

/**
Converts this `ParseObject` to a Parse Pointer.
- returns: The pointer version of the `ParseObject`, Pointer<Self>.
*/
func toPointer() throws -> Pointer<Self>

/**
Determines if a `KeyPath` of the current `ParseObject` should be restored
by comparing it to another `ParseObject`.
Expand Down Expand Up @@ -148,29 +172,11 @@ public protocol ParseObject: ParseTypeable,
// MARK: Default Implementations
public extension ParseObject {

/**
Creates a `ParseObject` with a specified `objectId`. Can be used to create references or associations
between `ParseObject`'s.
- warning: It is required that all added properties be optional properties so they can eventually be used as
Parse `Pointer`'s. If a developer really wants to have a required key, they should require it on the server-side or
create methods to check the respective properties on the client-side before saving objects. See
[here](https://github.com/parse-community/Parse-Swift/pull/315#issuecomment-1014701003)
for more information.
*/
init(objectId: String) {
self.init()
self.objectId = objectId
}

func hash(into hasher: inout Hasher) {
hasher.combine(self.id)
}

/**
A computed property that is a unique identifier and makes it easy to use `ParseObject`'s
as models in MVVM and SwiftUI.
- note: `id` allows `ParseObject`'s to be used even when they are not saved and do not have an `objectId`.
- important: `id` will have the same value as `objectId` when a `ParseObject` is saved.
- note: `id` allows `ParseObject`'s to be used even if they have not been saved and/or missing an `objectId`.
- important: `id` will have the same value as `objectId` when a `ParseObject` contains an `objectId`.
*/
var id: String {
objectId ?? UUID().uuidString
Expand All @@ -188,21 +194,17 @@ public extension ParseObject {
return object
}

/**
Determines if two objects have the same objectId.
- parameter as: Object to compare.
- returns: Returns a **true** if the other object has the same `objectId` or **false** if unsuccessful.
*/
init(objectId: String) {
self.init()
self.objectId = objectId
}

func hasSameObjectId<T: ParseObject>(as other: T) -> Bool {
return other.className == className && other.objectId == objectId && objectId != nil
other.className == className && other.objectId == objectId && objectId != nil
}

/**
Converts this `ParseObject` to a Parse Pointer.
- returns: The pointer version of the `ParseObject`, Pointer<Self>.
*/
func toPointer() throws -> Pointer<Self> {
return try Pointer(self)
try Pointer(self)
}

func shouldRestoreKey<W>(_ keyPath: KeyPath<Self, W?>,
Expand Down Expand Up @@ -240,6 +242,13 @@ extension ParseObject {
}
}

// MARK: Hashable
public extension ParseObject {
func hash(into hasher: inout Hasher) {
hasher.combine(self.id)
}
}

// MARK: Helper Methods
public extension ParseObject {
/**
Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/Objects/ParseUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ extension ParseUser {
if Parse.configuration.isRequiringCustomObjectIds && objectId == nil && !ignoringCustomObjectIdConfig {
throw ParseError(code: .missingObjectId, message: "objectId must not be nil")
}
if isSaved {
if try await isSaved() {
return try await replaceCommand() // MARK: Should be switched to "updateCommand" when server supports PATCH.
}
return try await createCommand()
Expand Down
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 = "5.4.2"
static let version = "5.4.3"
static let fileManagementDirectory = "parse/"
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
static let fileManagementLibraryDirectory = "Library/"
Expand Down
Loading

0 comments on commit 0e40929

Please sign in to comment.