Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Build CareKit for macOS and visionOS #716

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

cbaker6
Copy link
Contributor

@cbaker6 cbaker6 commented Jul 5, 2024

CareKitUI currently can't be built for macOS due to its use of UIKit. In addition, the whole framework currently be built for visionOS.

The following items are completed:

  • Enable CareKitUI to build for macOS similar to watchOS by allowing SwiftUI based CareKit views
  • Enable CareStore and CareKit to build for macOS
  • Enable all CareKit frameworks to build for visionOS
  • All tests pass on all OS's locally

Note

@cbaker6 cbaker6 changed the title feat: Build CareKitUI for macOS feat: Build CareKit for macOS and visionOS Jul 5, 2024
#endif
}

private func rowValueOfIndexPath(_ indexPath: IndexPath) -> Int {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this method because iOS and macOS use row/item respectively

@@ -86,7 +86,10 @@ public struct OCKTaskEvents: Collection, Identifiable {

// First make sure there is no matching event already stored in the data structure.
let indexPath = self.indexPath(of: event)
guard indexPath == nil else { return (self[indexPath!.section][indexPath!.row], false) }
guard indexPath == nil else {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment below about row/item is handled for how iOS/macOS

@@ -77,4 +77,46 @@ class TestStore: XCTestCase {
XCTAssertEqual(store.context.clockTime, 2)
}
}

#if os(macOS)
func checkStoreProtection(_ protection: FileProtectionType) throws {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is currently needed for macOS because macOS is the only one that reports these attributes directly on the file.

@@ -84,12 +84,20 @@ private struct CardModifier: ViewModifier {
RoundedRectangle(cornerRadius: style.appearance.cornerRadius2, style: .continuous)
}

private var foregroundColor: Color {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A helper computed property to help handle SwiftUI and UIKit types.

#if !os(macOS)
return isComplete ? Color.accentColor : Color(style.color.clear)
#else
return isComplete ? Color.accentColor : style.color.clear
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to modify this helper computed property to help handle SwiftUI and UIKit types.

#if !os(macOS)
return isComplete ? .init(style.color.tertiaryCustomFill) : .accentColor
#else
return isComplete ? style.color.tertiaryCustomFill : .accentColor
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to modify this helper computed property to help handle SwiftUI and UIKit types.


#else

return 1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This scale value may not be correct, made this change because I could only find UIFontMetrics in UIKit, let me know if you have an improvement on this.


#elseif os(macOS)

var secondaryCustomGroupedBackground: Color { get }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using SwiftUI Color directly for macOS

@@ -113,11 +126,23 @@ public extension OCKColorStyler {
var tertiaryCustomFill: UIColor { #colorLiteral(red: 0.462745098, green: 0.462745098, blue: 0.5019607843, alpha: 0.24) }
var quaternaryCustomFill: UIColor { #colorLiteral(red: 0.462745098, green: 0.462745098, blue: 0.5019607843, alpha: 0.18) }

#elseif os(macOS)

var secondaryCustomGroupedBackground: Color { .white }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose .white for this and tertiaryCustomFill, let me know if you think a better color should be used for macOS

#endif

#if os(iOS) || os(visionOS) || os(watchOS)

var white: UIColor { .white }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every supported OS except for macOS will use UIKit for these colors

@@ -32,7 +32,7 @@ import SwiftUI

#if os(iOS)
private let completionButtonTextPadding: CGFloat = 14
#elseif os(watchOS)
#else
private let completionButtonTextPadding: CGFloat = 8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made every OS other than iOS use this padding value, let me know if we should update it to be more specific.

.edgesIgnoringSafeArea(.bottom)
default:
fatalError("Link type does not support in-app content")
}
}
}

func webView(withURL url: URL, link: LinkItem) -> some View {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created this method because some of the OS's don't support UIKit for SafariView or it didn't work properly (visionOS using Canvas). Let me know if you have an improvement here.

@@ -43,7 +43,9 @@ struct SafariView: UIViewControllerRepresentable {

func makeUIViewController(context: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
let config = SFSafariViewController.Configuration()
#if !os(visionOS)
config.barCollapsingEnabled = true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not available on visionOS

@@ -292,6 +295,18 @@ open class OCKStore: OCKStoreProtocol, Equatable {
return true
}

private func updateFileProtectionPathAtURL(_ url: URL) throws {

#if os(macOS)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently only needed for macOS, but this method calls through just incase it's needed for other OS's later

@@ -256,7 +256,9 @@ open class OCKStore: OCKStoreProtocol, Equatable {
descriptor.url = storeURL
descriptor.type = NSSQLiteStoreType
descriptor.shouldAddStoreAsynchronously = false
#if !os(macOS)
descriptor.setOption(storeType.securityClass as NSObject, forKey: NSPersistentStoreFileProtectionKey)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handling macOS and a later call below

@@ -129,7 +129,11 @@ class TestHealthKitPassthroughStoreEvents: XCTestCase {
case heartRateTask.id:
XCTAssertEqual(outcomeValues.count, 2)
XCTAssertEqual(outcomeValues.first?.doubleValue, 70)
#if !os(macOS) && !os(visionOS)
XCTAssertEqual(outcomeValues[safe: 1]?.doubleValue, 80)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

macOS and visionOS doesn't like safe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant