Skip to content

Commit ac6d6f9

Browse files
authored
Make backgroundTask available for MacOS 10.15 (#299)
1 parent 75599e1 commit ac6d6f9

8 files changed

+152
-76
lines changed

Sources/SwiftQueue/JobBuilder.swift

+11
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ public final class JobBuilder {
7272
/// Limit of period to reproduce
7373
/// interval between each run. Does not affect the first iteration. Please add delay if so
7474
/// executor will make the job being scheduling to run in background with BackgroundTask API
75+
public func periodic(limit: Limit = .unlimited, interval: TimeInterval = 0) -> Self {
76+
assert(limit.validate)
77+
assert(interval >= 0)
78+
info.maxRun = limit
79+
info.interval = interval
80+
info.executor = .foreground
81+
return self
82+
}
83+
84+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
7585
public func periodic(limit: Limit = .unlimited, interval: TimeInterval = 0, executor: Executor = .foreground) -> Self {
7686
assert(limit.validate)
7787
assert(interval >= 0)
@@ -81,6 +91,7 @@ public final class JobBuilder {
8191
return self
8292
}
8393

94+
8495
/// Connectivity constraint.
8596
public func internet(atLeast: NetworkType) -> Self {
8697
info.requireNetwork = atLeast

Sources/ios/SwiftQueueManager+BackgroundTask.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import BackgroundTasks
2525
#endif
2626

27-
@available(iOS 13.0, tvOS 13.0, *)
27+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
2828
/// Extension of SwiftQueueManager to support BackgroundTask API from iOS 13.
2929
public extension SwiftQueueManager {
3030

@@ -57,7 +57,7 @@ public extension SwiftQueueManager {
5757
}
5858
}
5959

60-
@available(iOS 13.0, tvOS 13.0, *)
60+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
6161
internal extension SqOperation {
6262

6363
func scheduleBackgroundTask() {
@@ -75,7 +75,7 @@ internal extension SqOperation {
7575
}
7676
}
7777

78-
@available(iOS 13.0, tvOS 13.0, *)
78+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
7979
private class TaskJobResult: JobResult {
8080

8181
private let task: BGTask

SwiftQueue.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
D0B7CD1E797A69C89CB0ADE2 /* SqOperationQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B7CB571CECEEA34DD07398 /* SqOperationQueue.swift */; };
9696
D0B7CE62CE9A0DB7DF08FB57 /* ConstraintUniqueUUIDTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B7C37E250DEE9A9B55C8ED /* ConstraintUniqueUUIDTests.swift */; };
9797
D0B7CFA2089DFF576E0D765B /* JobBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B7CB3B79E039D3B11D8921 /* JobBuilder.swift */; };
98+
FA56F798BA513E48E5C686D4 /* BackgroundTasksTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA56F261936CF36C1851C98F /* BackgroundTasksTest.swift */; };
9899
OBJ_29 /* SwiftQueue.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* SwiftQueue.framework */; };
99100
/* End PBXBuildFile section */
100101

@@ -144,6 +145,7 @@
144145
D0B7C898344F1EB3A0815D67 /* ConstraintDeadlineTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintDeadlineTests.swift; sourceTree = "<group>"; };
145146
D0B7CB3B79E039D3B11D8921 /* JobBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JobBuilder.swift; path = SwiftQueue/JobBuilder.swift; sourceTree = "<group>"; };
146147
D0B7CB571CECEEA34DD07398 /* SqOperationQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SqOperationQueue.swift; path = SwiftQueue/SqOperationQueue.swift; sourceTree = "<group>"; };
148+
FA56F261936CF36C1851C98F /* BackgroundTasksTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundTasksTest.swift; sourceTree = "<group>"; };
147149
OBJ_13 /* SwiftQueue.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftQueue.framework; sourceTree = BUILT_PRODUCTS_DIR; };
148150
OBJ_14 /* SwiftQueueTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = SwiftQueueTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
149151
/* End PBXFileReference section */
@@ -210,6 +212,7 @@
210212
D0B7C2A57EFC83B94E3146B3 /* Package.swift */,
211213
95A2193AF039008357A8D362 /* LoggerTests.swift */,
212214
1E68E5F915860945E5B09AB1 /* SwiftQueueManagerTests.swift */,
215+
FA56F261936CF36C1851C98F /* BackgroundTasksTest.swift */,
213216
);
214217
name = SwiftQueueTests;
215218
path = Tests/SwiftQueueTests;
@@ -524,6 +527,7 @@
524527
D0B7C6C3E08DF6BFD0737E4D /* ConstraintDeadlineTests.swift in Sources */,
525528
95A214C332FB7115C12F88D2 /* LoggerTests.swift in Sources */,
526529
1E68EBC1AD12ACDE3162054B /* SwiftQueueManagerTests.swift in Sources */,
530+
FA56F798BA513E48E5C686D4 /* BackgroundTasksTest.swift in Sources */,
527531
);
528532
runOnlyForDeploymentPostprocessing = 0;
529533
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2019 Lucas Nelaupe
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import XCTest
24+
import Dispatch
25+
@testable import SwiftQueue
26+
27+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
28+
class BackgroundTasksTest {
29+
30+
let serializers: [JobInfoSerializer] = [
31+
V1Serializer(),
32+
DecodableSerializer()
33+
]
34+
35+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
36+
public func testBackgroundOperationShouldNotRun() {
37+
let (type, job) = (UUID().uuidString, TestJob())
38+
39+
let creator = TestCreator([type: job])
40+
41+
let manager = SwiftQueueManagerBuilder(creator: creator).set(persister: NoSerializer.shared).build()
42+
JobBuilder(type: type)
43+
.periodic(executor: .background)
44+
.internet(atLeast: .wifi)
45+
.priority(priority: .veryHigh)
46+
.service(quality: .background)
47+
.schedule(manager: manager)
48+
49+
job.assertNoRun()
50+
}
51+
52+
53+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
54+
public func testBuilderPeriodicLimited() throws {
55+
for serializer in serializers {
56+
let type = UUID().uuidString
57+
let limited: Double = 123
58+
let interval: Double = 12342
59+
let executor = Executor.any
60+
61+
let jobInfo = try toJobInfo(serializer, type: type, JobBuilder(type: type).periodic(limit: .limited(limited), interval: interval, executor: .any))
62+
XCTAssertEqual(jobInfo?.maxRun, Limit.limited(limited))
63+
XCTAssertEqual(jobInfo?.interval, interval)
64+
XCTAssertEqual(jobInfo?.executor, executor)
65+
}
66+
}
67+
68+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
69+
public func testBuilderPeriodicBackground() throws {
70+
for serializer in serializers {
71+
let type = UUID().uuidString
72+
let limited: Double = 123
73+
let interval: Double = 12342
74+
let executor = Executor.background
75+
76+
let jobInfo = try toJobInfo(serializer, type: type, JobBuilder(type: type).periodic(limit: .limited(limited), interval: interval, executor: .background))
77+
XCTAssertEqual(jobInfo?.maxRun, Limit.limited(limited))
78+
XCTAssertEqual(jobInfo?.interval, interval)
79+
XCTAssertEqual(jobInfo?.executor, executor)
80+
}
81+
}
82+
83+
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
84+
public func testGetAllAllowBackgroundOperation() {
85+
let (type, job) = (UUID().uuidString, TestJob())
86+
87+
let id = UUID().uuidString
88+
let id2 = UUID().uuidString
89+
90+
let group = UUID().uuidString
91+
let group2 = UUID().uuidString
92+
93+
let creator = TestCreator([type: job])
94+
95+
let persister = PersisterTracker(key: UUID().uuidString)
96+
97+
let manager = SwiftQueueManagerBuilder(creator: creator).set(isSuspended: true).set(persister: persister).build()
98+
99+
JobBuilder(type: type).periodic(executor: .foreground).parallel(queueName: group).schedule(manager: manager)
100+
JobBuilder(type: type).periodic(executor: .foreground).parallel(queueName: group2).schedule(manager: manager)
101+
102+
JobBuilder(type: type).singleInstance(forId: id).periodic(executor: .background).parallel(queueName: group).schedule(manager: manager)
103+
JobBuilder(type: type).singleInstance(forId: id2).periodic(executor: .any).parallel(queueName: group2).schedule(manager: manager)
104+
105+
let result = manager.getAllAllowBackgroundOperation()
106+
107+
XCTAssertEqual(2, result.count)
108+
XCTAssertTrue([id, id2].contains(result[0].info.uuid))
109+
XCTAssertTrue([id, id2].contains(result[1].info.uuid))
110+
}
111+
112+
113+
114+
}

Tests/SwiftQueueTests/LoggerTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class LoggerTests: XCTestCase {
3939
let manager = SwiftQueueManagerBuilder(creator: creator).set(persister: NoSerializer.shared).set(logger: debugLogger).build()
4040
JobBuilder(type: type)
4141
.singleInstance(forId: id)
42-
.internet(atLeast: .wifi)
42+
.internet(atLeast: .any)
4343
.schedule(manager: manager)
4444

4545
job.awaitForRemoval()

Tests/SwiftQueueTests/SwiftQueueBuilderTests.swift

+2-27
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,12 @@ class SwiftQueueBuilderTests: XCTestCase {
108108
for serializer in serializers {
109109
let type = UUID().uuidString
110110
let interval: Double = 12341
111+
let executor = Executor.foreground
111112

112113
let jobInfo = try toJobInfo(serializer, type: type, JobBuilder(type: type).periodic(limit: .unlimited, interval: interval))
113114
XCTAssertEqual(jobInfo?.maxRun, Limit.unlimited)
114115
XCTAssertEqual(jobInfo?.interval, interval)
115-
}
116-
}
117-
118-
public func testBuilderPeriodicLimited() throws {
119-
for serializer in serializers {
120-
let type = UUID().uuidString
121-
let limited: Double = 123
122-
let interval: Double = 12342
123-
124-
let jobInfo = try toJobInfo(serializer, type: type, JobBuilder(type: type).periodic(limit: .limited(limited), interval: interval))
125-
XCTAssertEqual(jobInfo?.maxRun, Limit.limited(limited))
126-
XCTAssertEqual(jobInfo?.interval, interval)
116+
XCTAssertEqual(jobInfo?.executor, executor)
127117
}
128118
}
129119

@@ -227,21 +217,6 @@ class SwiftQueueBuilderTests: XCTestCase {
227217
}
228218
}
229219

230-
private func toJobInfo(_ serializer: JobInfoSerializer, type: String, _ builder: JobBuilder) throws -> JobInfo? {
231-
let creator = TestCreator([type: TestJob()])
232-
233-
let persister = PersisterTracker(key: UUID().uuidString)
234-
235-
let manager = SwiftQueueManagerBuilder(creator: creator)
236-
.set(persister: persister)
237-
.set(serializer: serializer)
238-
.build()
239-
240-
builder.persist(required: true).schedule(manager: manager)
241-
242-
return try serializer.deserialize(json: persister.putData[0])
243-
}
244-
245220
private func assertUnicode(_ serializer: JobInfoSerializer, expected: String, file: StaticString = #file, line: UInt = #line) throws {
246221
let type = UUID().uuidString
247222

Tests/SwiftQueueTests/SwiftQueueManagerTests.swift

+1-45
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class SwiftQueueManagerTests: XCTestCase {
3333

3434
let manager = SwiftQueueManagerBuilder(creator: creator).set(persister: NoSerializer.shared).build()
3535
JobBuilder(type: type)
36-
.internet(atLeast: .wifi)
36+
.internet(atLeast: .any)
3737
.priority(priority: .veryHigh)
3838
.service(quality: .background)
3939

@@ -197,34 +197,6 @@ class SwiftQueueManagerTests: XCTestCase {
197197
XCTAssertNotEqual(Limit.unlimited, Limit.limited(-1))
198198
}
199199

200-
public func testGetAllAllowBackgroundOperation() {
201-
let (type, job) = (UUID().uuidString, TestJob())
202-
203-
let id = UUID().uuidString
204-
let id2 = UUID().uuidString
205-
206-
let group = UUID().uuidString
207-
let group2 = UUID().uuidString
208-
209-
let creator = TestCreator([type: job])
210-
211-
let persister = PersisterTracker(key: UUID().uuidString)
212-
213-
let manager = SwiftQueueManagerBuilder(creator: creator).set(isSuspended: true).set(persister: persister).build()
214-
215-
JobBuilder(type: type).periodic(executor: .foreground).parallel(queueName: group).schedule(manager: manager)
216-
JobBuilder(type: type).periodic(executor: .foreground).parallel(queueName: group2).schedule(manager: manager)
217-
218-
JobBuilder(type: type).singleInstance(forId: id).periodic(executor: .background).parallel(queueName: group).schedule(manager: manager)
219-
JobBuilder(type: type).singleInstance(forId: id2).periodic(executor: .any).parallel(queueName: group2).schedule(manager: manager)
220-
221-
let result = manager.getAllAllowBackgroundOperation()
222-
223-
XCTAssertEqual(2, result.count)
224-
XCTAssertTrue([id, id2].contains(result[0].info.uuid))
225-
XCTAssertTrue([id, id2].contains(result[1].info.uuid))
226-
}
227-
228200
public func testGetOperation() {
229201
let (type, job) = (UUID().uuidString, TestJob())
230202
let id = UUID().uuidString
@@ -244,22 +216,6 @@ class SwiftQueueManagerTests: XCTestCase {
244216
XCTAssertEqual(id, operation?.info.uuid)
245217
}
246218

247-
public func testBackgroundOperationShouldNotRun() {
248-
let (type, job) = (UUID().uuidString, TestJob())
249-
250-
let creator = TestCreator([type: job])
251-
252-
let manager = SwiftQueueManagerBuilder(creator: creator).set(persister: NoSerializer.shared).build()
253-
JobBuilder(type: type)
254-
.periodic(executor: .background)
255-
.internet(atLeast: .wifi)
256-
.priority(priority: .veryHigh)
257-
.service(quality: .background)
258-
.schedule(manager: manager)
259-
260-
job.assertNoRun()
261-
}
262-
263219
public func testGetAll() {
264220
let creator = TestCreator([:])
265221
let manager = SwiftQueueManagerBuilder(creator: creator).set(persister: NoSerializer.shared).build()

Tests/SwiftQueueTests/TestUtils.swift

+16
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,19 @@ extension JobBuilder {
270270
}
271271

272272
}
273+
274+
func toJobInfo(_ serializer: JobInfoSerializer, type: String, _ builder: JobBuilder) throws -> JobInfo? {
275+
let creator = TestCreator([type: TestJob()])
276+
277+
let persister = PersisterTracker(key: UUID().uuidString)
278+
279+
let manager = SwiftQueueManagerBuilder(creator: creator)
280+
.set(persister: persister)
281+
.set(serializer: serializer)
282+
.build()
283+
284+
builder.persist(required: true).schedule(manager: manager)
285+
286+
return try serializer.deserialize(json: persister.putData[0])
287+
}
288+

0 commit comments

Comments
 (0)