Skip to content

Commit 51cef0b

Browse files
authored
Merge pull request #425 from erik-apple/stable-candidate
Stable candidate
2 parents 0ac0e5b + 754a107 commit 51cef0b

File tree

71 files changed

+1187
-759
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1187
-759
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
language: swift
2-
osx_image: xcode11
2+
osx_image: xcode11.4
33
xcode_workspace: CKWorkspace.xcworkspace
44
xcode_scheme: CareKit
5-
xcode_destination: platform=iOS Simulator,OS=13.0,name=iPhone 11 Pro Max
5+
xcode_destination: platform=iOS Simulator,OS=13.4,name=iPhone 11 Pro Max

CareKit.xctestplan

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,93 @@
22
"configurations" : [
33
{
44
"id" : "28C2AC89-B957-4FB0-9242-53AEB9E6D4B0",
5-
"name" : "Configuration 1",
5+
"name" : "Default",
66
"options" : {
77

88
}
9+
},
10+
{
11+
"id" : "42D7C666-B3E1-4F36-88FB-E0B87436BB05",
12+
"name" : "Germany",
13+
"options" : {
14+
"language" : "de",
15+
"locationScenario" : {
16+
"identifier" : "London, England",
17+
"referenceType" : "built-in"
18+
},
19+
"region" : "DE"
20+
}
21+
},
22+
{
23+
"id" : "76269B8E-AEA1-4864-AA9A-F583B2F54AF1",
24+
"name" : "Africa",
25+
"options" : {
26+
"locationScenario" : {
27+
"identifier" : "Johannesburg, South Africa",
28+
"referenceType" : "built-in"
29+
},
30+
"region" : "EG"
31+
}
32+
},
33+
{
34+
"id" : "34F9B126-5A5C-4F0A-A861-84C9B2376FA2",
35+
"name" : "Australia",
36+
"options" : {
37+
"language" : "en-AU",
38+
"locationScenario" : {
39+
"identifier" : "Sydney, Australia",
40+
"referenceType" : "built-in"
41+
},
42+
"region" : "AU"
43+
}
44+
},
45+
{
46+
"id" : "05B1E279-40AF-49C6-8BAC-86779932468D",
47+
"name" : "England",
48+
"options" : {
49+
"language" : "en-GB",
50+
"locationScenario" : {
51+
"identifier" : "London, England",
52+
"referenceType" : "built-in"
53+
},
54+
"region" : "GB"
55+
}
56+
},
57+
{
58+
"id" : "F4D2A746-C1E8-4D5A-BCD7-EEEC3D73CEC5",
59+
"name" : "Japan",
60+
"options" : {
61+
"language" : "ja",
62+
"locationScenario" : {
63+
"identifier" : "Tokyo, Japan",
64+
"referenceType" : "built-in"
65+
},
66+
"region" : "JP"
67+
}
68+
},
69+
{
70+
"id" : "4DB57CAB-36AB-4D1A-8259-C918197191CE",
71+
"name" : "Hong Kong",
72+
"options" : {
73+
"language" : "zh-HK",
74+
"locationScenario" : {
75+
"identifier" : "Hong Kong, China",
76+
"referenceType" : "built-in"
77+
},
78+
"region" : "HK"
79+
}
80+
},
81+
{
82+
"id" : "2DEE87AE-1E91-4B64-BA06-8B37298B2A16",
83+
"name" : "Mexico",
84+
"options" : {
85+
"language" : "es-419",
86+
"locationScenario" : {
87+
"identifier" : "Mexico City, Mexico",
88+
"referenceType" : "built-in"
89+
},
90+
"region" : "MX"
91+
}
992
}
1093
],
1194
"defaultOptions" : {
@@ -19,7 +102,7 @@
19102
{
20103
"containerPath" : "container:CareKitCarePlanStore\/CareKitCarePlanStore.xcodeproj",
21104
"identifier" : "E784B8F72232EED600736CA5",
22-
"name" : "CareKitCarePlanStore"
105+
"name" : "CareKitStore"
23106
}
24107
]
25108
},

CareKit/CareKit.xcodeproj/project.pbxproj

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
032C86F02326B68D00D0A0EA /* Calendar+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032C86EF2326B68D00D0A0EA /* Calendar+Extensions.swift */; };
11-
1409474C22B020C4005C1D16 /* CareKitStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1409474A22B020C4005C1D16 /* CareKitStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1211
1409474E22B020CA005C1D16 /* CareKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1409474D22B020CA005C1D16 /* CareKitUI.framework */; };
13-
1409474F22B020CA005C1D16 /* CareKitUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1409474D22B020CA005C1D16 /* CareKitUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
1412
1409475122B02153005C1D16 /* CareKitStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1409475022B02153005C1D16 /* CareKitStore.framework */; };
1513
5101E6CB23733F3B0023B8A6 /* TestCustomCalendarViewSynchronizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5101E6CA23733F3B0023B8A6 /* TestCustomCalendarViewSynchronizer.swift */; };
1614
51094D94234F8E3E00B4BFFB /* OCKTaskController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51094D93234F8E3E00B4BFFB /* OCKTaskController.swift */; };
@@ -84,6 +82,7 @@
8482
51B714862367849100590A5A /* OCKButtonLogTaskView+Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B714852367849100590A5A /* OCKButtonLogTaskView+Updatable.swift */; };
8583
51BEAD5A237E00C600B32D55 /* TestDailyTasksPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BEAD59237E00C600B32D55 /* TestDailyTasksPageViewController.swift */; };
8684
51CF0A00235528EC00A343F9 /* OCKTaskControllerProtocol+Methods.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51CF09FF235528EC00A343F9 /* OCKTaskControllerProtocol+Methods.swift */; };
85+
51D8E27F24115D7D0026C716 /* TestListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51D8E27E24115D7D0026C716 /* TestListView.swift */; };
8786
51E88828234CE61300763B97 /* OCKContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E88827234CE61300763B97 /* OCKContactViewController.swift */; };
8887
51EF7E46234FAAB700B28C0A /* OCKSimpleTaskViewSynchronizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF7E45234FAAB700B28C0A /* OCKSimpleTaskViewSynchronizer.swift */; };
8988
51EF7E48234FAB7A00B28C0A /* OCKInstructionsTaskViewSynchronizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF7E47234FAB7A00B28C0A /* OCKInstructionsTaskViewSynchronizer.swift */; };
@@ -141,21 +140,6 @@
141140
};
142141
/* End PBXContainerItemProxy section */
143142

144-
/* Begin PBXCopyFilesBuildPhase section */
145-
1409474722B020A2005C1D16 /* Embed Frameworks */ = {
146-
isa = PBXCopyFilesBuildPhase;
147-
buildActionMask = 2147483647;
148-
dstPath = "";
149-
dstSubfolderSpec = 10;
150-
files = (
151-
1409474F22B020CA005C1D16 /* CareKitUI.framework in Embed Frameworks */,
152-
1409474C22B020C4005C1D16 /* CareKitStore.framework in Embed Frameworks */,
153-
);
154-
name = "Embed Frameworks";
155-
runOnlyForDeploymentPostprocessing = 0;
156-
};
157-
/* End PBXCopyFilesBuildPhase section */
158-
159143
/* Begin PBXFileReference section */
160144
032C86EF2326B68D00D0A0EA /* Calendar+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Calendar+Extensions.swift"; sourceTree = "<group>"; };
161145
03A2F774237F51C200A13638 /* CareKitStore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CareKitStore.xcodeproj; path = ../CareKitStore/CareKitStore.xcodeproj; sourceTree = "<group>"; };
@@ -232,6 +216,7 @@
232216
51B714852367849100590A5A /* OCKButtonLogTaskView+Updatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OCKButtonLogTaskView+Updatable.swift"; sourceTree = "<group>"; };
233217
51BEAD59237E00C600B32D55 /* TestDailyTasksPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestDailyTasksPageViewController.swift; sourceTree = "<group>"; };
234218
51CF09FF235528EC00A343F9 /* OCKTaskControllerProtocol+Methods.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OCKTaskControllerProtocol+Methods.swift"; sourceTree = "<group>"; };
219+
51D8E27E24115D7D0026C716 /* TestListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestListView.swift; sourceTree = "<group>"; };
235220
51E88827234CE61300763B97 /* OCKContactViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OCKContactViewController.swift; sourceTree = "<group>"; };
236221
51EF7E45234FAAB700B28C0A /* OCKSimpleTaskViewSynchronizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OCKSimpleTaskViewSynchronizer.swift; sourceTree = "<group>"; };
237222
51EF7E47234FAB7A00B28C0A /* OCKInstructionsTaskViewSynchronizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OCKInstructionsTaskViewSynchronizer.swift; sourceTree = "<group>"; };
@@ -484,6 +469,7 @@
484469
51FF9B8C2373374200BAEDB2 /* Calendar */,
485470
511372452374DFBD00831191 /* TestSynchronizedContext.swift */,
486471
51BEAD59237E00C600B32D55 /* TestDailyTasksPageViewController.swift */,
472+
51D8E27E24115D7D0026C716 /* TestListView.swift */,
487473
5196C7FD226F8F8F00F1C2A2 /* Info.plist */,
488474
);
489475
path = CareKitTests;
@@ -747,7 +733,6 @@
747733
8605A5B71C4F04EC00DD65FF /* Headers */,
748734
8605A5B61C4F04EC00DD65FF /* Frameworks */,
749735
8605A5B81C4F04EC00DD65FF /* Resources */,
750-
1409474722B020A2005C1D16 /* Embed Frameworks */,
751736
);
752737
buildRules = (
753738
);
@@ -871,6 +856,7 @@
871856
511372442374CA2B00831191 /* TestCustomChartViewController.swift in Sources */,
872857
511372422374CA1900831191 /* TestCartesianChartViewSynchronizer.swift in Sources */,
873858
51FF9B8E2373377500BAEDB2 /* TestWeekCalendarViewSynchronizer.swift in Sources */,
859+
51D8E27F24115D7D0026C716 /* TestListView.swift in Sources */,
874860
511372462374DFBD00831191 /* TestSynchronizedContext.swift in Sources */,
875861
51BEAD5A237E00C600B32D55 /* TestDailyTasksPageViewController.swift in Sources */,
876862
);

CareKit/CareKit/Lists/Controller/OCKDailyPageViewController.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ UIPageViewControllerDataSource, UIPageViewControllerDelegate {
110110

111111
// MARK: - Properties
112112

113+
open func selectDate(_ date: Date, animated: Bool) {
114+
let previousDate = selectedDate
115+
guard !Calendar.current.isDate(previousDate, inSameDayAs: date) else { return }
116+
calendarWeekPageViewController.selectDate(date, animated: animated)
117+
weekCalendarPageViewController(calendarWeekPageViewController, didSelectDate: date, previousDate: previousDate)
118+
}
119+
113120
override open func viewSafeAreaInsetsDidChange() {
114121
updateScrollViewInsets()
115122
}
@@ -145,11 +152,7 @@ UIPageViewControllerDataSource, UIPageViewControllerDelegate {
145152

146153
@objc
147154
private func pressedToday(sender: UIBarButtonItem) {
148-
let previousDate = selectedDate
149-
let currentDate = Date()
150-
guard !Calendar.current.isDate(previousDate, inSameDayAs: currentDate) else { return }
151-
calendarWeekPageViewController.selectDate(currentDate, animated: true)
152-
weekCalendarPageViewController(calendarWeekPageViewController, didSelectDate: currentDate, previousDate: previousDate)
155+
selectDate(Date(), animated: true)
153156
}
154157

155158
private func updateScrollViewInsets() {

CareKit/CareKit/Lists/View/OCKListView.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ import UIKit
3333
/// A view enclosing a scrollable stack view.
3434
internal class OCKListView: OCKView {
3535

36+
override var backgroundColor: UIColor? {
37+
didSet {
38+
contentView.backgroundColor = backgroundColor
39+
scrollView.backgroundColor = backgroundColor
40+
}
41+
}
42+
3643
// MARK: Properties
3744

3845
/// The stack view embedded inside the scroll view.
@@ -45,7 +52,7 @@ internal class OCKListView: OCKView {
4552
/// The scroll view that contains the stack view.
4653
let scrollView = UIScrollView()
4754

48-
private let contentView = UIView()
55+
let contentView = UIView()
4956

5057
// MARK: - Life Cycle
5158

@@ -68,7 +75,6 @@ internal class OCKListView: OCKView {
6875
}
6976

7077
private func styleSubviews() {
71-
scrollView.backgroundColor = contentView.backgroundColor
7278
scrollView.alwaysBounceVertical = true
7379
}
7480

@@ -97,7 +103,6 @@ internal class OCKListView: OCKView {
97103
let cachedStyle = style()
98104
contentView.directionalLayoutMargins = cachedStyle.dimension.directionalInsets1
99105
backgroundColor = cachedStyle.color.customGroupedBackground
100-
contentView.backgroundColor = cachedStyle.color.customGroupedBackground
101106
stackView.spacing = cachedStyle.dimension.directionalInsets1.top
102107
}
103108
}

CareKit/CareKit/Synchronized View Controllers/Calendar/View Controllers/OCKCalendarViewController.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ UIViewController, OCKCalendarViewDelegate {
105105
viewModelSubscription?.cancel()
106106
viewModelSubscription = controller.objectWillChange
107107
.context()
108-
.sink { [view] context in
109-
guard let typedView = view as? ViewSynchronizer.View else { fatalError("View should be of type \(ViewSynchronizer.View.self)") }
110-
self.viewSynchronizer.updateView(typedView, context: context)
108+
.sink { [weak self] context in
109+
guard let typedView = self?.view as? ViewSynchronizer.View else { fatalError("View should be of type \(ViewSynchronizer.View.self)") }
110+
self?.viewSynchronizer.updateView(typedView, context: context)
111111
}
112112
}
113113

CareKit/CareKit/Synchronized View Controllers/Chart/Controller/OCKChartController.swift

Lines changed: 22 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ open class OCKChartController: OCKChartControllerProtocol, ObservableObject {
4646

4747
// MARK: Properties
4848

49-
private let weekOfDate: Date
50-
private var subscription: AnyCancellable?
49+
private let eventQuery: OCKEventQuery
50+
private var cancellables: Set<AnyCancellable> = Set()
5151

5252
// MARK: - Life Cycle
5353

5454
/// Initialize the controller.
5555
/// - Parameter weekOfDate: A date in the week of the insights range.
5656
/// - Parameter storeManager: Wraps the store that contains the insight data.
5757
public required init(weekOfDate: Date, storeManager: OCKSynchronizedStoreManager) {
58-
self.weekOfDate = weekOfDate
58+
self.eventQuery = OCKEventQuery(dateInterval: Calendar.current.dateIntervalOfWeek(for: weekOfDate))
5959
self.storeManager = storeManager
6060
self.objectWillChange = .init([])
6161
}
@@ -67,44 +67,31 @@ open class OCKChartController: OCKChartControllerProtocol, ObservableObject {
6767
/// - configurations: An array of configurations to be plotted.
6868
open func fetchAndObserveInsights(forConfigurations configurations: [OCKDataSeriesConfiguration],
6969
errorHandler: ((Error) -> Void)? = nil) {
70-
71-
// Fetch tasks, then fetch events for the tasks and set the view model
72-
let eventQuery = OCKEventQuery(dateInterval: Calendar.current.dateIntervalOfWeek(for: weekOfDate))
73-
fetchTasks(eventQuery: eventQuery, configurations: configurations, errorHandler: errorHandler)
74-
}
75-
76-
private func fetchTasks(eventQuery: OCKEventQuery, configurations: [OCKDataSeriesConfiguration],
77-
errorHandler: ((Error) -> Void)? = nil) {
78-
79-
// Build up the task query
80-
var taskQuery = OCKTaskQuery(for: Date())
81-
taskQuery.ids = configurations.map { $0.taskID }
82-
83-
storeManager.store.fetchAnyTasks(query: taskQuery, callbackQueue: .main) { [weak self] result in
84-
guard let self = self else { return }
85-
switch result {
86-
case .success(let tasks):
87-
88-
// Fetch events and set the view model. Also set the view model when the events change
89-
self.refetchEvents(eventQuery: eventQuery, configurations: configurations) { result in
90-
if case let .failure(error) = result {
91-
errorHandler?(error)
92-
}
93-
}
94-
95-
self.subscribeTo(tasks: tasks, eventQuery: eventQuery, configurations: configurations) { result in
96-
if case let .failure(error) = result {
97-
errorHandler?(error)
70+
cancellables = Set()
71+
configurations.forEach { config in
72+
store.fetchAnyEvents(taskID: config.taskID, query: eventQuery, callbackQueue: .main) { result in
73+
switch result {
74+
case let .failure(error): errorHandler?(error)
75+
case let .success(events):
76+
self.refetchEvents(configurations: configurations, completion: nil)
77+
events.forEach { event in
78+
self.storeManager
79+
.publisher(forEvent: event, categories: [.add, .update, .delete])
80+
.sink(receiveValue: { _ in
81+
self.refetchEvents(configurations: configurations) { result in
82+
if case let .failure(error) = result {
83+
errorHandler?(error)
84+
}
85+
}
86+
})
87+
.store(in: &self.cancellables)
9888
}
9989
}
100-
101-
case .failure(let error):
102-
errorHandler?(error)
10390
}
10491
}
10592
}
10693

107-
private func refetchEvents(eventQuery: OCKEventQuery, configurations: [OCKDataSeriesConfiguration],
94+
private func refetchEvents(configurations: [OCKDataSeriesConfiguration],
10895
completion: OCKResultClosure<[OCKDataSeries]>?) {
10996
var allDataSeries = [OCKDataSeries]()
11097
let group = DispatchGroup()
@@ -138,25 +125,4 @@ open class OCKChartController: OCKChartControllerProtocol, ObservableObject {
138125
completion?(.success(allDataSeries))
139126
}
140127
}
141-
142-
private func subscribeTo(tasks: [OCKAnyTask],
143-
eventQuery: OCKEventQuery, configurations: [OCKDataSeriesConfiguration],
144-
completion: OCKResultClosure<[OCKDataSeries]>?) {
145-
// Set the view model when the tasks change
146-
let taskSubscriptions = tasks.map { task in
147-
return storeManager.publisher(forTask: task, categories: [.update, .delete], fetchImmediately: false)
148-
.sink { _ in self.refetchEvents(eventQuery: eventQuery, configurations: configurations, completion: completion) }
149-
}
150-
151-
// Set the view model when the events for the tasks change
152-
let eventSubscriptions = tasks.map { task in
153-
return self.storeManager.publisher(forEventsBelongingToTask: task, categories: [.update, .add, .delete])
154-
.sink { _ in self.refetchEvents(eventQuery: eventQuery, configurations: configurations, completion: completion) }
155-
}
156-
157-
subscription = AnyCancellable {
158-
taskSubscriptions.forEach { $0.cancel() }
159-
eventSubscriptions.forEach { $0.cancel() }
160-
}
161-
}
162128
}

CareKit/CareKit/Synchronized View Controllers/Chart/Synchronizers/OCKCartesianChartViewSynchronizer.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@ open class OCKCartesianChartViewSynchronizer: OCKChartViewSynchronizerProtocol {
5353

5454
open func makeView() -> OCKCartesianChartView {
5555
let chartView = OCKCartesianChartView(type: plotType)
56-
chartView.graphView.selectedIndex = Calendar.current.component(.weekday, from: selectedDate) - Calendar.current.firstWeekday
56+
let currentWeekday = Calendar.current.component(.weekday, from: selectedDate)
57+
let firstWeekday = Calendar.current.firstWeekday
58+
var offset = (currentWeekday - 1) - (firstWeekday - 1)
59+
if offset < 0 {
60+
offset += 7
61+
}
62+
chartView.graphView.selectedIndex = offset
5763
chartView.graphView.horizontalAxisMarkers = Calendar.current.orderedWeekdaySymbolsVeryShort()
5864
return chartView
5965
}

0 commit comments

Comments
 (0)