Skip to content

Commit

Permalink
feat: Add new health statuses and delay attempts (#43)
Browse files Browse the repository at this point in the history
* feat: Add new health statuses and delay attempts

* nits

* Switch ParseHealth combine from Future to PassthroughSubject

* improvements

* add tests and changelog

* nits

* improve added tests and changelog

* fix flakey LiveQuery tests

* fix failing linux/windows tests

* don't lint markdown files

* nit CI

* revert running tests on windows

* improve tests
  • Loading branch information
cbaker6 authored Jan 12, 2023
1 parent cabf542 commit 9c70348
Show file tree
Hide file tree
Showing 28 changed files with 850 additions and 104 deletions.
26 changes: 24 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- markdownlint-disable -->
# Parse-Swift Changelog

### main
Expand All @@ -7,9 +8,30 @@
### 5.0.0
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/4.16.2...5.0.0), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.0.0/documentation/parseswift)

__New features__

* (Breaking Change) Added a new ParseHealth.Status enum to support Parse Server.
Developers can access the new status values (Status.initialized, Status.starting)
using the ParseHealth.check callback or Combine methods. The new status values
are not available for async/await and synchounous methods. Connecting to Parse
Servers < 6.0.0, using async/await, or synchronous methods only returns
Status.ok or throws an error
([#43](https://github.com/netreconlab/Parse-Swift/pull/43)),
thanks to [Corey Baker](https://github.com/cbaker6).

* The Swift SDK can now properly handle HTTP Status codes 429 and 503 and will retry after the delay specified in the respective header ([#43](https://github.com/netreconlab/Parse-Swift/pull/43)), thanks to [Corey Baker](https://github.com/cbaker6).

* The max connection attempts for LiveQuery can now be changed when initializing the SDK ([#43](https://github.com/netreconlab/Parse-Swift/pull/43)), thanks to [Corey Baker](https://github.com/cbaker6).

__Fixes__
- (Breaking Change) Add and update ParseError codes. unknownError has been renamed to otherCause. invalidImageData now has the error code of 150. webhookError has the error code of 143 ([#23](https://github.com/netreconlab/Parse-Swift/pull/23)), thanks to [Corey Baker](https://github.com/cbaker6).
- (Breaking Change) Remove deprecated code ([#23](https://github.com/netreconlab/Parse-Swift/pull/23)), thanks to [Corey Baker](https://github.com/cbaker6).
* (Breaking Change) Add and update ParseError codes. unknownError has been renamed
to otherCause. invalidImageData now has the error code of 150. webhookError has
the error code of 143 ([#23](https://github.com/netreconlab/Parse-Swift/pull/23)),
thanks to [Corey Baker](https://github.com/cbaker6).

* (Breaking Change) Remove deprecated code
([#23](https://github.com/netreconlab/Parse-Swift/pull/23)), thanks
to [Corey Baker](https://github.com/cbaker6).

### 4.16.2
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/4.16.1...4.16.2), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/4.16.2/documentation/parseswift)
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- markdownlint-disable -->
# Contributing to the ParseSwift SDK <!-- omit in toc -->

## Table of Contents <!-- omit in toc -->
Expand Down
22 changes: 10 additions & 12 deletions ParseSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@
7028373A26BD8C89007688C9 /* ParseUser+async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7028373826BD8C89007688C9 /* ParseUser+async.swift */; };
7028373B26BD8C89007688C9 /* ParseUser+async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7028373826BD8C89007688C9 /* ParseUser+async.swift */; };
7028373C26BD8C89007688C9 /* ParseUser+async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7028373826BD8C89007688C9 /* ParseUser+async.swift */; };
7031F356296F553200E077CC /* APICommandMultipleAttemptsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7031F355296F553200E077CC /* APICommandMultipleAttemptsTests.swift */; };
7031F357296F553200E077CC /* APICommandMultipleAttemptsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7031F355296F553200E077CC /* APICommandMultipleAttemptsTests.swift */; };
7031F358296F553200E077CC /* APICommandMultipleAttemptsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7031F355296F553200E077CC /* APICommandMultipleAttemptsTests.swift */; };
7033ECB325584A83009770F3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7033ECB225584A83009770F3 /* AppDelegate.swift */; };
7033ECB525584A83009770F3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7033ECB425584A83009770F3 /* ViewController.swift */; };
7033ECB825584A83009770F3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7033ECB625584A83009770F3 /* Main.storyboard */; };
Expand Down Expand Up @@ -588,10 +591,6 @@
70C550A125B4A9F600B5DBC2 /* RemoveRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C5509F25B4A9F600B5DBC2 /* RemoveRelation.swift */; };
70C550A225B4A9F600B5DBC2 /* RemoveRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C5509F25B4A9F600B5DBC2 /* RemoveRelation.swift */; };
70C550A325B4A9F600B5DBC2 /* RemoveRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C5509F25B4A9F600B5DBC2 /* RemoveRelation.swift */; };
70C5655925AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C5655825AA147B00BDD57F /* ParseLiveQueryConstants.swift */; };
70C5655A25AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C5655825AA147B00BDD57F /* ParseLiveQueryConstants.swift */; };
70C5655B25AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C5655825AA147B00BDD57F /* ParseLiveQueryConstants.swift */; };
70C5655C25AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C5655825AA147B00BDD57F /* ParseLiveQueryConstants.swift */; };
70C7DC1E24D20E530050419B /* ParseUserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C7DC1D24D20E530050419B /* ParseUserTests.swift */; };
70C7DC2124D20F190050419B /* ParseQueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C7DC1F24D20F180050419B /* ParseQueryTests.swift */; };
70C7DC2224D20F190050419B /* ParseObjectBatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70C7DC2024D20F190050419B /* ParseObjectBatchTests.swift */; };
Expand Down Expand Up @@ -1196,6 +1195,7 @@
7023800E2747FCCD00EFC443 /* ExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionsTests.swift; sourceTree = "<group>"; };
7028373326BD8883007688C9 /* ParseObject+async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseObject+async.swift"; sourceTree = "<group>"; };
7028373826BD8C89007688C9 /* ParseUser+async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseUser+async.swift"; sourceTree = "<group>"; };
7031F355296F553200E077CC /* APICommandMultipleAttemptsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APICommandMultipleAttemptsTests.swift; sourceTree = "<group>"; };
7033ECB025584A83009770F3 /* TestHostTV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestHostTV.app; sourceTree = BUILT_PRODUCTS_DIR; };
7033ECB225584A83009770F3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7033ECB425584A83009770F3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1323,7 +1323,6 @@
70C5508425B4A68700B5DBC2 /* ParseOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseOperationTests.swift; sourceTree = "<group>"; };
70C5509125B4A99100B5DBC2 /* AddRelation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRelation.swift; sourceTree = "<group>"; };
70C5509F25B4A9F600B5DBC2 /* RemoveRelation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveRelation.swift; sourceTree = "<group>"; };
70C5655825AA147B00BDD57F /* ParseLiveQueryConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseLiveQueryConstants.swift; sourceTree = "<group>"; };
70C7DC1D24D20E530050419B /* ParseUserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseUserTests.swift; sourceTree = "<group>"; };
70C7DC1F24D20F180050419B /* ParseQueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseQueryTests.swift; sourceTree = "<group>"; };
70C7DC2024D20F190050419B /* ParseObjectBatchTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseObjectBatchTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1597,6 +1596,7 @@
children = (
4AA8076D1F794C1C008CD551 /* Info.plist */,
911DB12D24C4837E0027F3C7 /* APICommandTests.swift */,
7031F355296F553200E077CC /* APICommandMultipleAttemptsTests.swift */,
7003957525A0EE770052CB31 /* BatchUtilsTests.swift */,
7023800E2747FCCD00EFC443 /* ExtensionsTests.swift */,
70DFEA892618E77800F8EB4B /* InitializeSDKTests.swift */,
Expand Down Expand Up @@ -1940,7 +1940,6 @@
7003960825A184EF0052CB31 /* ParseLiveQuery.swift */,
703B091526BD99BC005A112F /* ParseLiveQuery+async.swift */,
918CED582684C74000CFDC83 /* ParseLiveQuery+combine.swift */,
70C5655825AA147B00BDD57F /* ParseLiveQueryConstants.swift */,
700395B925A1470F0052CB31 /* Subscription.swift */,
705D950725BE4C08003EF6F8 /* SubscriptionCallback.swift */,
700395DE25A147C40052CB31 /* Protocols */,
Expand Down Expand Up @@ -2790,7 +2789,6 @@
7004C22025B63C7A005E0AD9 /* ParseRelation.swift in Sources */,
7003959525A10DFC0052CB31 /* Messages.swift in Sources */,
703B091126BD992E005A112F /* ParseOperation+async.swift in Sources */,
70C5655925AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */,
91F346BE269B77B5005727B6 /* CloudObservable.swift in Sources */,
F97B462F24D9C74400F4A88B /* BatchUtils.swift in Sources */,
70385E802858EAA90084D306 /* ParseHookFunctionRequest.swift in Sources */,
Expand Down Expand Up @@ -2955,6 +2953,7 @@
70E6B01E28612FF00043EC4A /* ParseHookTriggerTests.swift in Sources */,
705025A12843F0E7008D6624 /* ParseSchemaCombineTests.swift in Sources */,
7044C1F925C5CFAB0011F6E7 /* ParseFileCombineTests.swift in Sources */,
7031F356296F553200E077CC /* APICommandMultipleAttemptsTests.swift in Sources */,
70C5502225B3D8F700B5DBC2 /* ParseAppleTests.swift in Sources */,
917BA4322703E36800F8D747 /* ParseConfigAsyncTests.swift in Sources */,
89899DB526045DC4002E2043 /* ParseFacebookCombineTests.swift in Sources */,
Expand Down Expand Up @@ -3103,7 +3102,6 @@
7004C22125B63C7A005E0AD9 /* ParseRelation.swift in Sources */,
7003959625A10DFC0052CB31 /* Messages.swift in Sources */,
703B091226BD992E005A112F /* ParseOperation+async.swift in Sources */,
70C5655A25AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */,
91F346BF269B77B5005727B6 /* CloudObservable.swift in Sources */,
F97B463024D9C74400F4A88B /* BatchUtils.swift in Sources */,
4AFDA72A1F26DAE1002AE4FC /* Parse.swift in Sources */,
Expand Down Expand Up @@ -3278,6 +3276,7 @@
70E6B02028612FF00043EC4A /* ParseHookTriggerTests.swift in Sources */,
705025A32843F0E7008D6624 /* ParseSchemaCombineTests.swift in Sources */,
7044C1FB25C5CFAB0011F6E7 /* ParseFileCombineTests.swift in Sources */,
7031F358296F553200E077CC /* APICommandMultipleAttemptsTests.swift in Sources */,
70C5502425B3D8F700B5DBC2 /* ParseAppleTests.swift in Sources */,
917BA4342703E36800F8D747 /* ParseConfigAsyncTests.swift in Sources */,
89899DB726045DC4002E2043 /* ParseFacebookCombineTests.swift in Sources */,
Expand Down Expand Up @@ -3402,6 +3401,7 @@
70E6B01F28612FF00043EC4A /* ParseHookTriggerTests.swift in Sources */,
705025A22843F0E7008D6624 /* ParseSchemaCombineTests.swift in Sources */,
7044C1FA25C5CFAB0011F6E7 /* ParseFileCombineTests.swift in Sources */,
7031F357296F553200E077CC /* APICommandMultipleAttemptsTests.swift in Sources */,
70C5502325B3D8F700B5DBC2 /* ParseAppleTests.swift in Sources */,
917BA4332703E36800F8D747 /* ParseConfigAsyncTests.swift in Sources */,
89899DB626045DC4002E2043 /* ParseFacebookCombineTests.swift in Sources */,
Expand Down Expand Up @@ -3550,7 +3550,6 @@
7004C22325B63C7A005E0AD9 /* ParseRelation.swift in Sources */,
7003959825A10DFC0052CB31 /* Messages.swift in Sources */,
703B091426BD992E005A112F /* ParseOperation+async.swift in Sources */,
70C5655C25AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */,
91F346C1269B77B5005727B6 /* CloudObservable.swift in Sources */,
70BDA2B6250536FF00FC2237 /* ParseInstallation.swift in Sources */,
F97B465924D9C78C00F4A88B /* Remove.swift in Sources */,
Expand Down Expand Up @@ -3740,7 +3739,6 @@
7004C22225B63C7A005E0AD9 /* ParseRelation.swift in Sources */,
7003959725A10DFC0052CB31 /* Messages.swift in Sources */,
703B091326BD992E005A112F /* ParseOperation+async.swift in Sources */,
70C5655B25AA147B00BDD57F /* ParseLiveQueryConstants.swift in Sources */,
91F346C0269B77B5005727B6 /* CloudObservable.swift in Sources */,
70BDA2B5250536FF00FC2237 /* ParseInstallation.swift in Sources */,
F97B465824D9C78C00F4A88B /* Remove.swift in Sources */,
Expand Down Expand Up @@ -3967,7 +3965,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -4029,7 +4027,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MACOSX_DEPLOYMENT_TARGET = 10.13;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<!-- markdownlint-disable -->
![parse-swift](https://user-images.githubusercontent.com/8621344/204069535-e1882bb0-bbcb-4178-87e6-58fd1bed96d1.png)

<h3 align="center">iOS · macOS · watchOS · tvOS · Linux · Android · Windows</h3>
Expand Down
2 changes: 1 addition & 1 deletion Scripts/generate-documentation
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ xcrun docc $DOCC_CMD \
--additional-symbol-graph-dir "$SGFS_DIR" \
--output-path "$OUTPUT_PATH" $EXTRA_DOCC_FLAGS \
--fallback-display-name ParseSwift \
--fallback-bundle-identifier com.parse.ParseSwift \
--fallback-bundle-identifier edu.uky.cs.netreconlab.ParseSwift \
--fallback-bundle-version 1.0.0

if [[ "$DOCC_CMD" == "convert"* ]]; then
Expand Down
2 changes: 2 additions & 0 deletions Sources/ParseSwift/API/API+Command+async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal extension API.Command {
notificationQueue: DispatchQueue? = nil,
childObjects: [String: PointerType]? = nil,
childFiles: [UUID: ParseFile]? = nil,
allowIntermediateResponses: Bool = false,
uploadProgress: ((URLSessionTask, Int64, Int64, Int64) -> Void)? = nil,
downloadProgress: ((URLSessionDownloadTask, Int64, Int64, Int64) -> Void)? = nil) async throws -> U {
try await withCheckedThrowingContinuation { continuation in
Expand All @@ -29,6 +30,7 @@ internal extension API.Command {
notificationQueue: notificationQueue,
childObjects: childObjects,
childFiles: childFiles,
allowIntermediateResponses: allowIntermediateResponses,
uploadProgress: uploadProgress,
downloadProgress: downloadProgress,
completion: continuation.resume)
Expand Down
4 changes: 4 additions & 0 deletions Sources/ParseSwift/API/API+Command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ internal extension API {
notificationQueue: notificationQueue,
childObjects: childObjects,
childFiles: childFiles,
allowIntermediateResponses: false,
uploadProgress: uploadProgress,
downloadProgress: downloadProgress) { result in
responseResult = result
Expand All @@ -126,6 +127,7 @@ internal extension API {
notificationQueue: DispatchQueue? = nil,
childObjects: [String: PointerType]? = nil,
childFiles: [UUID: ParseFile]? = nil,
allowIntermediateResponses: Bool = false,
uploadProgress: ((URLSessionTask, Int64, Int64, Int64) -> Void)? = nil,
downloadProgress: ((URLSessionDownloadTask, Int64, Int64, Int64) -> Void)? = nil,
completion: @escaping(Result<U, ParseError>) -> Void) {
Expand All @@ -144,6 +146,7 @@ internal extension API {
case .success(let urlRequest):
URLSession.parse.dataTask(with: urlRequest,
callbackQueue: callbackQueue,
allowIntermediateResponses: allowIntermediateResponses,
mapper: mapper) { result in
callbackQueue.async {
switch result {
Expand Down Expand Up @@ -202,6 +205,7 @@ internal extension API {
case .success(let urlRequest):
URLSession.parse.dataTask(with: urlRequest,
callbackQueue: callbackQueue,
allowIntermediateResponses: allowIntermediateResponses,
mapper: mapper) { result in
callbackQueue.async {
switch result {
Expand Down
4 changes: 3 additions & 1 deletion Sources/ParseSwift/API/API+NonParseBodyCommand+async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import FoundationNetworking
extension API.NonParseBodyCommand {
// MARK: Asynchronous Execution
func execute(options: API.Options,
callbackQueue: DispatchQueue) async throws -> U {
callbackQueue: DispatchQueue,
allowIntermediateResponses: Bool = false) async throws -> U {
try await withCheckedThrowingContinuation { continuation in
self.executeAsync(options: options,
callbackQueue: callbackQueue,
allowIntermediateResponses: allowIntermediateResponses,
completion: continuation.resume)
}
}
Expand Down
5 changes: 4 additions & 1 deletion Sources/ParseSwift/API/API+NonParseBodyCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ internal extension API {
let group = DispatchGroup()
group.enter()
self.executeAsync(options: options,
callbackQueue: synchronizationQueue) { result in
callbackQueue: synchronizationQueue,
allowIntermediateResponses: false) { result in
responseResult = result
group.leave()
}
Expand All @@ -59,12 +60,14 @@ internal extension API {
// MARK: Asynchronous Execution
func executeAsync(options: API.Options,
callbackQueue: DispatchQueue,
allowIntermediateResponses: Bool = false,
completion: @escaping(Result<U, ParseError>) -> Void) {

switch self.prepareURLRequest(options: options) {
case .success(let urlRequest):
URLSession.parse.dataTask(with: urlRequest,
callbackQueue: callbackQueue,
allowIntermediateResponses: allowIntermediateResponses,
mapper: mapper) { result in
callbackQueue.async {
switch result {
Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/API/Responses.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ internal struct BooleanResponse: Codable {

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

// MARK: PushResponse
Expand Down
Loading

0 comments on commit 9c70348

Please sign in to comment.