Skip to content

Commit 639fa9a

Browse files
committed
feat: Mark ParseObject and related types as Sendable
1 parent 55d9d22 commit 639fa9a

21 files changed

+53
-35
lines changed

ParseSwift.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
707A3BF125B0A4F0000D215C /* ParseAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */; };
143143
707A3C1125B0A8E8000D215C /* ParseAnonymous.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3C1025B0A8E8000D215C /* ParseAnonymous.swift */; };
144144
707A3C2025B14BD0000D215C /* ParseApple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3C1F25B14BCF000D215C /* ParseApple.swift */; };
145+
707DC1C02C3F5DE900FC1DFD /* InputStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707DC1BF2C3F5DE900FC1DFD /* InputStream.swift */; };
145146
7085DD9426CBF3A70033B977 /* Documentation.docc in Sources */ = {isa = PBXBuildFile; fileRef = 7085DD9326CBF3A70033B977 /* Documentation.docc */; };
146147
7085DDA326CC8A470033B977 /* ParseServer+combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7085DDA226CC8A470033B977 /* ParseServer+combine.swift */; };
147148
7085DDB326D1EC7F0033B977 /* ParseAuthenticationCombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7085DDB226D1EC7F0033B977 /* ParseAuthenticationCombineTests.swift */; };
@@ -489,6 +490,7 @@
489490
707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAuthentication.swift; sourceTree = "<group>"; };
490491
707A3C1025B0A8E8000D215C /* ParseAnonymous.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAnonymous.swift; sourceTree = "<group>"; };
491492
707A3C1F25B14BCF000D215C /* ParseApple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseApple.swift; sourceTree = "<group>"; };
493+
707DC1BF2C3F5DE900FC1DFD /* InputStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputStream.swift; sourceTree = "<group>"; };
492494
7085DD9326CBF3A70033B977 /* Documentation.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = Documentation.docc; sourceTree = "<group>"; };
493495
7085DDA226CC8A470033B977 /* ParseServer+combine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ParseServer+combine.swift"; sourceTree = "<group>"; };
494496
7085DDB226D1EC7F0033B977 /* ParseAuthenticationCombineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAuthenticationCombineTests.swift; sourceTree = "<group>"; };
@@ -1084,6 +1086,7 @@
10841086
706436A827341FD0007C6461 /* Date.swift */,
10851087
70C048C02880D7E500401689 /* Dictionary.swift */,
10861088
706436A327341F6E007C6461 /* Encodable.swift */,
1089+
707DC1BF2C3F5DE900FC1DFD /* InputStream.swift */,
10871090
9116F66E26A35D600082F6D6 /* URLCache.swift */,
10881091
F97B462C24D9C74400F4A88B /* URLSession.swift */,
10891092
);
@@ -1602,6 +1605,7 @@
16021605
916E207029D8C83100C21EC6 /* ParseRelationOperationable.swift in Sources */,
16031606
70B4E0BC2762F1D5004C9757 /* QueryConstraint.swift in Sources */,
16041607
70C167B427304F09009F4E30 /* Pointer+async.swift in Sources */,
1608+
707DC1C02C3F5DE900FC1DFD /* InputStream.swift in Sources */,
16051609
705025AE28456106008D6624 /* ParsePushStatusable.swift in Sources */,
16061610
F97B464A24D9C78B00F4A88B /* ParseOperationDelete.swift in Sources */,
16071611
705025CC284CE4C2008D6624 /* ParsePushPayloadable.swift in Sources */,

Sources/ParseSwift/API/API+Command.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ import FoundationNetworking
1414
internal extension API {
1515
// MARK: API.Command
1616
// swiftlint:disable:next type_body_length
17-
struct Command<T, U>: Encodable where T: ParseEncodable {
17+
struct Command<T, U>: Encodable, Sendable where T: ParseEncodable, U: Sendable {
1818
typealias ReturnType = U // swiftlint:disable:this nesting
1919
let method: API.Method
2020
let path: API.Endpoint
2121
let body: T?
22-
let mapper: ((Data) async throws -> U)
22+
let mapper: (@Sendable (Data) async throws -> U)
2323
let params: [String: String?]?
2424
let uploadData: Data?
2525
let uploadFile: URL?
@@ -36,7 +36,7 @@ internal extension API {
3636
parseURL: URL? = nil,
3737
otherURL: URL? = nil,
3838
stream: InputStream? = nil,
39-
mapper: @escaping ((Data) async throws -> U)) {
39+
mapper: @escaping (@Sendable (Data) async throws -> U)) {
4040
self.method = method
4141
self.path = path
4242
self.body = body

Sources/ParseSwift/API/API.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import FoundationNetworking
1616
/// The REST API for communicating with a Parse Server.
1717
public struct API {
1818

19-
public enum Method: String, Encodable {
19+
public enum Method: String, Encodable, Sendable {
2020
case GET, POST, PUT, PATCH, DELETE
2121
}
2222

23-
public enum Endpoint: Encodable {
23+
public enum Endpoint: Encodable, Sendable {
2424
case batch
2525
case objects(className: String)
2626
case object(className: String, objectId: String)
@@ -139,7 +139,7 @@ public struct API {
139139
public typealias Options = Set<API.Option>
140140

141141
/// Options available to send to Parse Server.
142-
public enum Option: Hashable {
142+
public enum Option: Hashable, Sendable {
143143

144144
/// Use the primaryKey/masterKey if it was provided during initial configuraration.
145145
case usePrimaryKey
@@ -164,7 +164,7 @@ public struct API {
164164
case tags([String: String])
165165
/// Add context.
166166
/// - warning: Requires Parse Server 5.0.0+.
167-
case context(Encodable)
167+
case context(Encodable & Sendable)
168168
/// The caching policy to use for a specific http request. Determines when to
169169
/// return a response from the cache. See Apple's
170170
/// [documentation](https://developer.apple.com/documentation/foundation/url_loading_system/accessing_cached_data)

Sources/ParseSwift/API/BatchUtils.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ typealias ParseObjectBatchResponseEncodablePointer<U> = [(Result<PointerType, Pa
2323
typealias RESTBatchCommandTypeEncodablePointer<T> = API.NonParseBodyCommand<ParseObjectBatchCommandEncodablePointer<T>, ParseObjectBatchResponseEncodablePointer<Encodable>> where T: Encodable
2424
// swiftlint:enable line_length
2525

26-
internal struct BatchCommand<T, U>: ParseEncodable where T: ParseEncodable {
26+
internal struct BatchCommand<T, U>: ParseEncodable where T: ParseEncodable, U: Sendable {
2727
let requests: [API.Command<T, U>]
2828
var transaction: Bool
2929
}

Sources/ParseSwift/Authentication/Protocols/ParseAuthentication.swift

+10-9
Original file line numberDiff line numberDiff line change
@@ -396,26 +396,26 @@ public extension ParseUser {
396396
}
397397

398398
internal func linkCommand() async throws -> API.Command<Self, Self> {
399-
var mutableSelf = self.anonymous.strip(self)
399+
let strippedUser = self.anonymous.strip(self)
400400
if let current = try? await Self.current() {
401-
guard current.hasSameObjectId(as: mutableSelf) else {
401+
guard current.hasSameObjectId(as: strippedUser) else {
402402
let error = ParseError(code: .otherCause,
403403
message: "Cannot signup a user with a different objectId than the current user")
404404
throw error
405405
}
406406
}
407407
return API.Command<Self, Self>(method: .PUT,
408408
path: endpoint,
409-
body: mutableSelf) { (data) -> Self in
409+
body: strippedUser) { (data) -> Self in
410410
let user = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data)
411-
mutableSelf = user.apply(to: mutableSelf)
411+
let updatedUser = user.apply(to: strippedUser)
412412
if let sessionToken = user.sessionToken {
413-
await Self.setCurrentContainer(.init(currentUser: mutableSelf,
413+
await Self.setCurrentContainer(.init(currentUser: updatedUser,
414414
sessionToken: sessionToken))
415415
} else {
416-
try await Self.setCurrent(mutableSelf)
416+
try await Self.setCurrent(updatedUser)
417417
}
418-
return mutableSelf
418+
return updatedUser
419419
}
420420
}
421421

@@ -431,13 +431,14 @@ public extension ParseUser {
431431
}
432432
body.authData = currentAuthData
433433
}
434+
let updatedBody = body
434435

435436
return API.Command<SignupLoginBody, Self>(method: .PUT,
436437
path: endpoint,
437-
body: body) { (data) -> Self in
438+
body: updatedBody) { (data) -> Self in
438439
let user = try ParseCoding.jsonDecoder().decode(UpdateResponse.self, from: data)
439440
var currentUser = user.apply(to: currentStrippedUser)
440-
currentUser.authData = body.authData
441+
currentUser.authData = updatedBody.authData
441442
if let sessionToken = user.sessionToken {
442443
await Self.setCurrentContainer(.init(currentUser: currentUser,
443444
sessionToken: sessionToken))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// InputStream.swift
3+
// ParseSwift
4+
//
5+
// Created by Corey Baker on 7/10/24.
6+
// Copyright © 2024 Network Reconnaissance Lab. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
extension InputStream: @unchecked Sendable {}

Sources/ParseSwift/Objects/ParseUser.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -1216,13 +1216,14 @@ extension ParseUser {
12161216
let acl = try? await ParseACL.defaultACL() {
12171217
user.ACL = acl
12181218
}
1219-
let mapper = { (data) -> Self in
1219+
let updatedUser = user
1220+
let mapper = { @Sendable (data) -> Self in
12201221
try ParseCoding
12211222
.jsonDecoder()
12221223
.decode(
12231224
CreateResponse.self,
12241225
from: data
1225-
).apply(to: user)
1226+
).apply(to: updatedUser)
12261227
}
12271228
let path = try await endpoint(.POST)
12281229
let command = API.Command<Self, Self>(
@@ -1246,7 +1247,7 @@ extension ParseUser {
12461247
mutableSelf.email = nil
12471248
}
12481249
}
1249-
let mapper = { (data: Data) -> Self in
1250+
let mapper = { @Sendable (data: Data) -> Self in
12501251
var updatedUser = self
12511252
updatedUser.originalData = nil
12521253
let userResponse = try ParseCoding
@@ -1301,7 +1302,7 @@ extension ParseUser {
13011302
mutableSelf.email = nil
13021303
}
13031304
}
1304-
let mapper = { (data: Data) -> Self in
1305+
let mapper = { @Sendable (data: Data) -> Self in
13051306
var updatedUser = self
13061307
updatedUser.originalData = nil
13071308
let userResponse = try ParseCoding

Sources/ParseSwift/Parse.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import FoundationNetworking
77

88
// MARK: Internal
99

10-
internal struct Parse {
10+
internal struct Parse: Sendable {
1111
static var configuration: ParseConfiguration!
1212
static var sessionDelegate: ParseURLSessionDelegate!
1313
}

Sources/ParseSwift/ParseConstants.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010

1111
enum ParseConstants {
1212
static let sdk = "swift"
13-
static let version = "5.9.3"
13+
static let version = "5.10.0"
1414
static let fileManagementDirectory = "parse/"
1515
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
1616
static let fileManagementLibraryDirectory = "Library/"
@@ -44,7 +44,7 @@ enum Method: String {
4444
/**
4545
The types of Parse Hook Triggers available.
4646
*/
47-
public enum ParseHookTriggerType: String, Codable {
47+
public enum ParseHookTriggerType: String, Codable, Sendable {
4848
/// Occurs before login of a `ParseUser`.
4949
case beforeLogin
5050
/// Occurs after login of a `ParseUser`.

Sources/ParseSwift/Protocols/ParseEncodable.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Foundation
1212
Types that conform to **ParseEncodable** should be encoded by the
1313
`ParseEncoder` when necessary.
1414
*/
15-
public protocol ParseEncodable: Encodable {}
15+
public protocol ParseEncodable: Encodable, Sendable {}
1616

1717
// MARK: CustomDebugStringConvertible
1818
extension ParseEncodable {

Sources/ParseSwift/Protocols/ParseHookFunctionable.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public extension ParseHookFunctionable {
3737
}
3838

3939
/// A type of request for Parse Hook Functions.
40-
public struct FunctionRequest: Encodable {
40+
public struct FunctionRequest: Encodable, Sendable {
4141
let functionName: String
4242
let url: URL?
4343

Sources/ParseSwift/Protocols/ParseHookParametable.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ import Foundation
1212
Conforming to `ParseHookParametable` allows types that can be created
1313
to decode parameters in `ParseHookFunctionRequest`'s.
1414
*/
15-
public protocol ParseHookParametable: Codable, Equatable {}
15+
public protocol ParseHookParametable: Codable, Equatable, Sendable {}

Sources/ParseSwift/Protocols/ParseHookTriggerable.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public extension ParseHookTriggerable {
113113
}
114114

115115
/// A type of request for Parse Hook Triggers.
116-
public struct TriggerRequest: Encodable {
116+
public struct TriggerRequest: Encodable, Sendable {
117117
let className: String
118118
let trigger: ParseHookTriggerType
119119
let url: URL?

Sources/ParseSwift/Protocols/ParseTypeable.swift

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Foundation
1212
A special type that is considered a Parse type.
1313
*/
1414
public protocol ParseTypeable: Codable,
15+
Sendable,
1516
Equatable,
1617
CustomDebugStringConvertible,
1718
CustomStringConvertible {}

Sources/ParseSwift/Types/Operations/ParseOperationCommand.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010

1111
/// Represents all supported Parse operation commands.
12-
public enum ParseOperationCommand: String, Codable {
12+
public enum ParseOperationCommand: String, Codable, Sendable {
1313
/// The add command.
1414
case add = "Add"
1515
/// The add relation command.

Sources/ParseSwift/Types/ParseACL.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public struct ParseACL: ParseTypeable,
2525
/**
2626
An enum specifying read and write access controls.
2727
*/
28-
public enum Access: String, Codable, CodingKey {
28+
public enum Access: String, Codable, Sendable, CodingKey {
2929
/// Read access control.
3030
case read
3131
/// Write access control.

Sources/ParseSwift/Types/ParseField.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public struct ParseField: ParseTypeable {
1717
var targetClass: String?
1818

1919
/// Field types available in `ParseSchema`.
20-
public enum FieldType: String, Codable {
20+
public enum FieldType: String, Codable, Sendable {
2121
/// A string type.
2222
case string = "String"
2323
/// A number type.

Sources/ParseSwift/Types/ParseHookResponse.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Foundation
1212
Build a response after processing a `ParseHookFunctionRequest`
1313
or `ParseHookTriggerRequest`.
1414
*/
15-
public struct ParseHookResponse<R: Codable & Equatable>: ParseTypeable {
15+
public struct ParseHookResponse<R: Codable & Equatable & Sendable>: ParseTypeable {
1616
/// The data to return in the response.
1717
public var success: R?
1818
/// An object with a Parse code and message.

Sources/ParseSwift/Types/ParsePushPayload/Apple/ParsePushPayloadApple.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public struct ParsePushPayloadApple: ParsePushApplePayloadable {
7676
var sound: AnyCodable?
7777

7878
/// The type of notification.
79-
public enum PushType: String, Codable {
79+
public enum PushType: String, Codable, Sendable {
8080
/// Send as an alert.
8181
case alert
8282
/// Send as a background notification.

Sources/ParseSwift/Types/ParsePushPayload/Firebase/ParsePushPayloadFirebase.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public struct ParsePushPayloadFirebase: ParsePushFirebasePayloadable {
4646
public var notification: ParsePushFirebaseNotification?
4747

4848
/// The priority type of a notification.
49-
public enum PushPriority: String, Codable {
49+
public enum PushPriority: String, Codable, Sendable {
5050
/// Sets the priority to **5**.
5151
case normal
5252
/// Sets the priority to **10**.

Sources/ParseSwift/Types/Query.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public struct Query<T>: ParseTypeable where T: ParseObject {
132132

133133
- parameter key: The key to order by.
134134
*/
135-
public enum Order: Codable, Equatable {
135+
public enum Order: Codable, Equatable, Sendable {
136136
/// Sort in ascending order based on `key`.
137137
case ascending(String)
138138
/// Sort in descending order based on `key`.

0 commit comments

Comments
 (0)