From 5431a53587312393ef7cf58922b2c4cdd7f27b8c Mon Sep 17 00:00:00 2001 From: Miroslav Kutak Date: Fri, 27 Mar 2020 21:01:53 +0100 Subject: [PATCH 1/3] SwiftUI sample --- .../contents.xcworkspacedata | 3 + .../project.pbxproj | 412 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../OCKSampleSwiftUI/AppDelegate.swift | 130 ++++++ .../OCKSampleSwiftUI/CareDailyPageView.swift | 51 +++ .../OCKSampleSwiftUI/CareViewController.swift | 149 +++++++ .../OCKSampleSwiftUI/ContactListView.swift | 51 +++ .../OCKSampleSwiftUI/ContentView.swift | 73 ++++ .../OCKSampleSwiftUI/SceneDelegate.swift | 57 +++ .../AppIcon.appiconset/Contents.json | 196 +++++++++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 35097 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 1144 bytes .../Icon-App-20x20@2x-1.png | Bin 0 -> 1018 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1018 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1428 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 730 bytes .../Icon-App-29x29@2x-1.png | Bin 0 -> 1176 bytes .../Icon-App-29x29@2x-2.png | Bin 0 -> 1176 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 942 bytes .../Icon-App-40x40@2x-1.png | Bin 0 -> 1457 bytes .../Icon-App-40x40@2x-2.png | Bin 0 -> 1457 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2011 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2011 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 4352 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1387 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3680 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 4033 bytes .../Icon-Homescreen-24x24@2x.png | Bin 0 -> 947 bytes .../Icon-Homescreen-27.5x27.5@2x.png | Bin 0 -> 1036 bytes .../Icon-Homescreen-29x29@2x.png | Bin 0 -> 1058 bytes .../Icon-Homescreen-29x29@3x-1.png | Bin 0 -> 1423 bytes .../Icon-Homescreen-29x29@3x.png | Bin 0 -> 1423 bytes .../Icon-Homescreen-40x40@2x.png | Bin 0 -> 1393 bytes .../Icon-Homescreen-86x86@2x.png | Bin 0 -> 3836 bytes .../Icon-Homescreen-98x98@2x.png | Bin 0 -> 4305 bytes .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 26 ++ .../Supporting Files/Info.plist | 60 +++ .../Supporting Files/Localizable.strings | 63 +++ .../Supporting Files/Localizable.stringsdict | 30 ++ .../OCKSampleSwiftUI/TipView.swift | 115 +++++ 42 files changed, 1437 insertions(+) create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.pbxproj create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/AppDelegate.swift create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/CareDailyPageView.swift create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/CareViewController.swift create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/ContactListView.swift create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/SceneDelegate.swift create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-2.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-2.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-24x24@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-27.5x27.5@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-29x29@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-29x29@3x-1.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-29x29@3x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-40x40@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-86x86@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-98x98@2x.png create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/Contents.json create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Base.lproj/LaunchScreen.storyboard create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Info.plist create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.strings create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.stringsdict create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI/TipView.swift diff --git a/CKWorkspace.xcworkspace/contents.xcworkspacedata b/CKWorkspace.xcworkspace/contents.xcworkspacedata index cf91e949f..c2938a89b 100644 --- a/CKWorkspace.xcworkspace/contents.xcworkspacedata +++ b/CKWorkspace.xcworkspace/contents.xcworkspacedata @@ -13,6 +13,9 @@ + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.pbxproj b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.pbxproj new file mode 100644 index 000000000..4cd0bd6ee --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.pbxproj @@ -0,0 +1,412 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 03A2F787237F51D800A13638 /* CareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F768237F51B400A13638 /* CareKit.framework */; }; + 03A2F788237F51D800A13638 /* CareKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F768237F51B400A13638 /* CareKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 03A2F789237F51D800A13638 /* CareKitStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C8B1F4228A1B41000B68FB /* CareKitStore.framework */; }; + 03A2F78A237F51D800A13638 /* CareKitStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E7C8B1F4228A1B41000B68FB /* CareKitStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 03A2F78B237F51D800A13638 /* CareKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F786237F51D800A13638 /* CareKitUI.framework */; }; + 03A2F78C237F51D800A13638 /* CareKitUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F786237F51D800A13638 /* CareKitUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 03F0600A2331946600CCE09B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03F060092331946600CCE09B /* SceneDelegate.swift */; }; + 03FEBEC6237A0D6100ACB35E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 03FEBEC4237A0D6100ACB35E /* Localizable.strings */; }; + 03FEBEC7237A0D6100ACB35E /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 03FEBEC5237A0D6100ACB35E /* Localizable.stringsdict */; }; + CED3B49C242E578400BC811C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED3B499242E578400BC811C /* ContentView.swift */; }; + CED3B49F242E591700BC811C /* ContactListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED3B49D242E591700BC811C /* ContactListView.swift */; }; + CED3B4A0242E591700BC811C /* CareDailyPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CED3B49E242E591700BC811C /* CareDailyPageView.swift */; }; + E72B2C0A226939E3009A9438 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E72B2C09226939E3009A9438 /* AppDelegate.swift */; }; + E72B2C14226939E4009A9438 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E72B2C12226939E4009A9438 /* LaunchScreen.storyboard */; }; + E7440E4F229477F7007AD30A /* CareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7440E4E229477F7007AD30A /* CareViewController.swift */; }; + E7C37849228F887800E982D8 /* TipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7C37848228F887800E982D8 /* TipView.swift */; }; + E7C4CA0B22809AD500ECC3D7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E7C4CA0A22809AD500ECC3D7 /* Assets.xcassets */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 03A2F767237F51B400A13638 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 03A2F762237F51B400A13638 /* CareKit.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8605A5BA1C4F04EC00DD65FF; + remoteInfo = CareKit; + }; + 03A2F769237F51B400A13638 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 03A2F762237F51B400A13638 /* CareKit.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 5196C7F9226F8F8F00F1C2A2; + remoteInfo = CareKitTests; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 51F1E2592360F46C003D83FA /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 03A2F78A237F51D800A13638 /* CareKitStore.framework in Embed Frameworks */, + 03A2F788237F51D800A13638 /* CareKit.framework in Embed Frameworks */, + 03A2F78C237F51D800A13638 /* CareKitUI.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 03A2F762237F51B400A13638 /* CareKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CareKit.xcodeproj; path = ../CareKit/CareKit.xcodeproj; sourceTree = ""; }; + 03A2F786237F51D800A13638 /* CareKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 03F060092331946600CCE09B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 03FEBEC4237A0D6100ACB35E /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; + 03FEBEC5237A0D6100ACB35E /* Localizable.stringsdict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.stringsdict; path = Localizable.stringsdict; sourceTree = ""; }; + 1409475222B025AD005C1D16 /* CareKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CED3B499242E578400BC811C /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + CED3B49D242E591700BC811C /* ContactListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactListView.swift; sourceTree = ""; }; + CED3B49E242E591700BC811C /* CareDailyPageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CareDailyPageView.swift; sourceTree = ""; }; + E72B2C06226939E3009A9438 /* OCKSampleSwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OCKSampleSwiftUI.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E72B2C09226939E3009A9438 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + E72B2C13226939E4009A9438 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + E72B2C15226939E4009A9438 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E737105922862B7B005D3B03 /* CareKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E7440E4E229477F7007AD30A /* CareViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CareViewController.swift; sourceTree = ""; }; + E7C37848228F887800E982D8 /* TipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipView.swift; sourceTree = ""; }; + E7C4CA0A22809AD500ECC3D7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + E7C8B1F4228A1B41000B68FB /* CareKitStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKitStore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E72B2C03226939E3009A9438 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 03A2F789237F51D800A13638 /* CareKitStore.framework in Frameworks */, + 03A2F787237F51D800A13638 /* CareKit.framework in Frameworks */, + 03A2F78B237F51D800A13638 /* CareKitUI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 03A2F763237F51B400A13638 /* Products */ = { + isa = PBXGroup; + children = ( + 03A2F768237F51B400A13638 /* CareKit.framework */, + 03A2F76A237F51B400A13638 /* CareKitTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 71A79C8A2294FBA1002B96D3 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 03FEBEC4237A0D6100ACB35E /* Localizable.strings */, + 03FEBEC5237A0D6100ACB35E /* Localizable.stringsdict */, + E7C4CA0A22809AD500ECC3D7 /* Assets.xcassets */, + E72B2C12226939E4009A9438 /* LaunchScreen.storyboard */, + E72B2C15226939E4009A9438 /* Info.plist */, + ); + path = "Supporting Files"; + sourceTree = ""; + }; + E72B2BFD226939E3009A9438 = { + isa = PBXGroup; + children = ( + 03A2F762237F51B400A13638 /* CareKit.xcodeproj */, + E72B2C08226939E3009A9438 /* OCKSampleSwiftUI */, + E72B2C07226939E3009A9438 /* Products */, + E72B2C2F22693C51009A9438 /* Frameworks */, + ); + sourceTree = ""; + }; + E72B2C07226939E3009A9438 /* Products */ = { + isa = PBXGroup; + children = ( + E72B2C06226939E3009A9438 /* OCKSampleSwiftUI.app */, + ); + name = Products; + sourceTree = ""; + }; + E72B2C08226939E3009A9438 /* OCKSampleSwiftUI */ = { + isa = PBXGroup; + children = ( + E72B2C09226939E3009A9438 /* AppDelegate.swift */, + 03F060092331946600CCE09B /* SceneDelegate.swift */, + CED3B499242E578400BC811C /* ContentView.swift */, + CED3B49E242E591700BC811C /* CareDailyPageView.swift */, + CED3B49D242E591700BC811C /* ContactListView.swift */, + E7440E4E229477F7007AD30A /* CareViewController.swift */, + E7C37848228F887800E982D8 /* TipView.swift */, + 71A79C8A2294FBA1002B96D3 /* Supporting Files */, + ); + path = OCKSampleSwiftUI; + sourceTree = ""; + }; + E72B2C2F22693C51009A9438 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 03A2F786237F51D800A13638 /* CareKitUI.framework */, + 1409475222B025AD005C1D16 /* CareKit.framework */, + E7C8B1F4228A1B41000B68FB /* CareKitStore.framework */, + E737105922862B7B005D3B03 /* CareKitUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E72B2C05226939E3009A9438 /* OCKSampleSwiftUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = E72B2C18226939E4009A9438 /* Build configuration list for PBXNativeTarget "OCKSampleSwiftUI" */; + buildPhases = ( + 05D4F0402357E0AA004F42DC /* Fix SPM */, + E72B2C02226939E3009A9438 /* Sources */, + E72B2C03226939E3009A9438 /* Frameworks */, + E72B2C04226939E3009A9438 /* Resources */, + 51F1E2592360F46C003D83FA /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OCKSampleSwiftUI; + packageProductDependencies = ( + ); + productName = CareKitDemoApp; + productReference = E72B2C06226939E3009A9438 /* OCKSampleSwiftUI.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E72B2BFE226939E3009A9438 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1020; + LastUpgradeCheck = 1100; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + E72B2C05226939E3009A9438 = { + CreatedOnToolsVersion = 10.2; + }; + }; + }; + buildConfigurationList = E72B2C01226939E3009A9438 /* Build configuration list for PBXProject "OCKSampleSwiftUI" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = E72B2BFD226939E3009A9438; + productRefGroup = E72B2C07226939E3009A9438 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 03A2F763237F51B400A13638 /* Products */; + ProjectRef = 03A2F762237F51B400A13638 /* CareKit.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + E72B2C05226939E3009A9438 /* OCKSampleSwiftUI */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 03A2F768237F51B400A13638 /* CareKit.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = CareKit.framework; + remoteRef = 03A2F767237F51B400A13638 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 03A2F76A237F51B400A13638 /* CareKitTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CareKitTests.xctest; + remoteRef = 03A2F769237F51B400A13638 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + E72B2C04226939E3009A9438 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E7C4CA0B22809AD500ECC3D7 /* Assets.xcassets in Resources */, + 03FEBEC7237A0D6100ACB35E /* Localizable.stringsdict in Resources */, + 03FEBEC6237A0D6100ACB35E /* Localizable.strings in Resources */, + E72B2C14226939E4009A9438 /* LaunchScreen.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 05D4F0402357E0AA004F42DC /* Fix SPM */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Fix SPM"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ -d \"${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/\" ] && [ \"${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/\" != \"${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/\" ] \nthen\n cp -f -R \"${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/\" \"${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/\"\nfi\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E72B2C02226939E3009A9438 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CED3B4A0242E591700BC811C /* CareDailyPageView.swift in Sources */, + E7440E4F229477F7007AD30A /* CareViewController.swift in Sources */, + CED3B49C242E578400BC811C /* ContentView.swift in Sources */, + E72B2C0A226939E3009A9438 /* AppDelegate.swift in Sources */, + CED3B49F242E591700BC811C /* ContactListView.swift in Sources */, + E7C37849228F887800E982D8 /* TipView.swift in Sources */, + 03F0600A2331946600CCE09B /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + E72B2C12226939E4009A9438 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E72B2C13226939E4009A9438 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + E72B2C16226939E4009A9438 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + E72B2C19226939E4009A9438 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 17; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/OCKSampleSwiftUI/Supporting Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.carekit-samplecode.OCKSample"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E72B2C01226939E3009A9438 /* Build configuration list for PBXProject "OCKSampleSwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E72B2C16226939E4009A9438 /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + E72B2C18226939E4009A9438 /* Build configuration list for PBXNativeTarget "OCKSampleSwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E72B2C19226939E4009A9438 /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = E72B2BFE226939E3009A9438 /* Project object */; +} diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..f0866e643 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/AppDelegate.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/AppDelegate.swift new file mode 100644 index 000000000..f15f572c0 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/AppDelegate.swift @@ -0,0 +1,130 @@ +/* +Copyright (c) 2019, Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder(s) nor the names of any contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. No license is granted to the trademarks of +the copyright holders even if such marks are included in this software. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import CareKit +import Contacts +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + // Manages synchronization of a CoreData store + lazy var synchronizedStoreManager: OCKSynchronizedStoreManager = { + let store = OCKStore(name: "SampleAppStore") + store.populateSampleData() + let manager = OCKSynchronizedStoreManager(wrapping: store) + return manager + }() + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + return true + } + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } +} + +private extension OCKStore { + + // Adds tasks and contacts into the store + func populateSampleData() { + + let thisMorning = Calendar.current.startOfDay(for: Date()) + let aFewDaysAgo = Calendar.current.date(byAdding: .day, value: -4, to: thisMorning)! + let beforeBreakfast = Calendar.current.date(byAdding: .hour, value: 8, to: aFewDaysAgo)! + let afterLunch = Calendar.current.date(byAdding: .hour, value: 14, to: aFewDaysAgo)! + + let schedule = OCKSchedule(composing: [ + OCKScheduleElement(start: beforeBreakfast, end: nil, + interval: DateComponents(day: 1)), + + OCKScheduleElement(start: afterLunch, end: nil, + interval: DateComponents(day: 2)) + ]) + + var doxylamine = OCKTask(id: "doxylamine", title: "Take Doxylamine", + carePlanID: nil, schedule: schedule) + doxylamine.instructions = "Take 25mg of doxylamine when you experience nausea." + + let nauseaSchedule = OCKSchedule(composing: [ + OCKScheduleElement(start: beforeBreakfast, end: nil, interval: DateComponents(day: 1), + text: "Anytime throughout the day", targetValues: [], duration: .allDay) + ]) + + var nausea = OCKTask(id: "nausea", title: "Track your nausea", + carePlanID: nil, schedule: nauseaSchedule) + nausea.impactsAdherence = false + nausea.instructions = "Tap the button below anytime you experience nausea." + + let kegelSchedule = OCKSchedule(composing: [OCKScheduleElement(start: beforeBreakfast, end: nil, interval: DateComponents(day: 2))]) + var kegels = OCKTask(id: "kegels", title: "Kegel Exercises", carePlanID: nil, schedule: kegelSchedule) + kegels.impactsAdherence = true + kegels.instructions = "Perform kegel exercies" + + addTasks([nausea, doxylamine, kegels], callbackQueue: .main, completion: nil) + + var contact1 = OCKContact(id: "jane", givenName: "Jane", + familyName: "Daniels", carePlanID: nil) + contact1.asset = "JaneDaniels" + contact1.title = "Family Practice Doctor" + contact1.role = "Dr. Daniels is a family practice doctor with 8 years of experience." + contact1.emailAddresses = [OCKLabeledValue(label: CNLabelEmailiCloud, value: "janedaniels@icloud.com")] + contact1.phoneNumbers = [OCKLabeledValue(label: CNLabelWork, value: "(324) 555-7415")] + contact1.messagingNumbers = [OCKLabeledValue(label: CNLabelWork, value: "(324) 555-7415")] + + contact1.address = { + let address = OCKPostalAddress() + address.street = "2598 Reposa Way" + address.city = "San Francisco" + address.state = "CA" + address.postalCode = "94127" + return address + }() + + var contact2 = OCKContact(id: "matthew", givenName: "Matthew", + familyName: "Reiff", carePlanID: nil) + contact2.asset = "MatthewReiff" + contact2.title = "OBGYN" + contact2.role = "Dr. Reiff is an OBGYN with 13 years of experience." + contact2.phoneNumbers = [OCKLabeledValue(label: CNLabelWork, value: "(324) 555-7415")] + contact2.messagingNumbers = [OCKLabeledValue(label: CNLabelWork, value: "(324) 555-7415")] + contact2.address = { + let address = OCKPostalAddress() + address.street = "396 El Verano Way" + address.city = "San Francisco" + address.state = "CA" + address.postalCode = "94127" + return address + }() + + addContacts([contact1, contact2]) + } +} diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/CareDailyPageView.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/CareDailyPageView.swift new file mode 100644 index 000000000..de6c9ced5 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/CareDailyPageView.swift @@ -0,0 +1,51 @@ +/* +Copyright (c) 2019, Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder(s) nor the names of any contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. No license is granted to the trademarks of +the copyright holders even if such marks are included in this software. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import SwiftUI +import CareKit + +struct CareDailyPageView: UIViewControllerRepresentable { + let storeManager: OCKSynchronizedStoreManager + + func makeUIViewController(context: Context) -> CareViewController { + CareViewController(storeManager: storeManager) + } + + func updateUIViewController(_ viewController: CareViewController, context: Context) { + } +} + +struct CareDailyPageView_Previews: PreviewProvider { + static var previews: some View { + let appDelegate = UIApplication.shared.delegate as! AppDelegate + let manager = appDelegate.synchronizedStoreManager + return CareDailyPageView(storeManager: manager) + } +} diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/CareViewController.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/CareViewController.swift new file mode 100644 index 000000000..10672b026 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/CareViewController.swift @@ -0,0 +1,149 @@ +/* + Copyright (c) 2019, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import Foundation +import UIKit +import CareKit + +extension NSNotification.Name { + struct CareViewController { + static let pressedToday = NSNotification.Name(rawValue: "CareViewControllerPressedToday") + } +} + +class CareViewController: OCKDailyPageViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + NotificationCenter.default.addObserver(self, selector: #selector(pressedToday), name: NSNotification.Name.CareViewController.pressedToday, object: nil) + } + + override open func viewSafeAreaInsetsDidChange() { + } + + @objc + private func pressedToday() { + selectDate(Date(), animated: true) + } + + // This will be called each time the selected date changes. + // Use this as an opportunity to rebuild the content shown to the user. + + override func dailyPageViewController(_ dailyPageViewController: OCKDailyPageViewController, + prepare listViewController: OCKListViewController, for date: Date) { + + let identifiers = ["doxylamine", "nausea", "kegels"] + var query = OCKTaskQuery(for: date) + query.ids = identifiers + query.excludesTasksWithNoEvents = true + + storeManager.store.fetchAnyTasks(query: query, callbackQueue: .main) { result in + switch result { + case .failure(let error): print("Error: \(error)") + case .success(let tasks): + + // Add a non-CareKit view into the list + let tipTitle = "Benefits of exercising" + let tipText = "Learn how activity can promote a healthy pregnancy." + + // Only show the tip view on the current date + if Calendar.current.isDate(date, inSameDayAs: Date()) { + let tipView = TipView() + tipView.headerView.titleLabel.text = tipTitle + tipView.headerView.detailLabel.text = tipText + tipView.imageView.image = UIImage(named: "exercise.jpg") + listViewController.appendView(tipView, animated: false) + } + + // Since the kegel task is only sheduled every other day, there will be cases + // where it is not contained in the tasks array returned from the query. + if let kegelsTask = tasks.first(where: { $0.id == "kegels" }) { + let kegelsCard = OCKSimpleTaskViewController(task: kegelsTask, eventQuery: .init(for: date), + storeManager: self.storeManager) + listViewController.appendViewController(kegelsCard, animated: false) + } + + // Create a card for the doxylamine task if there are events for it on this day. + if let doxylamineTask = tasks.first(where: { $0.id == "doxylamine" }) { + let doxylamineCard = OCKChecklistTaskViewController(task: doxylamineTask, eventQuery: .init(for: date), + storeManager: self.storeManager) + listViewController.appendViewController(doxylamineCard, animated: false) + } + + // Create a card for the nausea task if there are events for it on this day. + // Its OCKSchedule was defined to have daily events, so this task should be + // found in `tasks` every day after the task start date. + if let nauseaTask = tasks.first(where: { $0.id == "nausea" }) { + + // dynamic gradient colors + let nauseaGradientStart = UIColor { traitCollection -> UIColor in + return traitCollection.userInterfaceStyle == .light ? #colorLiteral(red: 0.9960784314, green: 0.3725490196, blue: 0.368627451, alpha: 1) : #colorLiteral(red: 0.8627432641, green: 0.2630574384, blue: 0.2592858295, alpha: 1) + } + let nauseaGradientEnd = UIColor { traitCollection -> UIColor in + return traitCollection.userInterfaceStyle == .light ? #colorLiteral(red: 0.9960784314, green: 0.4732026144, blue: 0.368627451, alpha: 1) : #colorLiteral(red: 0.8627432641, green: 0.3598620686, blue: 0.2592858295, alpha: 1) + } + + // Create a plot comparing nausea to medication adherence. + let nauseaDataSeries = OCKDataSeriesConfiguration( + taskID: "nausea", + legendTitle: "Nausea", + gradientStartColor: nauseaGradientStart, + gradientEndColor: nauseaGradientEnd, + markerSize: 10, + eventAggregator: OCKEventAggregator.countOutcomeValues) + + let doxylamineDataSeries = OCKDataSeriesConfiguration( + taskID: "doxylamine", + legendTitle: "Doxylamine", + gradientStartColor: .systemGray2, + gradientEndColor: .systemGray, + markerSize: 10, + eventAggregator: OCKEventAggregator.countOutcomeValues) + + let insightsCard = OCKCartesianChartViewController(plotType: .bar, selectedDate: date, + configurations: [nauseaDataSeries, doxylamineDataSeries], + storeManager: self.storeManager) + insightsCard.chartView.headerView.titleLabel.text = "Nausea & Doxylamine Intake" + insightsCard.chartView.headerView.detailLabel.text = "This Week" + insightsCard.chartView.headerView.accessibilityLabel = "Nausea & Doxylamine Intake, This Week" + listViewController.appendViewController(insightsCard, animated: false) + + // Also create a card that displays a single event. + // The event query passed into the initializer specifies that only + // today's log entries should be displayed by this log task view controller. + let nauseaCard = OCKButtonLogTaskViewController(task: nauseaTask, eventQuery: .init(for: date), + storeManager: self.storeManager) + listViewController.appendViewController(nauseaCard, animated: false) + } + } + } + } +} diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/ContactListView.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/ContactListView.swift new file mode 100644 index 000000000..4435383ed --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/ContactListView.swift @@ -0,0 +1,51 @@ +/* +Copyright (c) 2019, Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder(s) nor the names of any contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. No license is granted to the trademarks of +the copyright holders even if such marks are included in this software. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import SwiftUI +import CareKit + +struct ContactListView: UIViewControllerRepresentable { + let storeManager: OCKSynchronizedStoreManager + + func makeUIViewController(context: Context) -> OCKContactsListViewController { + OCKContactsListViewController(storeManager: storeManager) + } + + func updateUIViewController(_ viewController: OCKContactsListViewController, context: Context) { + } +} + +struct ContactListView_Previews: PreviewProvider { + static var previews: some View { + let appDelegate = UIApplication.shared.delegate as! AppDelegate + let manager = appDelegate.synchronizedStoreManager + return ContactListView(storeManager: manager) + } +} diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift new file mode 100644 index 000000000..a13c7375f --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift @@ -0,0 +1,73 @@ +/* + Copyright (c) 2019, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import SwiftUI +import CareKit + +struct ContentView: View { + let storeManager: OCKSynchronizedStoreManager + + @State var isContactListViewPresented: Bool = false + + var body: some View { + NavigationView { + VStack { + CareDailyPageView(storeManager: storeManager) + .edgesIgnoringSafeArea(Edge.Set.all) + .navigationBarItems( + leading: Button("Today", action: { + NotificationCenter.default.post(name: NSNotification.Name.CareViewController.pressedToday, object: nil) + }), trailing: Button("Care Teams", action: { + self.isContactListViewPresented = true + })) + .navigationBarTitle("", displayMode: .inline) + } + } + .sheet(isPresented: $isContactListViewPresented) { + NavigationView { + ContactListView(storeManager: self.storeManager) + .edgesIgnoringSafeArea(Edge.Set.all) + .navigationBarTitle("Care Teams") + .navigationBarItems(trailing: + Button("Done", action: { + self.isContactListViewPresented = false + })) + } + } + } +} + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + let appDelegate = UIApplication.shared.delegate as! AppDelegate + let manager = appDelegate.synchronizedStoreManager + return ContentView(storeManager: manager) + } +} diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/SceneDelegate.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/SceneDelegate.swift new file mode 100644 index 000000000..ad05a11a8 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/SceneDelegate.swift @@ -0,0 +1,57 @@ +/* + Copyright (c) 2019, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import CareKit +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + + // Create the SwiftUI view that provides the window contents. + let appDelegate = UIApplication.shared.delegate as! AppDelegate + let manager = appDelegate.synchronizedStoreManager + + let contentView = ContentView(storeManager: manager) + + // Use a UIHostingController as window root view controller. + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: contentView) + self.window = window + window.tintColor = UIColor { $0.userInterfaceStyle == .light ? #colorLiteral(red: 0.9960784314, green: 0.3725490196, blue: 0.368627451, alpha: 1) : #colorLiteral(red: 0.8627432641, green: 0.2630574384, blue: 0.2592858295, alpha: 1) } + window.makeKeyAndVisible() + } + } + +} diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..e04566584 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,196 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x-1.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x-2.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-Homescreen-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x-2.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + }, + { + "size" : "24x24", + "idiom" : "watch", + "filename" : "Icon-Homescreen-24x24@2x.png", + "scale" : "2x", + "role" : "notificationCenter", + "subtype" : "38mm" + }, + { + "size" : "27.5x27.5", + "idiom" : "watch", + "filename" : "Icon-Homescreen-27.5x27.5@2x.png", + "scale" : "2x", + "role" : "notificationCenter", + "subtype" : "42mm" + }, + { + "size" : "29x29", + "idiom" : "watch", + "filename" : "Icon-Homescreen-29x29@2x.png", + "role" : "companionSettings", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "watch", + "filename" : "Icon-Homescreen-29x29@3x-1.png", + "role" : "companionSettings", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "watch", + "filename" : "Icon-Homescreen-40x40@2x.png", + "scale" : "2x", + "role" : "appLauncher", + "subtype" : "38mm" + }, + { + "size" : "44x44", + "idiom" : "watch", + "scale" : "2x", + "role" : "appLauncher", + "subtype" : "40mm" + }, + { + "size" : "50x50", + "idiom" : "watch", + "scale" : "2x", + "role" : "appLauncher", + "subtype" : "44mm" + }, + { + "size" : "86x86", + "idiom" : "watch", + "filename" : "Icon-Homescreen-86x86@2x.png", + "scale" : "2x", + "role" : "quickLook", + "subtype" : "38mm" + }, + { + "size" : "98x98", + "idiom" : "watch", + "filename" : "Icon-Homescreen-98x98@2x.png", + "scale" : "2x", + "role" : "quickLook", + "subtype" : "42mm" + }, + { + "size" : "108x108", + "idiom" : "watch", + "scale" : "2x", + "role" : "quickLook", + "subtype" : "44mm" + }, + { + "idiom" : "watch-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..14728df6d45c6935b675674daef8fa86c06349c6 GIT binary patch literal 35097 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 QW&i*H07*qoM6N<$f>;2wcK`qY literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..2c7e444383ceca012839f1808cee57bb056829a6 GIT binary patch literal 1457 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 LNkvXXu0mjfr@h3{quXhp3n1sKA-BR9 z?H;@%0Bqs;c?Wu+Si=9tB^b32fK3iVdd`rJJ+#Xf+GPW2*}{9V2<8at7>GIrAr{`S zfh(lz0BPAl+IG+$N7&c{vBjgVA*gc@y#FAiX+!ag-AKt}7FV-wHL`0Tv2NaD6jp8| zoTqr6f(_juO>5Z59r@W4(s!msWil?7u`23Wcbb@Gcj#GHse~lN(g)IWLJx+ZuEDTA zmKu`8s=Uj8Hz(rrH#av$3?^@El37|q4N8ReI5G0dxi5x=Fe+GDW#4V3#bu*T$56N9 zh=mWRX-y3{&FSo?hMt9g@&GlgDY$TUU5kjp;*GyY-9jnuq0Gv=oYpSH4$mzAb5kJT zbo9aI-n>`ugb0-uodv3yp$-Ay4ok}6ll6us94UZvhd(P7ryn$Ejx@O+sIIH>rw{L{g{(_!f z$gXdJjoqn)GmQLl#M)0l{*GArqAmpH_1m15=a7aC$iIQu`cb?hg)jwF!JrO-{P*)h3XOU! z0o-oEY3}4rOd}3~jDj1`J}jhxh{bjKT3HXF*LHdRig#_gYxbiQ7HE zpIM}5UKK(J^S4@dV>@?n96oS}8j{R=GbQ-+b>o*jNXKDQBoZvIF-xi`_&91{0%CGl z+>0#F$K7IVN%Qv&Aa6(;h17|iM5NbYccGVD`FF9ABYK9U0)V{Azmk|*CJDr$Od8I| zLuOT0TggUGdCEpY+(B)eyKCU-kH}IYF~CC&SWSEGQ$90g;A$;b8Kil{W4J7rVXP-B zr&wIN`<`KgM7-I_naBaX1i!`?2NaV`oc#i4)IF4?B;D&8$3pSvu*zy4c-l5zp79$@ z!IzKAsrKa>ag!?+b}Rq%<-}!9`YIGQOv>W&bj1{_q&Z{JF0OMjJ##FzE!G%0 zJrNg|Ztu`bw+owK-s~~R36*5MPo6{9nTCGXN4Pr}FW!BCBz>xuDsu1?=aLPW4b>wbTP!TDM#tBNK*x^qdC&2vKPs3rwI%%6NSjNJ-(kS#vht>j4@Vv6}~!L z-dAl{}?3zBikmFOieM5ZgM=G^^}yy>{Y3;b@rd{+yv} zWLMiaqw6aT!`GUNisWeRs%O#rmm)5Zi5~g}%k>r7OS5hl+raAPV$eOfLRaa! zZ@1gPaHE5fZ0y=YLqb)MRNnM7Iyf*g{W5QLO2d|bkDaJj%9=ZK;N0_BiQGr)Z$<{` zjWR&a*Ok12ikw8Ctydi}W>*2kiqu#%+R@`~7no(kJDuLg$t);S{)sn$9q!*)%; zba+V7E&R29RuDMNRlKc3nYd6p)cyKSX|Gn|;LI~EnSQF?4+DFvpKg(Q zd_rLu#U7xqg|o6nyFQ`!)AXNm4|=}aS+ifE zKcw~ZhUJ3wt%4oJCZUTej@~m(xX9$mB+@d;K+!w?bB40b{*Ivsp*J2~J@RU|?JJo@b(zTS?|I%z?3#P6q zW}cr7%jlB6tb&vB%eXVv_Sm@$EO%zaHmvS-S@;oh+;NmQ*)N;2L$#-XM(WO)B+wQv zk?Z;dt*cDMn9B2yqIypqecbr_jx@3-5Sd z=p)O@t7?vQ2#9S}{HQwxluCIi8>cj!$E{l5Hf*U}jI8s|O35FtYBveU^HK2G{>|S; zg|zyJ!7Em&uBDf-oA$TyC-uy$o)D+eKgT}O##Zp5Ra^N^pET#6f39`Iui<95V1C~F oe-+%^etYL1N^bQc=Pb3ET{ll}6ugoV{|*4>;p^UdF#OVg06PXI^8f$< literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f76308bbfd82105bdffeeb85286cfa3803866674 GIT binary patch literal 2011 zcmY+Ec{r2{8^&LbH9FQ5S&9-)GWOjN%4EqPLsE7jnqxoIq%0MRbHs^~Ln;X=k|oEn zCKY9uglbarE;D2H{hM=r-#_1VJ@@l_?)(4yx$5tCcfr z^JK46kdZs6Wdj*|zz4iQ0~cy^7X4y5v$BDCrCs=K^*^Fkg^BoYbf4DR?8qpX$^oCNN6rsr31UW^DJgulGTy4yyL&q17zA@0Xv zOJ9z!YjsHc8zaaSSAFw;~@t$(vacY>>!)G07LR!JI`)Tj(0n}eW3NIR^lQJJun-)7=D5sNK=$;{gi zVOxLbmqP;LcgWbCcA<>b{EVbw#hd$p915pKrqeH1ftuFLx@OMbV~Eo+Xpbv*d{Vec zM_h0MghGwW0r$94!hfX~SA)BpXjxZSjgLVc2lmq!+`(6@`WEic1heJ=r+<{)@q(67 z#A;}TOgt#KGxUNA*v6kv`~h40A+9*a_1o;$=b)x7`DiR>ctS|sgzW=pnOB@nvp zeByWVkw{R(ibg17Kj{N^Si?3)xx=po-$_Cin;MhFy4OxpH6y8+vmf{H7FS>thQGKX z;&7;pFO7n#-f=mj@mJAblwlmH@=R8fdy5bynhfJ~(v zOC)WxWVdv2Cud;CAbQ~qa4#A(KqC$Tl#pcp*A3X*8$w~YQ*$IOTUvS%-Boy*j))}QWWNbVoC=oV2 zEbc|N*W(^BB+~=@0*RY4#-a6MClTd+*hAngU-3h1^e1>Z2_NXG4y>g=_pO+nHgvO*uL{;W;yF^DM>o-z zlUFJ!+jY;VQ6j?kbHk*V?^EWH4Th2b^-<1t`iplTKq=qq<;q+v+2!TT#OQfm zPcq>??wH=sbUhTleA-DSJjzT_`)IDrshlO^+Zi0)+f*@XeYfA2%87^Oo#XV?KE-d2 zm$%i`=ps*K@RahCxbW7IVig1Ty`@hnP4CTT7E0x1QTX=GGcBt7+OC~=P&5{{-wwZM7*bg;YvfL&hni5#dcCn%dyZNhRs_#9I2;# z-LJ=eaHPr6ST1h;p%Jb+SUP`Z1{oS0oq3tRHmzxg!^TZEC}+=~*?;c&oJ8KEjW?r1 zv?f^~_uFcIVP$R-(B7v3o3N?@{EDR0IkXgEmx2;{vA5Fh%&WoS{tfnMWSWgG!KgzE zFdG?Ga*udzke!V+j%b2SQ9Zh?X;+3b%GTFkzV*;P$(Pb4Ov~ie6@TuM5FKh&0~}jQ z+EdQEs{>{~C{`MTIAe)_VkSC5x=Xfps^AyvhI?M$DeKct8k&8kEjvKb|7mbf%~MI~ z$0rn*V^zt`f1(hQHPsu`j-2lWRoZK0orjd?KI$Tw*H1r_PQU(8NO|p_RohWI6j_C% zZ&4=9-TTdA0hE){|L16;Kn8BBNKqPD?N<5xciev3dIU2^xbrh|Ki%Ld=b+cS9ku%u z2SVGvY+5ba+$!8&Vj8xj>f|%qjEPE_N+zrj43&HmzGSM{?&}l$fFVFh!>#sNK_iRR3X+J)D@E{`}uj6aTWrv~Iwx2yFQQVBh|Q#k74 zC1QO)zio}76kB!vQFPy_qmP@u-3nIjPUuz`Skg;Mq9nh~G9iP~gCn<25S{TBJi#5W z3;jen1vRblPCmZ9niqYikX)r8ZR?zl@w`>%*N!fekCk&dpq%pIs!lVXxDXAU9T5FK zCZIM%4qdTMb1S=q7CGF;p47LfeuAGt{u=*89bd(URd3-rf7V)f{-w?xyN;QYL><`k ne-#vMyS?L2W%mZ5OSby#&YPz<3t!2Ke+Pi^^z&#t7;))8h5RTq literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9be3e3b35b814d8405edf35d09f68e1e2daeb0f9 GIT binary patch literal 4352 zcmd5=i9ZzD7auRX7(z0P$-ae0wqi_U35m%TEwa6`gdrx&F!qEPTS|y3pY^tKumu33lmLLZBmiKaJr%bK0HFQ`0MH<06^H@+8pi_F}X2~&O5yn)3HV08E9c`9&-0<5;`=`@s?ZuIHRRpx9Vq` z@Zp7MiLdvmmsWPT$(!9OB*!{XU}V|dZ^HG$7VnMocnTN_;P_HNe{KJgyWZ;*SdRR&=Vosb@tup zB{iCA(isI+Fq6~tq!QoFGZqP_FK6SD?G=1I#s2?TS~U-E^1}SegS`pk#htxOfi@t2 zUZ9y=yqX4FF*oZm8QY863XMFtE%P8Ux`$(k=hDP!1)9g^sDhejqJt;G_^lkX3MHn( z)rKuz>sepp?tweIypek3Syzu+^S}0V38xoff{EpBFOxu8O3W}d4~oS0aQ^Ry>qs6q z;0IG@h>U;ZFg{qX3+e-whLX|g{Wquhup~Rcp z?)mxvQ=8zoK<%)^h9=Qy$o+#eIgSX$kkKty(H_sb3{zm0fawem(#K%ti$>%7@wsz{ zXI2uI3?WsWbVSLTe&jf&{;&ECfY=z>USY_vper@EMybxbF5@z`JjL9r zSZi*VITtvY_Av_lEk!-Sz5n{$?rzDW@sjoXJZ-}*jn3mgsI8Zr$%!XHHVb7RBfu|5 z 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 literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..bd3131bbb1f07def5c717aae13b36022078c2c3e GIT binary patch literal 1387 zcmV-x1(f=UP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw0006j zP)t-s?mt)VKUeNQSMESq?Kx8HD@E%eJ?kDi>mWSrCqnHuPwhBS>?uU-C`0WxQ0_un z?K4d48#nDQN$^%{^LL2#ikbC{n)7^(@n3W9Ia2E#IqW7u?m<}YL0Rl7MeQ_A@LF#3 zd5QIlne%&#@mz52HBRj=Nb4Lp^@^DL)YqUsqo?mSfPI#cQvGx275{Nd#HrLgZrT6f`TG6u@$-6$ z>liia88!5WmhVz$>mNJoB0cUtR{PJ@_MxrrLRs^FkL)Eu{qFJho~r5>H10oG??zqx z-SA#=>lroqy2Je0-s>Yi?mJWOP-gLKe(pe5^_Zmiw7%>nLi)|q{psuNI8g03 zPw-f6@KEtj z{pafSl%e>ry6YM?@@;?XAUpZQ%lzWz@nw1RfROGyRr<`*>n1_(M_%z{ck3KE>J%~f zt+(nFGVVB0`NPWm-s0^rO8)ow?mboOB0lXpQ~mDn|NZ^&Q)uo)Tkb|({`dLn6*BKj zV*c~>@nm@Y=IQ?U`S4k8{Nd&Iq_6q8!R#$a?J-L8c!~9mobEeR?@3_%;NM7T}ACiVaT010qNS#tmY3labT3lag+-G2N4000McNliru;0PTM zHy=s5dk_Es0(?nCK~z}7?bzp26G0RJ@XK3Mh)FJIK?zx+C`1oUF4hpNh>{=?MI-j! zv48~&DmE-wQAA_!9eerrj4)#+?cNJ!#?iU=@y+gU-tFDqy*)wD%|wK0|rCfcPzgNF>wA2z(eQOKOV6fcroBSseI zj~ZPfm5PjtG3IuS87ucj*|_nZQZInw@=cgHsV_Hq3QYBL8pg{571QK+Om{hy88fZ3 zX2(;NbE;e-1!MlX^W=mms}6>0<|pQA9cCv13;Pzx$>FS9n4DTvzZl0@-jWncjx0^h zH3T_c*|Oy_DORjpgsv>~)=OAr{tX+c*rv@}5X{aishGUA2*LE* z$dUOKi9TQfV~PsR>lchlc;kZK(=+t3|w zn2H@~#dZKRS5vX0$FRK#HSXgytIbk?R^|+zpkXJg2=B8~j?)w?a>fQY##`Dc*x7So z0tVvwV%)mWkuonW#xD9UVbcPWkb}iMfbu*TveRvR_~WXFO#166|0002ovPDHLkV1n)6wUGb- literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b813b5efcb456b91bf5f6a7a96ef4ab048b39278 GIT binary patch literal 3680 zcmd57>w25%+3q|z+*rs-ay7$($~tt4giRe2LO^%0DvQgC}{-%K&b-&YhC~VgrPtr zw4eoH$k<@>v4KGuoG}hBwI(vysZcAoZ~y>w`X4ck%q5&KgzOP;I}7#&j=z$v$DFn>FKhp%qbP5K;OSufEZ0Hm@^gc5{+?V7p;S&BHoV(=QtO3 zg5BI~P|T$bd1x_*|1YFp&0@u$!pD=q#9^8i)!_s}6XGQDhLk>%4=5tG9HB<&c@=L@ zlMm-)1=66*K?X;*5NR(eE@;lL5|FLET&X4)n6#w+Di z=@sDHZ*AjfKOW z1Lh`Rsx%{PhUKSJs%_uRL{9&J^_(B!o@7(nAAhiMt6<6}@rjcyh<%6~6{PclvfsSb z4XJuChH}X{S_@JP5&8xCA#4IqAf853+3^Y(jPL^C_(T%uWxyI7%K@_JGckEGW)deB z+v%!!IP2n3N+%~|98W_EdY7ag564fBwRt6jLbnI%Wa&q0RY%`dCzoE8chq$R>Qc!a zn9gt;JQB(GOlYCQU+YW(mO3zluV`?H?l;UWrmW!NkVn7Bc6a_fnN%G}TdOXuUzG_Y z8zy{-du@x#E#+WJNNNrP{jB$QpspCXYLmKl#;@9G`xR4VJDU{SKNw~_!Nx>2;8a50 z+p>`0<8KOI4UaAr+`goF_8jI1aM_zgx^gl^mX=UH0&+AIT*!UvNxa@)5hJM5)L3r^l0pKkchh} z=_C1bVyv2AMoa-TftSkpYmzcEV^yGExJM;B7P2LE>-%4!el=oL#4KsO>f~>u)3?^^ zC>21T|4`XZi}G)s?cp8kB#%IKsgn9XsnU6Jyj(M{*6&TKmX_84{NN)8b8jJo{HGIR zbv~1^l9P>R5XidGRnWk=*Yi(gqGiC=&&j2pO8fAq8E3HayXy~~di37z73vE7+9f(w z@yBz@vl3{@dZQINM_>G^N4vAb$GQ4C_ViCSgRiMl_Td_?xQuu4{Euxb?FDRv!aLAk z%e*DuLHZ0D6kUf&$>D1^a$j7pgjff;`Mv@l@AZ_HTH9rV_rWjuSdV$G=sSh12upcIsLO5T;325xO(-p-T;nPke zgthr%>3OM@l`)@JPM+#a-Y#l`Zllf$iel;YmoYk;0qSEy& zOP)+-RH?n>%b5rixv9vp3pD3W2-60?v>2YKfLQcKFT*cogs>t!)DcCplToIqN4Wy$ zHXIUIPeBB0HB!kWOHp4JK@d;w|%fhJ)Pu)Kor{> zBm!+qg-2y>IjI8>&K9&6mus^5k%tOJpF?Iuj2s*Vjs#V>@ULLsv94Li*9b%#vCU|7)dWi>+1s4o;mZLV4-$CF(T(bupgrZ2Oon`)Ks?-tVF7Aug zVtf1j*8&q4I>>3Om{Oa2luVFG5M?1k$pxFuRWS} zr6MR4L9UYZpr3w|bxSMxiMpv3o(_dpki;3}-nTsV=br+^g)&hS-xrclyS&c zUk5)v>kRR@T4*&7n`kY{&)2jI*SyKzmSWs2RHQSoD(S~$ZfO!8`OwZV8B%6&n z`DPjGKL;K8DrTY0B1$i5+}DifJd_)PjefgtPpZncp$D6kY`-!lpF(K=xM%%V(w0?MApA?hyfaO@8hn$!mS1N&PT9M zok@5-F!qFg=(y(r!Qg5{j>me5LK!cwBMlMdNcA*(U#E(&w|26O3`PvKoDL~$S@qq;mK6gaouK>1$2GLf$)byeuvt?aZ`rz*J z9`kLI*@Hq~0f`ma*{Gx+79v+r>$>6H9br2e){Waqr(dZqpA zN6Ws2P9SZPpy$23Et8YSV{QHLc+_9|y5F43#BgGd`Kk8*?-4 z&hR}=Opq7S^*Br2TsQGuAoP4SX=6={G8jz3=O~>gmX3Sd60&`eIm!#0x4Q1!mPe69 zz#SXm#4O=$L|m9Y3$O8m<6{#qU0vz509$jH_jGobUHpT_d65VIK6`Krdnnf23;jR49_@1g literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..386f05564d2d95ab9a10676574be5fbe6d187c48 GIT binary patch literal 4033 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 literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-29x29@3x-1.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-29x29@3x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..043aace3dae9d5a14c09489b712a6e4d42f505b9 GIT binary patch literal 1423 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 G*#80bj#(Q3 literal 0 HcmV?d00001 diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-98x98@2x.png b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Assets.xcassets/AppIcon.appiconset/Icon-Homescreen-98x98@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e0d2b55ca305e1b4a2e3fc57706007a00715f0dc GIT binary patch literal 4305 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 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Info.plist b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Info.plist new file mode 100644 index 000000000..da6219c25 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Info.plist @@ -0,0 +1,60 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + OCKSample + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.strings b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.strings new file mode 100644 index 000000000..189f9c9f9 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.strings @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019, Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder(s) nor the names of any contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. No license is granted to the trademarks of +the copyright holders even if such marks are included in this software. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +"ADDRESS" = "Address"; +"ANNOUNCE_EVENT_DELETED" = "Logged event was deleted"; +"CANCEL" = "Cancel"; +"CALL" = "Call"; +"COMPLETED" = "Completed"; +"CONTACTS" = "Contacts"; +"DELETE" = "Delete"; +"DONE" = "Done"; +"DOUBLE_TAP_MAP" = "Double-tap to open directions in Maps"; +"DOUBLE_TAP_TO_COMPLETE" = "Double-tap to mark as completed"; +"DOUBLE_TAP_TO_INCOMPLETE" = "Double-tap to mark as incomplete"; +"DOUBLE_TAP_TO_RECORD_EVENT" = "Double-tap to record an event"; +"DOUBLE_TAP_TO_REMOVE_EVENT" = "Double-tap to removed logged event"; +"EMAIL" = "E-mail"; +"EVENT" = "Event"; +"GOAL" = "Goal"; +"HIGH" = "High"; +"INCOMPLETE" = "Incomplete"; +"LOG" = "Log"; +"LOG_ENTRY" = "Log Entry"; +"LOGGING" = "Logging"; +"LOW" = "Low"; +"MARK_COMPLETE" = "Mark as Completed"; +"MESSAGE" = "Message"; +"NO_TASKS" = "No Tasks"; +"NO_EVENTS" = "No Events"; +"PROGRESS" = "Progress"; +"SEARCH" = "Search"; +"SELECTED" = "Selected"; +"TASKS" = "Tasks"; +"THREE_FINGER_SWIPE_DAY" = "Three-finger swipe to go to next or previous day"; +"THREE_FINGER_SWIPE_WEEK" = "Three-finger swipe to go to next or previous week"; +"TODAY" = "Today"; diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.stringsdict b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.stringsdict new file mode 100644 index 000000000..d823f17ed --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/Supporting Files/Localizable.stringsdict @@ -0,0 +1,30 @@ + + + + + EVENTS_REMAINING + + NSStringLocalizedFormatKey + %#@events_remaining@ + events_remaining + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + i + zero + 0 remaining + one + 1 remaining + two + + few + + many + + other + %i remaining + + + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/TipView.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/TipView.swift new file mode 100644 index 000000000..b88b37865 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/TipView.swift @@ -0,0 +1,115 @@ +/* + Copyright (c) 2019, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import UIKit +import CareKit + +class TipView: OCKView, OCKCardable { + + var cardView: UIView { self } + let contentView: UIView = OCKView() + let headerView = OCKHeaderView() + let imageView = UIImageView() + var imageHeightConstraint: NSLayoutConstraint! + + private let blurView: UIVisualEffectView = { + let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.regular) + return UIVisualEffectView(effect: blurEffect) + }() + + override init() { + super.init() + setup() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setup() { + headerView.detailLabel.textColor = .secondaryLabel + + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + imageView.layer.cornerRadius = layer.cornerRadius + + blurView.clipsToBounds = true + blurView.layer.cornerRadius = layer.cornerRadius + blurView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + + contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + contentView.frame = bounds + + addSubview(contentView) + contentView.addSubview(imageView) + contentView.addSubview(blurView) + contentView.addSubview(headerView) + + imageView.translatesAutoresizingMaskIntoConstraints = false + blurView.translatesAutoresizingMaskIntoConstraints = false + headerView.translatesAutoresizingMaskIntoConstraints = false + imageHeightConstraint = imageView.heightAnchor.constraint(equalToConstant: scaledImageHeight(compatibleWith: traitCollection)) + + NSLayoutConstraint.activate([ + headerView.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor), + headerView.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor), + headerView.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor), + + blurView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + blurView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + blurView.topAnchor.constraint(equalTo: contentView.topAnchor), + blurView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor, constant: 16), + + imageView.topAnchor.constraint(equalTo: contentView.topAnchor), + imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), + imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), + imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), + imageHeightConstraint + ]) + } + + func scaledImageHeight(compatibleWith traitCollection: UITraitCollection) -> CGFloat { + return UIFontMetrics.default.scaledValue(for: 200, compatibleWith: traitCollection) + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + if previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory { + imageHeightConstraint.constant = scaledImageHeight(compatibleWith: traitCollection) + } + } + + override func styleDidChange() { + super.styleDidChange() + let cachedStyle = style() + enableCardStyling(true, style: cachedStyle) + directionalLayoutMargins = cachedStyle.dimension.directionalInsets1 + } +} From 453eb2036ae6defe225fd4316f1d001955b37160 Mon Sep 17 00:00:00 2001 From: Miroslav Kutak Date: Thu, 9 Apr 2020 12:42:14 +0200 Subject: [PATCH 2/3] Added OCKCatalogSwiftUI target [#355]. --- .../contents.xcworkspacedata | 3 + .../project.pbxproj | 515 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcschemes/OCKCatalogSwiftUI.xcscheme | 91 ++++ .../OCKCatalogSwiftUI/AppDelegate.swift | 51 ++ .../AppIcon.appiconset/Contents.json | 98 ++++ .../Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../OCKCatalogSwiftUI/ContentView.swift | 76 +++ .../OCKCatalogSwiftUI/Info.plist | 60 ++ .../OCKCatalogSwiftUI/Localizable.strings | 63 +++ .../OCKCatalogSwiftUI/Localizable.stringsdict | 30 + .../OCKStore+Extensions.swift | 109 ++++ .../OCKViewControllerRepresentable.swift | 268 +++++++++ .../OCKCatalogSwiftUI/SceneDelegate.swift | 49 ++ OCKCatalogSwiftUI/OCKCatalogTests/Info.plist | 22 + .../xcschemes/OCKSampleSwiftUI.xcscheme | 88 +++ .../OCKSampleSwiftUI/ContentView.swift | 2 +- 19 files changed, 1570 insertions(+), 1 deletion(-) create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.pbxproj create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKCatalogSwiftUI.xcscheme create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/AppDelegate.swift create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/Contents.json create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/Base.lproj/LaunchScreen.storyboard create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/Info.plist create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.strings create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.stringsdict create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKStore+Extensions.swift create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift create mode 100644 OCKCatalogSwiftUI/OCKCatalogSwiftUI/SceneDelegate.swift create mode 100644 OCKCatalogSwiftUI/OCKCatalogTests/Info.plist create mode 100644 OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKSampleSwiftUI.xcscheme diff --git a/CKWorkspace.xcworkspace/contents.xcworkspacedata b/CKWorkspace.xcworkspace/contents.xcworkspacedata index c2938a89b..2de15ff64 100644 --- a/CKWorkspace.xcworkspace/contents.xcworkspacedata +++ b/CKWorkspace.xcworkspace/contents.xcworkspacedata @@ -19,4 +19,7 @@ + + diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.pbxproj b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.pbxproj new file mode 100644 index 000000000..757896ec2 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.pbxproj @@ -0,0 +1,515 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 039A9EAA236B97B400158EDD /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 039A9EA9236B97B400158EDD /* SceneDelegate.swift */; }; + 03A2F78E237F51DF00A13638 /* CareKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F771237F51BA00A13638 /* CareKit.framework */; }; + 03A2F78F237F51DF00A13638 /* CareKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F771237F51BA00A13638 /* CareKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 03A2F790237F51DF00A13638 /* CareKitStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7C8B1F0228A1B34000B68FB /* CareKitStore.framework */; }; + 03A2F791237F51DF00A13638 /* CareKitStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E7C8B1F0228A1B34000B68FB /* CareKitStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 03A2F792237F51DF00A13638 /* CareKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F78D237F51DF00A13638 /* CareKitUI.framework */; }; + 03A2F793237F51DF00A13638 /* CareKitUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 03A2F78D237F51DF00A13638 /* CareKitUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 03FEBEA2237A0C7E00ACB35E /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 03FEBEA0237A0C7D00ACB35E /* Localizable.stringsdict */; }; + 03FEBEA3237A0C7E00ACB35E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 03FEBEA1237A0C7E00ACB35E /* Localizable.strings */; }; + 51EF57C9229B21AA0071E2F6 /* OCKStore+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF57C8229B21AA0071E2F6 /* OCKStore+Extensions.swift */; }; + CE432E1C243E311D0054E7A1 /* OCKViewControllerRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE432E1B243E311D0054E7A1 /* OCKViewControllerRepresentable.swift */; }; + CE432E1E243E380B0054E7A1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE432E1D243E380B0054E7A1 /* ContentView.swift */; }; + E7D010FC222498F400C008DE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7D010FB222498F400C008DE /* AppDelegate.swift */; }; + E7D01103222498F400C008DE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E7D01102222498F400C008DE /* Assets.xcassets */; }; + E7D01106222498F400C008DE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E7D01104222498F400C008DE /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 03A2F770237F51BA00A13638 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 03A2F76B237F51BA00A13638 /* CareKit.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8605A5BA1C4F04EC00DD65FF; + remoteInfo = CareKit; + }; + 03A2F772237F51BA00A13638 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 03A2F76B237F51BA00A13638 /* CareKit.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 5196C7F9226F8F8F00F1C2A2; + remoteInfo = CareKitTests; + }; + 5143E1FB22C2832600E32526 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E7D010F0222498F400C008DE /* Project object */; + proxyType = 1; + remoteGlobalIDString = E7D010F7222498F400C008DE; + remoteInfo = OCKCatalog; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 516CD56823543678005E2779 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 03A2F791237F51DF00A13638 /* CareKitStore.framework in Embed Frameworks */, + 03A2F78F237F51DF00A13638 /* CareKit.framework in Embed Frameworks */, + 03A2F793237F51DF00A13638 /* CareKitUI.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 039A9EA9236B97B400158EDD /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 03A2F76B237F51BA00A13638 /* CareKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CareKit.xcodeproj; path = ../CareKit/CareKit.xcodeproj; sourceTree = ""; }; + 03A2F78D237F51DF00A13638 /* CareKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 03FEBEA0237A0C7D00ACB35E /* Localizable.stringsdict */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.stringsdict; path = Localizable.stringsdict; sourceTree = ""; }; + 03FEBEA1237A0C7E00ACB35E /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; + 1409475522B0261A005C1D16 /* CareKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5143E1F622C2832600E32526 /* OCKCatalogSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OCKCatalogSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5143E1FA22C2832600E32526 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 51D0ECFD2284894E00D24A76 /* CareKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 51EF57C8229B21AA0071E2F6 /* OCKStore+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OCKStore+Extensions.swift"; sourceTree = ""; }; + CE432E1B243E311D0054E7A1 /* OCKViewControllerRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OCKViewControllerRepresentable.swift; sourceTree = ""; }; + CE432E1D243E380B0054E7A1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + E7C8B1F0228A1B34000B68FB /* CareKitStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CareKitStore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E7D010F8222498F400C008DE /* OCKCatalogSwiftUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OCKCatalogSwiftUI.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E7D010FB222498F400C008DE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + E7D01102222498F400C008DE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + E7D01105222498F400C008DE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + E7D01107222498F400C008DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5143E1F322C2832600E32526 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7D010F5222498F400C008DE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 03A2F790237F51DF00A13638 /* CareKitStore.framework in Frameworks */, + 03A2F78E237F51DF00A13638 /* CareKit.framework in Frameworks */, + 03A2F792237F51DF00A13638 /* CareKitUI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 03A2F76C237F51BA00A13638 /* Products */ = { + isa = PBXGroup; + children = ( + 03A2F771237F51BA00A13638 /* CareKit.framework */, + 03A2F773237F51BA00A13638 /* CareKitTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 5143E1F722C2832600E32526 /* OCKCatalogTests */ = { + isa = PBXGroup; + children = ( + 5143E1FA22C2832600E32526 /* Info.plist */, + ); + path = OCKCatalogTests; + sourceTree = ""; + }; + 51D0ECFC2284894E00D24A76 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 03A2F78D237F51DF00A13638 /* CareKitUI.framework */, + 1409475522B0261A005C1D16 /* CareKit.framework */, + E7C8B1F0228A1B34000B68FB /* CareKitStore.framework */, + 51D0ECFD2284894E00D24A76 /* CareKitUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + E7D010EF222498F400C008DE = { + isa = PBXGroup; + children = ( + 03A2F76B237F51BA00A13638 /* CareKit.xcodeproj */, + E7D010FA222498F400C008DE /* OCKCatalogSwiftUI */, + 5143E1F722C2832600E32526 /* OCKCatalogTests */, + E7D010F9222498F400C008DE /* Products */, + 51D0ECFC2284894E00D24A76 /* Frameworks */, + ); + sourceTree = ""; + }; + E7D010F9222498F400C008DE /* Products */ = { + isa = PBXGroup; + children = ( + E7D010F8222498F400C008DE /* OCKCatalogSwiftUI.app */, + 5143E1F622C2832600E32526 /* OCKCatalogSwiftUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + E7D010FA222498F400C008DE /* OCKCatalogSwiftUI */ = { + isa = PBXGroup; + children = ( + 51EF57C8229B21AA0071E2F6 /* OCKStore+Extensions.swift */, + CE432E1B243E311D0054E7A1 /* OCKViewControllerRepresentable.swift */, + E7D010FB222498F400C008DE /* AppDelegate.swift */, + 039A9EA9236B97B400158EDD /* SceneDelegate.swift */, + CE432E1D243E380B0054E7A1 /* ContentView.swift */, + E7D01107222498F400C008DE /* Info.plist */, + E7D01104222498F400C008DE /* LaunchScreen.storyboard */, + 03FEBEA1237A0C7E00ACB35E /* Localizable.strings */, + 03FEBEA0237A0C7D00ACB35E /* Localizable.stringsdict */, + E7D01102222498F400C008DE /* Assets.xcassets */, + ); + path = OCKCatalogSwiftUI; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5143E1F522C2832600E32526 /* OCKCatalogSwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5143E1FF22C2832600E32526 /* Build configuration list for PBXNativeTarget "OCKCatalogSwiftUITests" */; + buildPhases = ( + 5143E1F222C2832600E32526 /* Sources */, + 5143E1F322C2832600E32526 /* Frameworks */, + 5143E1F422C2832600E32526 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5143E1FC22C2832600E32526 /* PBXTargetDependency */, + ); + name = OCKCatalogSwiftUITests; + productName = OCKCatalogTests; + productReference = 5143E1F622C2832600E32526 /* OCKCatalogSwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E7D010F7222498F400C008DE /* OCKCatalogSwiftUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = E7D0110A222498F400C008DE /* Build configuration list for PBXNativeTarget "OCKCatalogSwiftUI" */; + buildPhases = ( + 0588EAC82357CC4F00F2646B /* Fix SPM */, + E7D010F4222498F400C008DE /* Sources */, + E7D010F5222498F400C008DE /* Frameworks */, + E7D010F6222498F400C008DE /* Resources */, + 51936B1B22418DAA00F7B1DD /* ShellScript */, + 516CD56823543678005E2779 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OCKCatalogSwiftUI; + packageProductDependencies = ( + ); + productName = OCK2SampleApp; + productReference = E7D010F8222498F400C008DE /* OCKCatalogSwiftUI.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E7D010F0222498F400C008DE /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = Apple; + TargetAttributes = { + 5143E1F522C2832600E32526 = { + CreatedOnToolsVersion = 11.0; + TestTargetID = E7D010F7222498F400C008DE; + }; + E7D010F7222498F400C008DE = { + CreatedOnToolsVersion = 10.1; + LastSwiftMigration = 1020; + }; + }; + }; + buildConfigurationList = E7D010F3222498F400C008DE /* Build configuration list for PBXProject "OCKCatalogSwiftUI" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = E7D010EF222498F400C008DE; + productRefGroup = E7D010F9222498F400C008DE /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 03A2F76C237F51BA00A13638 /* Products */; + ProjectRef = 03A2F76B237F51BA00A13638 /* CareKit.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + E7D010F7222498F400C008DE /* OCKCatalogSwiftUI */, + 5143E1F522C2832600E32526 /* OCKCatalogSwiftUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 03A2F771237F51BA00A13638 /* CareKit.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = CareKit.framework; + remoteRef = 03A2F770237F51BA00A13638 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 03A2F773237F51BA00A13638 /* CareKitTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = CareKitTests.xctest; + remoteRef = 03A2F772237F51BA00A13638 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 5143E1F422C2832600E32526 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7D010F6222498F400C008DE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E7D01106222498F400C008DE /* LaunchScreen.storyboard in Resources */, + 03FEBEA3237A0C7E00ACB35E /* Localizable.strings in Resources */, + E7D01103222498F400C008DE /* Assets.xcassets in Resources */, + 03FEBEA2237A0C7E00ACB35E /* Localizable.stringsdict in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0588EAC82357CC4F00F2646B /* Fix SPM */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Fix SPM"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ -d \"${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/\" ] && [ \"${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/\" != \"${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/\" ] \nthen\n cp -f -R \"${SYMROOT}/Release${EFFECTIVE_PLATFORM_NAME}/\" \"${SYMROOT}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/\"\nfi\n"; + }; + 51936B1B22418DAA00F7B1DD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5143E1F222C2832600E32526 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7D010F4222498F400C008DE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E7D010FC222498F400C008DE /* AppDelegate.swift in Sources */, + CE432E1E243E380B0054E7A1 /* ContentView.swift in Sources */, + 51EF57C9229B21AA0071E2F6 /* OCKStore+Extensions.swift in Sources */, + 039A9EAA236B97B400158EDD /* SceneDelegate.swift in Sources */, + CE432E1C243E311D0054E7A1 /* OCKViewControllerRepresentable.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 5143E1FC22C2832600E32526 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E7D010F7222498F400C008DE /* OCKCatalogSwiftUI */; + targetProxy = 5143E1FB22C2832600E32526 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + E7D01104222498F400C008DE /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E7D01105222498F400C008DE /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5143E1FD22C2832600E32526 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 7JYUG8QGJ3; + INFOPLIST_FILE = OCKCatalogTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = Apple.OCKCatalogTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OCKCatalogSwiftUI.app/OCKCatalogSwiftUI"; + }; + name = Debug; + }; + E7D01108222498F400C008DE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = "$(BUILD_DIR)/Debug-$(PLATFORM_NAME)"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + E7D0110B222498F400C008DE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 17; + DEVELOPMENT_TEAM = ""; + INFOPLIST_FILE = "$(SRCROOT)/OCKCatalogSwiftUI/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.example.carekit-samplecode.OCKCatalog"; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5143E1FF22C2832600E32526 /* Build configuration list for PBXNativeTarget "OCKCatalogSwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5143E1FD22C2832600E32526 /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + E7D010F3222498F400C008DE /* Build configuration list for PBXProject "OCKCatalogSwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E7D01108222498F400C008DE /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + E7D0110A222498F400C008DE /* Build configuration list for PBXNativeTarget "OCKCatalogSwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E7D0110B222498F400C008DE /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = E7D010F0222498F400C008DE /* Project object */; +} diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..514821cf1 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKCatalogSwiftUI.xcscheme b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKCatalogSwiftUI.xcscheme new file mode 100644 index 000000000..57ff7d8e3 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKCatalogSwiftUI.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/AppDelegate.swift b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/AppDelegate.swift new file mode 100644 index 000000000..f962b0b52 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/AppDelegate.swift @@ -0,0 +1,51 @@ +/* + Copyright (c) 2019, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import CareKit +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + let storeManager: OCKSynchronizedStoreManager = { + let store = OCKStore(name: "carekit-catalog") + store.fillWithDummyData() + return OCKSynchronizedStoreManager(wrapping: store) + }() + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + return true + } + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, + options: UIScene.ConnectionOptions) -> UISceneConfiguration { + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } +} diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..d8db8d65f --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/Contents.json b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Base.lproj/LaunchScreen.storyboard b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..bfa361294 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift new file mode 100644 index 000000000..d714ba955 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift @@ -0,0 +1,76 @@ +// +/* + Copyright (c) 2020, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import SwiftUI + +fileprivate struct ListItem: View { + + let destination: T + let title: String + + var body: some View { + NavigationLink(destination: destination + .edgesIgnoringSafeArea(Edge.Set.all), + label: { Text(title) }) + } + +} + +struct ContentView: View { + var body: some View { + NavigationView { + List { + Section(header: Text("TASK")) { + ListItem(destination: OCKGridTaskView(), title: "Grid") + ListItem(destination: OCKChecklistTaskView(), title: "Checklist") + ListItem(destination: OCKSimpleTaskView(), title: "Simple") + ListItem(destination: OCKInstructionsTaskView(), title: "Instructions") + ListItem(destination: OCKButtonLogTaskView(), title: "Button Log") + } + Section(header: Text("CONTACT")) { + ListItem(destination: OCKSimpleContactView(), title: "Simple") + ListItem(destination: OCKDetailedContactView(), title: "Detailed") + } + Section(header: Text("CHART")) { + ListItem(destination: OCKCartesianChartView(type: .line), title: "Line") + ListItem(destination: OCKCartesianChartView(type: .scatter), title: "Scatter") + ListItem(destination: OCKCartesianChartView(type: .bar), title: "Bar") + } + Section(header: Text("LIST")) { + ListItem(destination: OCKDailyTasksPageView(), title: "Task") + ListItem(destination: OCKContactsListView(), title: "Contacts") + } + } + .listStyle(GroupedListStyle()) + .navigationBarTitle(Text("CareKit Catalog"), displayMode: .large) + } + } +} diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Info.plist b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Info.plist new file mode 100644 index 000000000..349341158 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Info.plist @@ -0,0 +1,60 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + OCKCatalog + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.strings b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.strings new file mode 100644 index 000000000..189f9c9f9 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.strings @@ -0,0 +1,63 @@ +/* +Copyright (c) 2019, Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder(s) nor the names of any contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. No license is granted to the trademarks of +the copyright holders even if such marks are included in this software. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +"ADDRESS" = "Address"; +"ANNOUNCE_EVENT_DELETED" = "Logged event was deleted"; +"CANCEL" = "Cancel"; +"CALL" = "Call"; +"COMPLETED" = "Completed"; +"CONTACTS" = "Contacts"; +"DELETE" = "Delete"; +"DONE" = "Done"; +"DOUBLE_TAP_MAP" = "Double-tap to open directions in Maps"; +"DOUBLE_TAP_TO_COMPLETE" = "Double-tap to mark as completed"; +"DOUBLE_TAP_TO_INCOMPLETE" = "Double-tap to mark as incomplete"; +"DOUBLE_TAP_TO_RECORD_EVENT" = "Double-tap to record an event"; +"DOUBLE_TAP_TO_REMOVE_EVENT" = "Double-tap to removed logged event"; +"EMAIL" = "E-mail"; +"EVENT" = "Event"; +"GOAL" = "Goal"; +"HIGH" = "High"; +"INCOMPLETE" = "Incomplete"; +"LOG" = "Log"; +"LOG_ENTRY" = "Log Entry"; +"LOGGING" = "Logging"; +"LOW" = "Low"; +"MARK_COMPLETE" = "Mark as Completed"; +"MESSAGE" = "Message"; +"NO_TASKS" = "No Tasks"; +"NO_EVENTS" = "No Events"; +"PROGRESS" = "Progress"; +"SEARCH" = "Search"; +"SELECTED" = "Selected"; +"TASKS" = "Tasks"; +"THREE_FINGER_SWIPE_DAY" = "Three-finger swipe to go to next or previous day"; +"THREE_FINGER_SWIPE_WEEK" = "Three-finger swipe to go to next or previous week"; +"TODAY" = "Today"; diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.stringsdict b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.stringsdict new file mode 100644 index 000000000..d823f17ed --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/Localizable.stringsdict @@ -0,0 +1,30 @@ + + + + + EVENTS_REMAINING + + NSStringLocalizedFormatKey + %#@events_remaining@ + events_remaining + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + i + zero + 0 remaining + one + 1 remaining + two + + few + + many + + other + %i remaining + + + + diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKStore+Extensions.swift b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKStore+Extensions.swift new file mode 100644 index 000000000..3bb5c650c --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKStore+Extensions.swift @@ -0,0 +1,109 @@ +/* + Copyright (c) 2019, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import CareKit +import Foundation + +extension OCKSchedule { + /// Create a schedule that happens at meal times every day of the week. + static func mealTimesEachDay(start: Date, end: Date?) -> OCKSchedule { + let startDate = Calendar.current.startOfDay(for: start) + let breakfast = OCKSchedule.dailyAtTime(hour: 7, minutes: 30, start: startDate, end: end, text: "Breakfast") + let lunch = OCKSchedule.dailyAtTime(hour: 12, minutes: 0, start: startDate, end: end, text: "Lunch") + let dinner = OCKSchedule.dailyAtTime(hour: 17, minutes: 30, start: startDate, end: end, text: "Dinner") + return OCKSchedule(composing: [breakfast, lunch, dinner]) + } +} + +extension OCKStore { + func fillWithDummyData() { + // Note: If the tasks and contacts already exist in the store, these methods will fail. If you have modified the data and would like the + // changes to be reflected in the app, delete and reinstall the catalog app. + let aFewDaysAgo = Calendar.current.startOfDay(for: Calendar.current.date(byAdding: .day, value: -10, to: Date())!) + addTasks(makeTasks(on: aFewDaysAgo), callbackQueue: .main) { result in + switch result { + case .failure(let error): print("[ERROR] \(error.localizedDescription)") + case .success: break + } + } + + addContacts(makeContacts(), callbackQueue: .main) { result in + switch result { + case .failure(let error): print("[ERROR] \(error.localizedDescription)") + case .success: break + } + } + } + + private func makeTasks(on start: Date) -> [OCKTask] { + var task1 = OCKTask(id: "nausea", title: "Nausea", carePlanID: nil, + schedule: .dailyAtTime(hour: 7, minutes: 0, start: start, end: nil, text: nil)) + task1.instructions = "Log any time you experience nausea." + task1.impactsAdherence = false + + var task2 = OCKTask(id: "doxylamine", title: "Doxylamine", carePlanID: nil, + schedule: .mealTimesEachDay(start: start, end: nil)) + task2.instructions = "Take the tablet with a full glass of water." + + return [task1, task2] + } + + private func makeContacts() -> [OCKContact] { + var contact1 = OCKContact(id: "lexi-torres", givenName: "Lexi", familyName: "Torres", carePlanID: nil) + contact1.role = "Dr. Torres is a family practice doctor with over 20 years of experience." + let phoneNumbers1 = [OCKLabeledValue(label: "work", value: "2135558479")] + contact1.phoneNumbers = phoneNumbers1 + contact1.title = "Family Practice" + contact1.messagingNumbers = phoneNumbers1 + contact1.emailAddresses = [OCKLabeledValue(label: "work", value: "lexitorres@icloud.com")] + let address1 = OCKPostalAddress() + address1.street = "26 E Centerline Rd" + address1.city = "Victor" + address1.state = "MI" + address1.postalCode = "48848" + contact1.address = address1 + + var contact2 = OCKContact(id: "matthew-reiff", givenName: "Matthew", familyName: "Reiff", carePlanID: nil) + contact2.role = "Dr. Reiff is a family practice doctor with over 20 years of experience." + contact2.title = "Family Practice" + let phoneNumbers2 = [OCKLabeledValue(label: "work", value: "7745550146")] + contact2.phoneNumbers = phoneNumbers2 + contact2.messagingNumbers = phoneNumbers2 + contact2.emailAddresses = [OCKLabeledValue(label: "work", value: "matthewreiff@icloud.com")] + let address2 = OCKPostalAddress() + address2.street = "9391 Burkshire Avenue" + address2.city = "Cardiff" + address2.state = "CA" + address2.postalCode = "92007" + contact2.address = address2 + + return [contact1, contact2] + } +} diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift new file mode 100644 index 000000000..f8919f002 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift @@ -0,0 +1,268 @@ +// +/* + Copyright (c) 2020, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import SwiftUI +import CareKit + +struct OCKListView: View, UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + func makeUIViewController(context: Context) -> OCKListViewController { + let listController = OCKListViewController() + return listController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKChecklistTaskView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + func makeUIViewController(context: Context) -> OCKListViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let trackedTaskID = "doxylamine" + let viewController = OCKChecklistTaskViewController(taskID: trackedTaskID, eventQuery: .init(for: Date()), storeManager: appDelegate.storeManager) + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKGridTaskView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + func makeUIViewController(context: Context) -> OCKListViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let trackedTaskID = "doxylamine" + let viewController = OCKGridTaskViewController(taskID: trackedTaskID, eventQuery: .init(for: Date()), storeManager: appDelegate.storeManager) + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKSimpleTaskView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + func makeUIViewController(context: Context) -> OCKListViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let trackedTaskID = "doxylamine" + let viewController = OCKSimpleTaskViewController(taskID: trackedTaskID, eventQuery: .init(for: Date()), storeManager: appDelegate.storeManager) + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKInstructionsTaskView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKInstructionsTaskViewController + + func makeUIViewController(context: Context) -> OCKInstructionsTaskViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let trackedTaskID = "doxylamine" + let viewController = OCKInstructionsTaskViewController(taskID: trackedTaskID, eventQuery: .init(for: Date()), storeManager: appDelegate.storeManager) + return viewController + } + + func updateUIViewController(_ uiViewController: OCKInstructionsTaskViewController, context: Context) { + + } +} + +struct OCKButtonLogTaskView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + func makeUIViewController(context: Context) -> OCKListViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let trackedTaskID = "doxylamine" + let viewController = OCKButtonLogTaskViewController(taskID: trackedTaskID, eventQuery: .init(for: Date()), storeManager: appDelegate.storeManager) + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKSimpleContactView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + func makeUIViewController(context: Context) -> OCKListViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let contactID = "lexi-torres" + let viewController = OCKSimpleContactViewController(contactID: contactID, storeManager: appDelegate.storeManager) + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKDetailedContactView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + func makeUIViewController(context: Context) -> OCKListViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let contactID = "lexi-torres" + let viewController = OCKDetailedContactViewController(contactID: contactID, storeManager: appDelegate.storeManager) + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKCartesianChartView: UIViewControllerRepresentable { + typealias UIViewControllerType = OCKListViewController + + let type: OCKCartesianGraphView.PlotType + + func makeUIViewController(context: Context) -> OCKListViewController { + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let viewController = makeChartViewController(withStyle: type, storeManager: appDelegate.storeManager) + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController + } + + private func makeChartViewController(withStyle style: OCKCartesianGraphView.PlotType, + storeManager: OCKSynchronizedStoreManager) -> UIViewController { + // 8 and 9 + let gradientStart = UIColor { traitCollection -> UIColor in + return traitCollection.userInterfaceStyle == .light ? #colorLiteral(red: 0.9960784314, green: 0.3725490196, blue: 0.368627451, alpha: 1) : #colorLiteral(red: 0.8627432641, green: 0.2630574384, blue: 0.2592858295, alpha: 1) + } + let gradientEnd = UIColor { traitCollection -> UIColor in + return traitCollection.userInterfaceStyle == .light ? #colorLiteral(red: 0.9960784314, green: 0.4732026144, blue: 0.368627451, alpha: 1) : #colorLiteral(red: 0.8627432641, green: 0.3598620686, blue: 0.2592858295, alpha: 1) + } + + let markerSize: CGFloat = style == .bar ? 10 : 2 + let startOfDay = Calendar.current.startOfDay(for: Date()) + + let trackedTaskID = "doxylamine" + + let configurations = [ + OCKDataSeriesConfiguration( + taskID: trackedTaskID, + legendTitle: trackedTaskID.capitalized, + gradientStartColor: gradientStart, + gradientEndColor: gradientEnd, + markerSize: markerSize, + eventAggregator: .countOutcomeValues) + ] + + let chartViewController = OCKCartesianChartViewController(plotType: style, selectedDate: startOfDay, + configurations: configurations, storeManager: storeManager) + chartViewController.controller.fetchAndObserveInsights(forConfigurations: configurations) + chartViewController.chartView.headerView.titleLabel.text = trackedTaskID.capitalized + return chartViewController + } + + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { + + } +} + +struct OCKDailyTasksPageView: View, UIViewControllerRepresentable { + typealias UIViewControllerType = OCKDailyTasksPageViewController + + func makeUIViewController(context: Context) -> OCKDailyTasksPageViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let rootViewController = OCKDailyTasksPageViewController(storeManager: appDelegate.storeManager) + rootViewController.isModalInPresentation = true + return rootViewController + } + + func updateUIViewController(_ uiViewController: OCKDailyTasksPageViewController, context: Context) { + + } +} + +struct OCKContactsListView: View, UIViewControllerRepresentable { + typealias UIViewControllerType = OCKContactsListViewController + + func makeUIViewController(context: Context) -> OCKContactsListViewController { + + let appDelegate = UIApplication.shared.delegate as! AppDelegate + + let rootViewController = OCKContactsListViewController(storeManager: appDelegate.storeManager) + return rootViewController + } + + func updateUIViewController(_ uiViewController: OCKContactsListViewController, context: Context) { + + } +} diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/SceneDelegate.swift b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/SceneDelegate.swift new file mode 100644 index 000000000..9b211d487 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/SceneDelegate.swift @@ -0,0 +1,49 @@ +/* + Copyright (c) 2019, Apple Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + 3. Neither the name of the copyright holder(s) nor the names of any contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. No license is granted to the trademarks of + the copyright holders even if such marks are included in this software. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import CareKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + + let vc = UIHostingController(rootView: ContentView()) + + if let windowScene = scene as? UIWindowScene { + window = UIWindow(windowScene: windowScene) + window?.rootViewController = vc + window?.tintColor = UIColor { $0.userInterfaceStyle == .light ? #colorLiteral(red: 0.9960784314, green: 0.3725490196, blue: 0.368627451, alpha: 1) : #colorLiteral(red: 0.8627432641, green: 0.2630574384, blue: 0.2592858295, alpha: 1) } + window?.makeKeyAndVisible() + } + } +} diff --git a/OCKCatalogSwiftUI/OCKCatalogTests/Info.plist b/OCKCatalogSwiftUI/OCKCatalogTests/Info.plist new file mode 100644 index 000000000..64d65ca49 --- /dev/null +++ b/OCKCatalogSwiftUI/OCKCatalogTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKSampleSwiftUI.xcscheme b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKSampleSwiftUI.xcscheme new file mode 100644 index 000000000..72f6950e5 --- /dev/null +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI.xcodeproj/xcshareddata/xcschemes/OCKSampleSwiftUI.xcscheme @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift b/OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift index a13c7375f..650fbfcf2 100644 --- a/OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift +++ b/OCKSampleSwiftUI/OCKSampleSwiftUI/ContentView.swift @@ -42,7 +42,7 @@ struct ContentView: View { CareDailyPageView(storeManager: storeManager) .edgesIgnoringSafeArea(Edge.Set.all) .navigationBarItems( - leading: Button("Today", action: { + leading: Button(loc("TODAY"), action: { NotificationCenter.default.post(name: NSNotification.Name.CareViewController.pressedToday, object: nil) }), trailing: Button("Care Teams", action: { self.isContactListViewPresented = true From 90689fced7e38b4296c22fd996cb0d1017b56af8 Mon Sep 17 00:00:00 2001 From: Miroslav Kutak Date: Fri, 8 May 2020 13:19:25 +0200 Subject: [PATCH 3/3] Minor textual changes to the OCK catalog sample --- .../OCKCatalogSwiftUI/ContentView.swift | 2 +- .../OCKViewControllerRepresentable.swift | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift index d714ba955..d7e0553a2 100644 --- a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/ContentView.swift @@ -65,7 +65,7 @@ struct ContentView: View { ListItem(destination: OCKCartesianChartView(type: .bar), title: "Bar") } Section(header: Text("LIST")) { - ListItem(destination: OCKDailyTasksPageView(), title: "Task") + ListItem(destination: OCKDailyTasksPageView(), title: "Tasks") ListItem(destination: OCKContactsListView(), title: "Contacts") } } diff --git a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift index f8919f002..7e0b73361 100644 --- a/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift +++ b/OCKCatalogSwiftUI/OCKCatalogSwiftUI/OCKViewControllerRepresentable.swift @@ -106,18 +106,22 @@ struct OCKSimpleTaskView: UIViewControllerRepresentable { } struct OCKInstructionsTaskView: UIViewControllerRepresentable { - typealias UIViewControllerType = OCKInstructionsTaskViewController + typealias UIViewControllerType = OCKListViewController - func makeUIViewController(context: Context) -> OCKInstructionsTaskViewController { + func makeUIViewController(context: Context) -> OCKListViewController { let appDelegate = UIApplication.shared.delegate as! AppDelegate let trackedTaskID = "doxylamine" let viewController = OCKInstructionsTaskViewController(taskID: trackedTaskID, eventQuery: .init(for: Date()), storeManager: appDelegate.storeManager) - return viewController + + + let listController = OCKListViewController() + listController.appendViewController(viewController, animated: false) + return listController } - func updateUIViewController(_ uiViewController: OCKInstructionsTaskViewController, context: Context) { + func updateUIViewController(_ uiViewController: OCKListViewController, context: Context) { } }