├── SleepAccelerometer ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ ├── sleep_accel-1024.png │ │ ├── sleep_accel-120.png │ │ ├── sleep_accel-121.png │ │ ├── sleep_accel-152.png │ │ ├── sleep_accel-167.png │ │ ├── sleep_accel-180.png │ │ ├── sleep_accel-20.png │ │ ├── sleep_accel-29.png │ │ ├── sleep_accel-40.png │ │ ├── sleep_accel-41.png │ │ ├── sleep_accel-42.png │ │ ├── sleep_accel-58.png │ │ ├── sleep_accel-59.png │ │ ├── sleep_accel-60.png │ │ ├── sleep_accel-76.png │ │ ├── sleep_accel-80.png │ │ ├── sleep_accel-81.png │ │ ├── sleep_accel-87.png │ │ └── Contents.json ├── SleepAccelerometer-Bridging-Header.h ├── HealthHelper.h ├── SleepAccelerometer.entitlements ├── MainTableViewCell.swift ├── HealthHelper.m ├── Data.xcdatamodeld │ └── Data.xcdatamodel │ │ └── contents ├── WatchManager.swift ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── HeartRateHandler.swift ├── Info.plist ├── AppDelegate.swift ├── SleepEvent.swift └── MainTableViewController.swift ├── .gitignore ├── SleepAccelerometer WatchKit App ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ ├── sleep_accel-100.png │ │ ├── sleep_accel-172.png │ │ ├── sleep_accel-196.png │ │ ├── sleep_accel-216.png │ │ ├── sleep_accel-48.png │ │ ├── sleep_accel-55.png │ │ ├── sleep_accel-58.png │ │ ├── sleep_accel-80.png │ │ ├── sleep_accel-87.png │ │ ├── sleep_accel-88.png │ │ ├── sleep_accel-1024.png │ │ └── Contents.json ├── Info.plist └── Base.lproj │ └── Interface.storyboard ├── SleepAccelerometer WatchKit Extension ├── Assets.xcassets │ ├── Contents.json │ └── Complication.complicationset │ │ ├── Graphic Bezel.imageset │ │ └── Contents.json │ │ ├── Graphic Corner.imageset │ │ └── Contents.json │ │ ├── Graphic Circular.imageset │ │ └── Contents.json │ │ ├── Graphic Large Rectangular.imageset │ │ └── Contents.json │ │ ├── Circular.imageset │ │ └── Contents.json │ │ ├── Modular.imageset │ │ └── Contents.json │ │ ├── Extra Large.imageset │ │ └── Contents.json │ │ ├── Utilitarian.imageset │ │ └── Contents.json │ │ ├── Graphic Extra Large.imageset │ │ └── Contents.json │ │ └── Contents.json ├── SleepAccelerometer WatchKit Extension.entitlements ├── InterfaceController.swift ├── NotificationController.swift ├── SleepData.xcdatamodeld │ └── SleepData.xcdatamodel │ │ └── contents ├── PushNotificationPayload.apns ├── CompletionInterfaceController.swift ├── Info.plist ├── ConfigurationInterfaceController.swift ├── ExtensionDelegate.swift └── SleepInterfaceController.swift ├── SleepAccelerometer.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── ojwalch.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── SleepAccelerometer.xcscheme └── project.pbxproj ├── README.md ├── SleepAccelerometerTests ├── Info.plist └── SleepAccelerometerTests.swift └── SleepAccelerometerUITests ├── Info.plist └── SleepAccelerometerUITests.swift /SleepAccelerometer/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | SleepAccelerometer.xcodeproj/project.xcworkspace/xcuserdata/* 2 | SleepAccelerometer.xcodeproj/xcuserdata/* 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-1024.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-120.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-121.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-121.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-152.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-167.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-180.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-20.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-29.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-40.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-41.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-42.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-58.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-59.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-60.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-76.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-80.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-81.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-81.png -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/sleep_accel-87.png -------------------------------------------------------------------------------- /SleepAccelerometer/SleepAccelerometer-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "HealthHelper.h" 6 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-100.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-172.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-196.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-216.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-48.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-55.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-58.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-80.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-87.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-88.png -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ojwalch/sleep_accel/HEAD/SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/sleep_accel-1024.png -------------------------------------------------------------------------------- /SleepAccelerometer/HealthHelper.h: -------------------------------------------------------------------------------- 1 | #import 2 | @import HealthKit; 3 | 4 | @interface HealthHelper : NSObject 5 | @property HKHealthStore *healthStore; 6 | 7 | -(void) getHealthPermissions; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /SleepAccelerometer.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sleep Accel 2 | 3 | This is a simple app to scrape acceleration data from an Apple Watch. It also starts an exercise event to achieve continuous heart rate monitoring without needing to turn on the microphone. Saved sleep events appear in a TableView on the main page. 4 | 5 | 6 | ## License 7 | MIT 8 | -------------------------------------------------------------------------------- /SleepAccelerometer/SleepAccelerometer.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.healthkit 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SleepAccelerometer/MainTableViewCell.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class MainTableViewCell: UITableViewCell { 4 | 5 | override func awakeFromNib() { 6 | super.awakeFromNib() 7 | } 8 | 9 | override func setSelected(_ selected: Bool, animated: Bool) { 10 | super.setSelected(selected, animated: animated) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SleepAccelerometer.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/SleepAccelerometer WatchKit Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.healthkit 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : ">161" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">183" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : ">161" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">183" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/InterfaceController.swift: -------------------------------------------------------------------------------- 1 | import WatchKit 2 | import Foundation 3 | 4 | class InterfaceController: WKInterfaceController { 5 | 6 | override func awake(withContext context: Any?) { 7 | super.awake(withContext: context) 8 | } 9 | 10 | override func willActivate() { 11 | super.willActivate() 12 | } 13 | 14 | override func didDeactivate() { 15 | super.didDeactivate() 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : ">161" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">183" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : ">161" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">183" 12 | } 13 | ], 14 | "info" : { 15 | "author" : "xcode", 16 | "version" : 1 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">161" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "scale" : "2x", 16 | "screen-width" : ">145" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "scale" : "2x", 21 | "screen-width" : ">183" 22 | } 23 | ], 24 | "info" : { 25 | "author" : "xcode", 26 | "version" : 1 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">161" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "scale" : "2x", 16 | "screen-width" : ">145" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "scale" : "2x", 21 | "screen-width" : ">183" 22 | } 23 | ], 24 | "info" : { 25 | "author" : "xcode", 26 | "version" : 1 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">161" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "scale" : "2x", 16 | "screen-width" : ">145" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "scale" : "2x", 21 | "screen-width" : ">183" 22 | } 23 | ], 24 | "info" : { 25 | "author" : "xcode", 26 | "version" : 1 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">161" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "scale" : "2x", 16 | "screen-width" : ">145" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "scale" : "2x", 21 | "screen-width" : ">183" 22 | } 23 | ], 24 | "info" : { 25 | "author" : "xcode", 26 | "version" : 1 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Graphic Extra Large.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "watch", 5 | "scale" : "2x", 6 | "screen-width" : "<=145" 7 | }, 8 | { 9 | "idiom" : "watch", 10 | "scale" : "2x", 11 | "screen-width" : ">161" 12 | }, 13 | { 14 | "idiom" : "watch", 15 | "scale" : "2x", 16 | "screen-width" : ">145" 17 | }, 18 | { 19 | "idiom" : "watch", 20 | "scale" : "2x", 21 | "screen-width" : ">183" 22 | } 23 | ], 24 | "info" : { 25 | "author" : "xcode", 26 | "version" : 1 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/NotificationController.swift: -------------------------------------------------------------------------------- 1 | 2 | import WatchKit 3 | import Foundation 4 | import UserNotifications 5 | 6 | 7 | class NotificationController: WKUserNotificationInterfaceController { 8 | 9 | override init() { 10 | // Initialize variables here. 11 | super.init() 12 | 13 | // Configure interface objects here. 14 | } 15 | 16 | override func willActivate() { 17 | // This method is called when watch view controller is about to be visible to user 18 | super.willActivate() 19 | } 20 | 21 | override func didDeactivate() { 22 | // This method is called when watch view controller is no longer visible 23 | super.didDeactivate() 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /SleepAccelerometerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SleepAccelerometerUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/SleepData.xcdatamodeld/SleepData.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/PushNotificationPayload.apns: -------------------------------------------------------------------------------- 1 | { 2 | "aps": { 3 | "alert": { 4 | "body": "Test message", 5 | "title": "Optional title" 6 | }, 7 | "category": "myCategory", 8 | "thread-id":"5280" 9 | }, 10 | 11 | "WatchKit Simulator Actions": [ 12 | { 13 | "title": "First Button", 14 | "identifier": "firstButtonAction" 15 | } 16 | ], 17 | 18 | "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." 19 | } 20 | -------------------------------------------------------------------------------- /SleepAccelerometerTests/SleepAccelerometerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SleepAccelerometerTests.swift 3 | // SleepAccelerometerTests 4 | // 5 | // Created by Olivia Walch on 5/9/18. 6 | // Copyright © 2018 Olivia Walch. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import SleepAccelerometer 11 | 12 | class SleepAccelerometerTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SleepAccelerometer/HealthHelper.m: -------------------------------------------------------------------------------- 1 | #import "HealthHelper.h" 2 | 3 | @implementation HealthHelper 4 | 5 | /* Requests access for heart rate and steps */ 6 | -(void) getHealthPermissions{ 7 | NSLog(@"Requesting health permissions..."); 8 | 9 | if(NSClassFromString(@"HKHealthStore") && [HKHealthStore isHealthDataAvailable]) 10 | { 11 | _healthStore = [[HKHealthStore alloc] init]; 12 | 13 | NSSet *readObjectTypes = [NSSet setWithObjects: 14 | [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate], 15 | [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount], 16 | nil]; 17 | 18 | [_healthStore requestAuthorizationToShareTypes:nil 19 | readTypes:readObjectTypes 20 | completion:^(BOOL success, NSError *error) { 21 | 22 | if(success == YES) 23 | { 24 | NSLog(@"Successfully got access."); 25 | } 26 | else 27 | { 28 | NSLog(@"Unable to get authorization for health access."); 29 | } 30 | }]; 31 | } 32 | 33 | } 34 | 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | SleepAccelerometer WatchKit App 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | UISupportedInterfaceOrientations 24 | 25 | UIInterfaceOrientationPortrait 26 | UIInterfaceOrientationPortraitUpsideDown 27 | 28 | WKCompanionAppBundleIdentifier 29 | com.arcascope.SleepAccelerometer 30 | WKWatchKitApp 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /SleepAccelerometer.xcodeproj/xcuserdata/ojwalch.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SleepAccelerometer WatchKit App (Notification).xcscheme 8 | 9 | orderHint 10 | 2 11 | 12 | SleepAccelerometer WatchKit App.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | SleepAccelerometer.xcscheme 18 | 19 | orderHint 20 | 0 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 02C9480520A33F540065C296 26 | 27 | primary 28 | 29 | 30 | 02C9481920A33F580065C296 31 | 32 | primary 33 | 34 | 35 | 02C9482420A33F580065C296 36 | 37 | primary 38 | 39 | 40 | 02C9482D20A33F580065C296 41 | 42 | primary 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /SleepAccelerometer/Data.xcdatamodeld/Data.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/Assets.xcassets/Complication.complicationset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "assets" : [ 3 | { 4 | "filename" : "Circular.imageset", 5 | "idiom" : "watch", 6 | "role" : "circular" 7 | }, 8 | { 9 | "filename" : "Extra Large.imageset", 10 | "idiom" : "watch", 11 | "role" : "extra-large" 12 | }, 13 | { 14 | "filename" : "Graphic Bezel.imageset", 15 | "idiom" : "watch", 16 | "role" : "graphic-bezel" 17 | }, 18 | { 19 | "filename" : "Graphic Circular.imageset", 20 | "idiom" : "watch", 21 | "role" : "graphic-circular" 22 | }, 23 | { 24 | "filename" : "Graphic Corner.imageset", 25 | "idiom" : "watch", 26 | "role" : "graphic-corner" 27 | }, 28 | { 29 | "filename" : "Graphic Extra Large.imageset", 30 | "idiom" : "watch", 31 | "role" : "graphic-extra-large" 32 | }, 33 | { 34 | "filename" : "Graphic Large Rectangular.imageset", 35 | "idiom" : "watch", 36 | "role" : "graphic-large-rectangular" 37 | }, 38 | { 39 | "filename" : "Modular.imageset", 40 | "idiom" : "watch", 41 | "role" : "modular" 42 | }, 43 | { 44 | "filename" : "Utilitarian.imageset", 45 | "idiom" : "watch", 46 | "role" : "utilitarian" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SleepAccelerometerUITests/SleepAccelerometerUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SleepAccelerometerUITests.swift 3 | // SleepAccelerometerUITests 4 | // 5 | // Created by Olivia Walch on 5/9/18. 6 | // Copyright © 2018 Olivia Walch. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SleepAccelerometerUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SleepAccelerometer/WatchManager.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import WatchConnectivity 3 | 4 | class WatchManager: NSObject { 5 | 6 | fileprivate var watchSession: WCSession? 7 | 8 | override init() { 9 | super.init() 10 | watchSession = WCSession.default 11 | watchSession?.delegate = self 12 | watchSession?.activate() 13 | } 14 | } 15 | 16 | extension WatchManager: WCSessionDelegate { 17 | 18 | func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 19 | print("Session activation did complete") 20 | } 21 | 22 | public func sessionDidBecomeInactive(_ session: WCSession) { 23 | print("Session became inactive") 24 | } 25 | 26 | public func sessionDidDeactivate(_ session: WCSession) { 27 | print("Session deactivated") 28 | } 29 | 30 | func session(_: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String : Any]) -> Void){ 31 | 32 | let key = message["key"] as! Double 33 | let accel = message["acceleration"] as! NSArray 34 | 35 | for i in 0.. 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | SleepAccelerometer WatchKit Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSExtension 24 | 25 | NSExtensionAttributes 26 | 27 | WKAppBundleIdentifier 28 | com.arcascope.SleepAccelerometer.watchkitapp 29 | 30 | NSExtensionPointIdentifier 31 | com.apple.watchkit 32 | 33 | WKBackgroundModes 34 | 35 | workout-processing 36 | 37 | WKExtensionDelegateClassName 38 | $(PRODUCT_MODULE_NAME).ExtensionDelegate 39 | NSHealthUpdateUsageDescription 40 | We update health data to track sleep 41 | NSHealthShareUsageDescription 42 | We access health data to track sleep 43 | 44 | 45 | -------------------------------------------------------------------------------- /SleepAccelerometer/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/ConfigurationInterfaceController.swift: -------------------------------------------------------------------------------- 1 | import WatchKit 2 | import Foundation 3 | import HealthKit 4 | import WatchConnectivity 5 | 6 | class ConfigurationInterfaceController: WKInterfaceController { 7 | 8 | var watchSession: WCSession? { 9 | didSet { 10 | if let session = watchSession { 11 | print("Creating watch session") 12 | session.delegate = self 13 | session.activate() 14 | } 15 | } 16 | } 17 | 18 | override init() { 19 | super.init() 20 | } 21 | 22 | override func awake(withContext context: Any?) { 23 | super.awake(withContext: context) 24 | 25 | watchSession = WCSession.default 26 | setTitle("Sleep Tracker") 27 | } 28 | 29 | override func didAppear() { 30 | super.didAppear() 31 | } 32 | 33 | @IBAction func beginRecording() { 34 | let workoutConfiguration = HKWorkoutConfiguration() 35 | workoutConfiguration.activityType = .yoga 36 | workoutConfiguration.locationType = .indoor 37 | 38 | if #available(watchOSApplicationExtension 4.0, *) { 39 | WKInterfaceController.reloadRootPageControllers(withNames: ["SleepInterfaceController"], contexts: [workoutConfiguration], orientation: WKPageOrientation.vertical, pageIndex: 0) 40 | } else { 41 | WKInterfaceController.reloadRootControllers(withNames: ["SleepInterfaceController"], contexts: [workoutConfiguration]) 42 | } 43 | } 44 | 45 | } 46 | 47 | extension ConfigurationInterfaceController: WCSessionDelegate { 48 | func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 49 | print("Session activation completed") 50 | } 51 | 52 | func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) { 53 | 54 | print("Watch received app context: ", applicationContext) 55 | 56 | if (applicationContext["ConnectedKey"] as? Bool) == true { 57 | print("Connected") 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /SleepAccelerometer/HeartRateHandler.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import UIKit 3 | 4 | class HeartRateHandler: NSObject { 5 | var stringHolder = [String]() 6 | 7 | let health: HKHealthStore = HKHealthStore() 8 | let heartRateUnit:HKUnit = HKUnit(from: "count/min") 9 | let heartRateType:HKQuantityType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)! 10 | var heartRateQuery:HKSampleQuery? 11 | 12 | // Retrieve heart rate data and save to file 13 | func retrieveHeartRate(start: Date, end: Date, path: URL, completionHandler: @escaping (() -> Void)) { 14 | 15 | if let sleepType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate) 16 | { 17 | let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: true) 18 | let predicate = HKQuery.predicateForSamples(withStart: start, end: end, options: .strictStartDate) 19 | 20 | let query = HKSampleQuery(sampleType: sleepType, predicate: predicate, limit: 3000000, sortDescriptors: [sortDescriptor]) { (query, tmpResult, error) -> Void in 21 | 22 | if error != nil { 23 | print("Unable to query") 24 | return 25 | } 26 | 27 | if let result = tmpResult { 28 | 29 | for item in result { 30 | if let sample = item as? HKQuantitySample { 31 | let value = sample.quantity.doubleValue(for: HKUnit(from: "count/min")) 32 | self.stringHolder.append("\(sample.startDate.timeIntervalSince1970),\(value)") 33 | } 34 | } 35 | } 36 | self.writeString(path: path, completionHandler: completionHandler) 37 | } 38 | health.execute(query) 39 | } 40 | } 41 | 42 | func writeString(path: URL, completionHandler: @escaping ()-> Void){ 43 | let text = self.stringHolder.joined(separator: "\n") 44 | 45 | do { 46 | try text.write(to: path, atomically: false, encoding: String.Encoding.utf8) 47 | print("Save path: " + path.absoluteString) 48 | DispatchQueue.main.async{ 49 | completionHandler() 50 | } 51 | } 52 | catch { 53 | print("Could not write HR to file"); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SleepAccelerometer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | LSRequiresIPhoneOS 22 | 23 | NSCameraUsageDescription 24 | The app does not use a camera 25 | NSHealthShareUsageDescription 26 | Improve circadian estimate 27 | NSHealthUpdateUsageDescription 28 | Improve circadian estimate 29 | NSLocationAlwaysAndWhenInUseUsageDescription 30 | We use GPS to improve light estimate 31 | NSLocationAlwaysUsageDescription 32 | We use GPS to improve light estimate 33 | NSLocationWhenInUseUsageDescription 34 | We use GPS to improve light estimate 35 | NSMicrophoneUsageDescription 36 | The app does not use the microphone 37 | NSMotionUsageDescription 38 | The app uses motion to better estimate your circadian state 39 | UIBackgroundModes 40 | 41 | audio 42 | location 43 | 44 | UILaunchStoryboardName 45 | LaunchScreen 46 | UIMainStoryboardFile 47 | Main 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | healthkit 52 | 53 | UISupportedInterfaceOrientations 54 | 55 | UIInterfaceOrientationPortrait 56 | 57 | UISupportedInterfaceOrientations~ipad 58 | 59 | UIInterfaceOrientationPortrait 60 | UIInterfaceOrientationPortraitUpsideDown 61 | UIInterfaceOrientationLandscapeLeft 62 | UIInterfaceOrientationLandscapeRight 63 | 64 | UIViewControllerBasedStatusBarAppearance 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/ExtensionDelegate.swift: -------------------------------------------------------------------------------- 1 | import WatchKit 2 | 3 | class ExtensionDelegate: NSObject, WKExtensionDelegate { 4 | 5 | func applicationDidFinishLaunching() { 6 | // Perform any final initialization of your application. 7 | } 8 | 9 | func applicationDidBecomeActive() { 10 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 11 | } 12 | 13 | func applicationWillResignActive() { 14 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 15 | // Use this method to pause ongoing tasks, disable timers, etc. 16 | } 17 | 18 | func handle(_ backgroundTasks: Set) { 19 | // Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one. 20 | for task in backgroundTasks { 21 | // Use a switch statement to check the task type 22 | switch task { 23 | case let backgroundTask as WKApplicationRefreshBackgroundTask: 24 | // Be sure to complete the background task once you’re done. 25 | if #available(watchOSApplicationExtension 4.0, *) { 26 | backgroundTask.setTaskCompletedWithSnapshot(false) 27 | } else { 28 | // Fallback on earlier versions 29 | } 30 | case let snapshotTask as WKSnapshotRefreshBackgroundTask: 31 | // Snapshot tasks have a unique completion call, make sure to set your expiration date 32 | snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil) 33 | case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask: 34 | // Be sure to complete the connectivity task once you’re done. 35 | if #available(watchOSApplicationExtension 4.0, *) { 36 | connectivityTask.setTaskCompletedWithSnapshot(false) 37 | } else { 38 | // Fallback on earlier versions 39 | } 40 | case let urlSessionTask as WKURLSessionRefreshBackgroundTask: 41 | // Be sure to complete the URL session task once you’re done. 42 | if #available(watchOSApplicationExtension 4.0, *) { 43 | urlSessionTask.setTaskCompletedWithSnapshot(false) 44 | } else { 45 | // Fallback on earlier versions 46 | } 47 | default: 48 | // make sure to complete unhandled task types 49 | if #available(watchOSApplicationExtension 4.0, *) { 50 | task.setTaskCompletedWithSnapshot(false) 51 | } else { 52 | // Fallback on earlier versions 53 | } 54 | } 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /SleepAccelerometer/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "sleep_accel-40.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "sleep_accel-60.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "sleep_accel-58.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "sleep_accel-87.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "sleep_accel-80.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "sleep_accel-120.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "sleep_accel-121.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "sleep_accel-180.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "sleep_accel-20.png", 53 | "idiom" : "ipad", 54 | "scale" : "1x", 55 | "size" : "20x20" 56 | }, 57 | { 58 | "filename" : "sleep_accel-41.png", 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "20x20" 62 | }, 63 | { 64 | "filename" : "sleep_accel-29.png", 65 | "idiom" : "ipad", 66 | "scale" : "1x", 67 | "size" : "29x29" 68 | }, 69 | { 70 | "filename" : "sleep_accel-59.png", 71 | "idiom" : "ipad", 72 | "scale" : "2x", 73 | "size" : "29x29" 74 | }, 75 | { 76 | "filename" : "sleep_accel-42.png", 77 | "idiom" : "ipad", 78 | "scale" : "1x", 79 | "size" : "40x40" 80 | }, 81 | { 82 | "filename" : "sleep_accel-81.png", 83 | "idiom" : "ipad", 84 | "scale" : "2x", 85 | "size" : "40x40" 86 | }, 87 | { 88 | "filename" : "sleep_accel-76.png", 89 | "idiom" : "ipad", 90 | "scale" : "1x", 91 | "size" : "76x76" 92 | }, 93 | { 94 | "filename" : "sleep_accel-152.png", 95 | "idiom" : "ipad", 96 | "scale" : "2x", 97 | "size" : "76x76" 98 | }, 99 | { 100 | "filename" : "sleep_accel-167.png", 101 | "idiom" : "ipad", 102 | "scale" : "2x", 103 | "size" : "83.5x83.5" 104 | }, 105 | { 106 | "filename" : "sleep_accel-1024.png", 107 | "idiom" : "ios-marketing", 108 | "scale" : "1x", 109 | "size" : "1024x1024" 110 | } 111 | ], 112 | "info" : { 113 | "author" : "xcode", 114 | "version" : 1 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /SleepAccelerometer/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | import CoreData 4 | import WatchConnectivity 5 | 6 | @UIApplicationMain 7 | class AppDelegate: UIResponder, UIApplicationDelegate { 8 | 9 | var window: UIWindow? 10 | var watchManager = WatchManager() 11 | 12 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 13 | let navigationBarAppearance = UINavigationBar.appearance() 14 | 15 | navigationBarAppearance.tintColor = UIColor.white 16 | navigationBarAppearance.barTintColor = UIColor.darkGray 17 | 18 | if let vc = window?.rootViewController as? MainTableViewController { 19 | vc.watchManager = watchManager; 20 | } 21 | 22 | return true 23 | } 24 | 25 | 26 | func applicationWillResignActive(_ application: UIApplication) { 27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 28 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 29 | } 30 | 31 | func applicationDidEnterBackground(_ application: UIApplication) { 32 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 34 | } 35 | 36 | func applicationWillEnterForeground(_ application: UIApplication) { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | func applicationDidBecomeActive(_ application: UIApplication) { 41 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 42 | } 43 | 44 | func applicationWillTerminate(_ application: UIApplication) { 45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 46 | } 47 | 48 | lazy var persistentContainer: NSPersistentContainer = { 49 | 50 | let container = NSPersistentContainer(name: "Data") 51 | container.loadPersistentStores(completionHandler: { (storeDescription, error) in 52 | if let error = error { 53 | 54 | fatalError("Unresolved error, \((error as NSError).userInfo)") 55 | } 56 | }) 57 | return container 58 | }() 59 | 60 | 61 | func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 62 | 63 | } 64 | 65 | func sessionDidBecomeInactive(_ session: WCSession) { 66 | 67 | } 68 | 69 | func sessionDidDeactivate(_ session: WCSession) { 70 | 71 | } 72 | 73 | } 74 | 75 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "sleep_accel-48.png", 5 | "idiom" : "watch", 6 | "role" : "notificationCenter", 7 | "scale" : "2x", 8 | "size" : "24x24", 9 | "subtype" : "38mm" 10 | }, 11 | { 12 | "filename" : "sleep_accel-55.png", 13 | "idiom" : "watch", 14 | "role" : "notificationCenter", 15 | "scale" : "2x", 16 | "size" : "27.5x27.5", 17 | "subtype" : "42mm" 18 | }, 19 | { 20 | "filename" : "sleep_accel-58.png", 21 | "idiom" : "watch", 22 | "role" : "companionSettings", 23 | "scale" : "2x", 24 | "size" : "29x29" 25 | }, 26 | { 27 | "filename" : "sleep_accel-87.png", 28 | "idiom" : "watch", 29 | "role" : "companionSettings", 30 | "scale" : "3x", 31 | "size" : "29x29" 32 | }, 33 | { 34 | "idiom" : "watch", 35 | "role" : "notificationCenter", 36 | "scale" : "2x", 37 | "size" : "33x33", 38 | "subtype" : "45mm" 39 | }, 40 | { 41 | "filename" : "sleep_accel-80.png", 42 | "idiom" : "watch", 43 | "role" : "appLauncher", 44 | "scale" : "2x", 45 | "size" : "40x40", 46 | "subtype" : "38mm" 47 | }, 48 | { 49 | "filename" : "sleep_accel-88.png", 50 | "idiom" : "watch", 51 | "role" : "appLauncher", 52 | "scale" : "2x", 53 | "size" : "44x44", 54 | "subtype" : "40mm" 55 | }, 56 | { 57 | "idiom" : "watch", 58 | "role" : "appLauncher", 59 | "scale" : "2x", 60 | "size" : "46x46", 61 | "subtype" : "41mm" 62 | }, 63 | { 64 | "filename" : "sleep_accel-100.png", 65 | "idiom" : "watch", 66 | "role" : "appLauncher", 67 | "scale" : "2x", 68 | "size" : "50x50", 69 | "subtype" : "44mm" 70 | }, 71 | { 72 | "idiom" : "watch", 73 | "role" : "appLauncher", 74 | "scale" : "2x", 75 | "size" : "51x51", 76 | "subtype" : "45mm" 77 | }, 78 | { 79 | "idiom" : "watch", 80 | "role" : "appLauncher", 81 | "scale" : "2x", 82 | "size" : "54x54", 83 | "subtype" : "49mm" 84 | }, 85 | { 86 | "filename" : "sleep_accel-172.png", 87 | "idiom" : "watch", 88 | "role" : "quickLook", 89 | "scale" : "2x", 90 | "size" : "86x86", 91 | "subtype" : "38mm" 92 | }, 93 | { 94 | "filename" : "sleep_accel-196.png", 95 | "idiom" : "watch", 96 | "role" : "quickLook", 97 | "scale" : "2x", 98 | "size" : "98x98", 99 | "subtype" : "42mm" 100 | }, 101 | { 102 | "filename" : "sleep_accel-216.png", 103 | "idiom" : "watch", 104 | "role" : "quickLook", 105 | "scale" : "2x", 106 | "size" : "108x108", 107 | "subtype" : "44mm" 108 | }, 109 | { 110 | "idiom" : "watch", 111 | "role" : "quickLook", 112 | "scale" : "2x", 113 | "size" : "117x117", 114 | "subtype" : "45mm" 115 | }, 116 | { 117 | "idiom" : "watch", 118 | "role" : "quickLook", 119 | "scale" : "2x", 120 | "size" : "129x129", 121 | "subtype" : "49mm" 122 | }, 123 | { 124 | "filename" : "sleep_accel-1024.png", 125 | "idiom" : "watch-marketing", 126 | "scale" : "1x", 127 | "size" : "1024x1024" 128 | }, 129 | { 130 | "idiom" : "watch", 131 | "role" : "longLook", 132 | "scale" : "2x", 133 | "size" : "44x44", 134 | "subtype" : "42mm" 135 | } 136 | ], 137 | "info" : { 138 | "author" : "xcode", 139 | "version" : 1 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /SleepAccelerometer/SleepEvent.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | import CoreData 4 | 5 | class SleepEvent: NSObject { 6 | 7 | class func getAllEvents() async throws -> [Double] { 8 | guard let appDelegate = await UIApplication.shared.delegate as? AppDelegate else { 9 | return [] 10 | } 11 | 12 | let managedContext = await appDelegate.persistentContainer.viewContext 13 | 14 | let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "Acceleration") 15 | fetchRequest.resultType = .dictionaryResultType 16 | fetchRequest.propertiesToFetch = ["start_time"] 17 | fetchRequest.returnsDistinctResults = true 18 | 19 | let result = try await managedContext.perform { 20 | return try managedContext.fetch(fetchRequest) 21 | } 22 | let startTimes = result.compactMap { dict -> Double? in 23 | return dict["start_time"] as? Double 24 | } 25 | return startTimes 26 | } 27 | 28 | // Get all acceleration data types for start time 29 | class func getAccelerationFor(startTime: Double) async throws -> [[Double]] { 30 | guard let appDelegate = await UIApplication.shared.delegate as? AppDelegate else { 31 | return [] 32 | } 33 | 34 | let managedContext = await appDelegate.persistentContainer.viewContext 35 | 36 | let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "Acceleration") 37 | fetchRequest.predicate = NSPredicate(format: "start_time == %@", String(startTime)) 38 | 39 | let result = try await managedContext.perform { 40 | return try fetchRequest.execute() 41 | } 42 | 43 | let values: [[Double]] = result.compactMap { data in 44 | guard let timeStamp = data.value(forKey: "time_stamp") as? Double, 45 | let xAccel = data.value(forKey: "x_accel") as? Double, 46 | let yAccel = data.value(forKey: "y_accel") as? Double, 47 | let zAccel = data.value(forKey: "z_accel") as? Double else { 48 | return nil 49 | } 50 | return [timeStamp, xAccel, yAccel, zAccel] 51 | } 52 | return values 53 | } 54 | 55 | class func deleteAccelerationFor(startTime: Double) async throws -> Int { 56 | guard let appDelegate = await UIApplication.shared.delegate as? AppDelegate else { 57 | return 0 58 | } 59 | 60 | let context = await appDelegate.persistentContainer.newBackgroundContext() 61 | return try await context.perform { 62 | let request = NSFetchRequest(entityName: "Acceleration") 63 | request.predicate = NSPredicate(format: "start_time == %@", String(startTime)) 64 | let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: request) 65 | batchDeleteRequest.resultType = .resultTypeCount 66 | let result = try context.execute(batchDeleteRequest) as! NSBatchDeleteResult 67 | print("Deleted this many results: " + String(result.result as! Int)) 68 | return result.result as! Int 69 | } 70 | } 71 | 72 | class func writeEvent(start : Double, timeStamp : Double, x : Double, y : Double, z : Double){ 73 | DispatchQueue.main.async{ 74 | guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { 75 | return 76 | } 77 | 78 | let managedContext = appDelegate.persistentContainer.viewContext 79 | let entity = NSEntityDescription.entity(forEntityName: "Acceleration", in: managedContext) 80 | 81 | if(entity != nil){ 82 | 83 | let accelItem = NSManagedObject(entity: entity!, insertInto: managedContext) 84 | accelItem.setValue(x, forKeyPath: "x_accel") 85 | accelItem.setValue(y, forKeyPath: "y_accel") 86 | accelItem.setValue(z, forKeyPath: "z_accel") 87 | accelItem.setValue(timeStamp, forKeyPath: "time_stamp") 88 | accelItem.setValue(round(start), forKeyPath: "start_time") 89 | 90 | do { 91 | try managedContext.save() 92 | } catch let error as NSError { 93 | print("Could not save. \(error), \(error.userInfo)") 94 | } 95 | } 96 | } 97 | } 98 | } 99 | 100 | -------------------------------------------------------------------------------- /SleepAccelerometer.xcodeproj/xcuserdata/ojwalch.xcuserdatad/xcschemes/SleepAccelerometer.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /SleepAccelerometer/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 82 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /SleepAccelerometer WatchKit Extension/SleepInterfaceController.swift: -------------------------------------------------------------------------------- 1 | import WatchKit 2 | import Foundation 3 | import HealthKit 4 | import CoreMotion 5 | import WatchConnectivity 6 | 7 | class SleepInterfaceController: WKInterfaceController, HKWorkoutSessionDelegate,URLSessionDelegate{ 8 | 9 | let healthStore = HKHealthStore() 10 | var workoutSession : HKWorkoutSession? 11 | var activeDataQueries = [HKQuery]() 12 | var workoutStartDate : Date? 13 | var workoutEndDate : Date? 14 | var workoutEvents = [HKWorkoutEvent]() 15 | var metadata = [String: AnyObject]() 16 | var timer : Timer? 17 | var isPaused = false 18 | var counter = 0 19 | let threshold = 1000 20 | 21 | let motionManager = CMMotionManager() 22 | var allValues = ""; 23 | let defaults = UserDefaults.standard 24 | var accelerometerOutput = NSMutableArray() 25 | var accelerometerOutputPost = NSMutableArray() 26 | 27 | var watchSession: WCSession? { 28 | didSet { 29 | if let session = watchSession { 30 | session.delegate = self 31 | session.activate() 32 | } 33 | } 34 | } 35 | 36 | override func awake(withContext context: Any?) { 37 | super.awake(withContext: context) 38 | watchSession = WCSession.default 39 | 40 | if let workoutConfiguration = context as? HKWorkoutConfiguration { 41 | do { 42 | workoutSession = try HKWorkoutSession(healthStore: healthStore, configuration: workoutConfiguration) 43 | workoutSession?.delegate = self 44 | workoutStartDate = Date() 45 | workoutSession?.startActivity(with: Date()) 46 | 47 | } catch { 48 | } 49 | } 50 | } 51 | 52 | @IBAction func stopRecording() { 53 | workoutEndDate = Date() 54 | workoutSession?.end() 55 | } 56 | 57 | func pushToPhone(){ 58 | if WCSession.isSupported() { 59 | 60 | let session = WCSession.default 61 | print("Attempting to post \(self.accelerometerOutputPost.count) entries to phone...") 62 | 63 | session.sendMessage(["key": Double((workoutStartDate?.timeIntervalSince1970)!), "acceleration" : self.accelerometerOutputPost], replyHandler: { (response) -> Void in 64 | if let response = response["response"] as? String { 65 | print(response) 66 | } 67 | 68 | }, errorHandler: { (error) -> Void in 69 | print(error) 70 | }) 71 | } 72 | } 73 | 74 | func startAccumulatingData(startDate: Date) { 75 | startMotionCapture(); 76 | } 77 | 78 | func startQuery(quantityTypeIdentifier: HKQuantityTypeIdentifier) { 79 | let datePredicate = HKQuery.predicateForSamples(withStart: workoutStartDate, end: nil, options: .strictStartDate) 80 | let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()]) 81 | let queryPredicate = NSCompoundPredicate(andPredicateWithSubpredicates:[datePredicate, devicePredicate]) 82 | 83 | let updateHandler: ((HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void) = { query, samples, deletedObjects, queryAnchor, error in 84 | } 85 | 86 | let query = HKAnchoredObjectQuery(type: HKObjectType.quantityType(forIdentifier: quantityTypeIdentifier)!, 87 | predicate: queryPredicate, 88 | anchor: nil, 89 | limit: HKObjectQueryNoLimit, 90 | resultsHandler: updateHandler) 91 | query.updateHandler = updateHandler 92 | healthStore.execute(query) 93 | activeDataQueries.append(query) 94 | } 95 | 96 | 97 | func stopAccumulatingData() { 98 | for query in activeDataQueries { 99 | healthStore.stop(query) 100 | } 101 | 102 | activeDataQueries.removeAll() 103 | stopTimer() 104 | } 105 | 106 | func pauseAccumulatingData() { 107 | DispatchQueue.main.sync { 108 | isPaused = true 109 | } 110 | } 111 | 112 | func resumeAccumulatingData() { 113 | DispatchQueue.main.sync { 114 | isPaused = false 115 | } 116 | } 117 | 118 | func stopTimer() { 119 | timer?.invalidate() 120 | } 121 | 122 | func startMotionCapture(){ 123 | 124 | print("Motion capture starting..."); 125 | motionManager.accelerometerUpdateInterval = 1.0/60.0; 126 | print("Set accelerometer update interval..."); 127 | 128 | if (motionManager.isAccelerometerAvailable) { 129 | 130 | print("Creating handler..."); 131 | let handler:CMAccelerometerHandler = {(data: CMAccelerometerData?, error: Error?) -> Void in 132 | 133 | if(data != nil){ 134 | let output : [Double] = [ Date().timeIntervalSince1970, data!.acceleration.x, data!.acceleration.y, data!.acceleration.z] 135 | 136 | // Mutated 137 | self.accelerometerOutput.add(output) 138 | self.counter = self.counter + 1; 139 | 140 | // Size checked 141 | if(self.threshold <= self.counter){ 142 | 143 | print("Time to post..."); 144 | self.counter = 0; 145 | self.accelerometerOutputPost = self.accelerometerOutput.mutableCopy() as! NSMutableArray 146 | self.accelerometerOutput = NSMutableArray() 147 | 148 | self.pushToPhone() 149 | } 150 | } 151 | } 152 | 153 | print("Sending accelerometer updates to queue..."); 154 | motionManager.startAccelerometerUpdates(to: OperationQueue.main, withHandler: handler) 155 | 156 | } 157 | else { 158 | print("No accelerometer available.") 159 | } 160 | } 161 | 162 | func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: Error) { 163 | print("Workout session did fail with error: \(error)") 164 | } 165 | 166 | func workoutSession(_ workoutSession: HKWorkoutSession, didGenerate event: HKWorkoutEvent) { 167 | workoutEvents.append(event) 168 | } 169 | 170 | func workoutSession(_ workoutSession: HKWorkoutSession, 171 | didChangeTo toState: HKWorkoutSessionState, 172 | from fromState: HKWorkoutSessionState, 173 | date: Date) { 174 | switch toState { 175 | case .running: 176 | if fromState == .notStarted { 177 | startAccumulatingData(startDate: workoutStartDate!) 178 | } else { 179 | resumeAccumulatingData() 180 | } 181 | 182 | case .paused: 183 | pauseAccumulatingData() 184 | 185 | case .ended: 186 | stopAccumulatingData() 187 | saveWorkout() 188 | default: 189 | break 190 | } 191 | } 192 | 193 | private func saveWorkout() { 194 | 195 | let configuration = workoutSession!.workoutConfiguration 196 | 197 | let workout = HKWorkout(activityType: configuration.activityType, start: workoutStartDate!, end: workoutEndDate!) 198 | 199 | WKInterfaceController.reloadRootControllers(withNamesAndContexts: [(name: "CompletionInterfaceController", context: [workout] as AnyObject)]) 200 | 201 | } 202 | } 203 | 204 | extension SleepInterfaceController: WCSessionDelegate { 205 | func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { 206 | print("Session activation for HR completed") 207 | } 208 | func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) { 209 | print("Received application context: ", applicationContext) 210 | } 211 | } 212 | 213 | -------------------------------------------------------------------------------- /SleepAccelerometer/MainTableViewController.swift: -------------------------------------------------------------------------------- 1 | 2 | import UIKit 3 | import CoreData 4 | import MessageUI 5 | 6 | class MainTableViewController: UITableViewController,MFMailComposeViewControllerDelegate { 7 | 8 | var savedEvents : [Double] = [] // Holder for saved sleep events 9 | var watchManager : WatchManager? 10 | let HEADER_HEIGHT : CGFloat = 30.0 11 | private let control = UIRefreshControl() 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | getHealthPermissions() 17 | 18 | tableView.refreshControl = control 19 | tableView.refreshControl?.addTarget(self, action: #selector(refreshSleepEvents(_:)), for: .valueChanged) 20 | 21 | Task { 22 | savedEvents = try await SleepEvent.getAllEvents() 23 | DispatchQueue.main.async { [weak self] in 24 | self?.tableView.reloadData() 25 | } 26 | } 27 | 28 | self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white] 29 | } 30 | 31 | func getHealthPermissions(){ 32 | let healthHelper = HealthHelper() 33 | healthHelper.getHealthPermissions() 34 | } 35 | 36 | override func viewWillAppear(_ animated: Bool) { 37 | super.viewWillAppear(true) 38 | Task { 39 | savedEvents = try await SleepEvent.getAllEvents() 40 | 41 | DispatchQueue.main.async { [weak self] in 42 | self?.tableView.reloadData() // Don't forget to reload the tableView to reflect the changes 43 | } 44 | } 45 | } 46 | 47 | @objc private func refreshSleepEvents(_ sender: Any) { 48 | Task { 49 | savedEvents = try await SleepEvent.getAllEvents() 50 | 51 | DispatchQueue.main.async { [weak self] in 52 | self?.tableView.reloadData() 53 | self?.control.endRefreshing() 54 | } 55 | } 56 | } 57 | 58 | override func didReceiveMemoryWarning() { 59 | super.didReceiveMemoryWarning() 60 | } 61 | 62 | override func numberOfSections(in tableView: UITableView) -> Int { 63 | return 1 64 | } 65 | 66 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 67 | return savedEvents.count 68 | } 69 | 70 | override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 71 | 72 | let headerView = UIView() 73 | headerView.backgroundColor = UIColor.darkGray 74 | 75 | let titleLabel = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: tableView.bounds.size.width, height: HEADER_HEIGHT)) 76 | titleLabel.font = UIFont.systemFont(ofSize: 12.0) 77 | titleLabel.textColor = UIColor.white 78 | 79 | let subtitleText = "Select row to export data" 80 | let attributes = [NSAttributedString.Key.kern : 2.0] 81 | titleLabel.attributedText = NSAttributedString(string: subtitleText.uppercased(), attributes: attributes as [NSAttributedString.Key : Any]) 82 | titleLabel.textAlignment = .center 83 | 84 | headerView.addSubview(titleLabel) 85 | 86 | return headerView 87 | } 88 | 89 | override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 90 | return HEADER_HEIGHT 91 | } 92 | 93 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 94 | 95 | let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell", for: indexPath) 96 | cell.textLabel?.text = stringFromEpoch(savedEvents[indexPath.row]) 97 | 98 | return cell 99 | } 100 | 101 | override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 102 | return true 103 | } 104 | 105 | override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 106 | if editingStyle == .delete { 107 | // Retrieve the startTime for the event to be deleted 108 | let startTime = savedEvents[indexPath.row] 109 | tableView.isUserInteractionEnabled = false 110 | 111 | Task { 112 | do { 113 | _ = try await SleepEvent.deleteAccelerationFor(startTime: startTime) 114 | 115 | DispatchQueue.main.async { [weak self] in 116 | guard let self = self else { return } 117 | 118 | self.savedEvents.remove(at: indexPath.row) 119 | tableView.deleteRows(at: [indexPath], with: .fade) 120 | } 121 | } catch { 122 | print("Error deleting sleep event: \(error)") 123 | } 124 | } 125 | // Re-enable user interaction on the main thread after update 126 | DispatchQueue.main.async { 127 | tableView.isUserInteractionEnabled = true 128 | } 129 | } 130 | } 131 | 132 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 133 | // Disable user interaction to prevent further selection 134 | tableView.isUserInteractionEnabled = false 135 | let selectedEvent = savedEvents[indexPath.row] 136 | 137 | Task { 138 | let acceleration = try await SleepEvent.getAccelerationFor(startTime: selectedEvent) 139 | if acceleration.count > 0 { 140 | let heartRateHandler = HeartRateHandler() 141 | let startDate = Date(timeIntervalSince1970: selectedEvent) 142 | let accelItem = acceleration.last 143 | let endDate = Date(timeIntervalSince1970: accelItem?[0] ?? 0) 144 | 145 | let fileNameHR = "\(Int(savedEvents[indexPath.row]))_hr.csv" 146 | let pathHR = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileNameHR) 147 | 148 | // Save HR as a file, then save acceleration and send both as attachments 149 | heartRateHandler.retrieveHeartRate(start: startDate, end: endDate, path: pathHR) { 150 | DispatchQueue.main.async { [weak self] in 151 | // Ensure to re-enable user interaction after the async operation and UI update 152 | self?.tableView.isUserInteractionEnabled = true 153 | 154 | // Call function to handle UI update or further processing 155 | self?.exportMotionAndSendEmail(epochTime: selectedEvent, data: acceleration) 156 | } 157 | } 158 | } else { 159 | // If no acceleration data, re-enable interaction immediately 160 | DispatchQueue.main.async { [weak self] in 161 | self?.tableView.isUserInteractionEnabled = true 162 | } 163 | } 164 | } 165 | } 166 | 167 | func stringFromEpoch(_ epochTime : Double) -> String{ 168 | let date = Date(timeIntervalSince1970: epochTime) 169 | let dateFormatter = DateFormatter() 170 | dateFormatter.dateFormat = "MMM dd YYYY hh:mm a" 171 | let dateString = dateFormatter.string(from: date) 172 | return dateString 173 | } 174 | 175 | func exportMotionAndSendEmail(epochTime: Double, data: [[Double]]){ 176 | 177 | let epochTimeString = "\(Int(epochTime))" 178 | 179 | let fileName = epochTimeString + "_acceleration.csv" // Motion data 180 | let hrFileName = epochTimeString + "_hr.csv" // HR data 181 | 182 | let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName) 183 | let hrPath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(hrFileName) 184 | 185 | var csvText = "Timestamp,x,y,z\n" 186 | 187 | let count = data.count 188 | 189 | if count > 0 { 190 | for i in 0 ..< data.count { 191 | let item = data[i] 192 | let newLine = "\(item[0]),\(item[1]),\(item[2]),\(item[3])\n" 193 | csvText.append(newLine) 194 | } 195 | 196 | do { 197 | try csvText.write(to: path!, atomically: true, encoding: String.Encoding.utf8) 198 | // Uncomment to send email with paths for CSV files 199 | // sendEmail(dateString: stringFromEpoch(epochTime), path: path!, hr_path: hrPath!) 200 | shareData(paths: [path!.absoluteURL, hrPath!.absoluteURL]) 201 | 202 | } catch { 203 | print("Unable to create file") 204 | print("\(error)") 205 | } 206 | 207 | } else { 208 | print("No data to export") 209 | } 210 | } 211 | 212 | func shareData(paths: [URL]) { 213 | var activityItems: [URL] = [] 214 | for path in paths{ 215 | if let _ = NSData(contentsOf: path) { 216 | activityItems.append(path.absoluteURL) 217 | } else { 218 | print("Unable to read file") 219 | } 220 | } 221 | 222 | let activity = UIActivityViewController( 223 | activityItems: activityItems, 224 | applicationActivities: nil 225 | ) 226 | present(activity, animated: true, completion: nil) 227 | } 228 | 229 | // Send email with attached CSV files 230 | func sendEmail(dateString: String, path: URL, hr_path: URL) { 231 | 232 | let composeVC = MFMailComposeViewController() 233 | composeVC.mailComposeDelegate = self 234 | 235 | composeVC.navigationBar.tintColor = .white 236 | composeVC.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white] 237 | 238 | // Configure email 239 | composeVC.setSubject("Sleep event data for " + dateString) 240 | composeVC.setMessageBody("Sleep event data attached as CSV", isHTML: false) 241 | 242 | if let fileData = NSData(contentsOf: path) { 243 | print("Motion data loaded.") 244 | composeVC.addAttachmentData(fileData as Data, mimeType: "text/csv", fileName: "motion_data.csv") 245 | } 246 | 247 | if let fileData = NSData(contentsOf: hr_path) { 248 | print("HR data loaded.") 249 | composeVC.addAttachmentData(fileData as Data, mimeType: "text/csv", fileName: "hr_data.csv") 250 | } 251 | 252 | self.present(composeVC, animated: true, completion: nil) 253 | } 254 | 255 | func mailComposeController(_ controller: MFMailComposeViewController, 256 | didFinishWith result: MFMailComposeResult, error: Error?) { 257 | controller.dismiss(animated: true, completion: nil) 258 | } 259 | 260 | @IBAction func showEditing(sender: UIBarButtonItem) 261 | { 262 | if(self.tableView.isEditing == true) 263 | { 264 | self.tableView.isEditing = false 265 | self.navigationItem.rightBarButtonItem?.title = "Done" 266 | } 267 | else 268 | { 269 | self.tableView.isEditing = true 270 | self.navigationItem.rightBarButtonItem?.title = "Edit" 271 | } 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /SleepAccelerometer.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0223E13620A7A11E00243F2E /* HealthHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0223E13520A7A11E00243F2E /* HealthHelper.m */; }; 11 | 0223E13920A7A2C700243F2E /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0223E13820A7A2C700243F2E /* HealthKit.framework */; }; 12 | 0223E13C20A7A38700243F2E /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0223E13B20A7A38700243F2E /* HealthKit.framework */; }; 13 | 0226842420A9D2D8001C76AB /* WatchConnectivity.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0226842320A9D2D8001C76AB /* WatchConnectivity.framework */; }; 14 | 0226842620A9D59D001C76AB /* WatchConnectivity.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0226842520A9D59D001C76AB /* WatchConnectivity.framework */; }; 15 | 022BFDDD20A7224900A4CE4D /* MainTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022BFDDC20A7224900A4CE4D /* MainTableViewController.swift */; }; 16 | 022BFDDF20A7229500A4CE4D /* SleepEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022BFDDE20A7229500A4CE4D /* SleepEvent.swift */; }; 17 | 022BFDE120A740B100A4CE4D /* ConfigurationInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022BFDE020A740B100A4CE4D /* ConfigurationInterfaceController.swift */; }; 18 | 022BFDE920A757F900A4CE4D /* CompletionInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022BFDE820A757F900A4CE4D /* CompletionInterfaceController.swift */; }; 19 | 022BFDEB20A75A7300A4CE4D /* WatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022BFDEA20A75A7300A4CE4D /* WatchManager.swift */; }; 20 | 02C842EA20CFF95600A7EB3E /* HeartRateHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C842E920CFF95600A7EB3E /* HeartRateHandler.swift */; }; 21 | 02C9480A20A33F550065C296 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C9480920A33F550065C296 /* AppDelegate.swift */; }; 22 | 02C9480F20A33F550065C296 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02C9480D20A33F550065C296 /* Main.storyboard */; }; 23 | 02C9481120A33F580065C296 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 02C9481020A33F580065C296 /* Assets.xcassets */; }; 24 | 02C9481420A33F580065C296 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02C9481220A33F580065C296 /* LaunchScreen.storyboard */; }; 25 | 02C9481F20A33F580065C296 /* SleepAccelerometerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C9481E20A33F580065C296 /* SleepAccelerometerTests.swift */; }; 26 | 02C9482A20A33F580065C296 /* SleepAccelerometerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C9482920A33F580065C296 /* SleepAccelerometerUITests.swift */; }; 27 | 02C9482F20A33F590065C296 /* SleepAccelerometer WatchKit App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 02C9482E20A33F590065C296 /* SleepAccelerometer WatchKit App.app */; }; 28 | 02C9483520A33F590065C296 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 02C9483320A33F590065C296 /* Interface.storyboard */; }; 29 | 02C9483720A33F590065C296 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 02C9483620A33F590065C296 /* Assets.xcassets */; }; 30 | 02C9483E20A33F590065C296 /* SleepAccelerometer WatchKit Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 02C9483D20A33F590065C296 /* SleepAccelerometer WatchKit Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 31 | 02C9484320A33F590065C296 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C9484220A33F590065C296 /* InterfaceController.swift */; }; 32 | 02C9484520A33F590065C296 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C9484420A33F590065C296 /* ExtensionDelegate.swift */; }; 33 | 02C9484720A33F590065C296 /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C9484620A33F590065C296 /* NotificationController.swift */; }; 34 | 02C9484920A33F5A0065C296 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 02C9484820A33F5A0065C296 /* Assets.xcassets */; }; 35 | 02C9486120A33FA60065C296 /* SleepInterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C9486020A33FA60065C296 /* SleepInterfaceController.swift */; }; 36 | 02D8D93B20A777B60003A7C0 /* Data.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 022BFDE520A7550F00A4CE4D /* Data.xcdatamodeld */; }; 37 | 02D8D93D20A777ED0003A7C0 /* MainTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02D8D93C20A777ED0003A7C0 /* MainTableViewCell.swift */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXContainerItemProxy section */ 41 | 02C9481B20A33F580065C296 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = 02C947FE20A33F530065C296 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = 02C9480520A33F540065C296; 46 | remoteInfo = SleepAccelerometer; 47 | }; 48 | 02C9482620A33F580065C296 /* PBXContainerItemProxy */ = { 49 | isa = PBXContainerItemProxy; 50 | containerPortal = 02C947FE20A33F530065C296 /* Project object */; 51 | proxyType = 1; 52 | remoteGlobalIDString = 02C9480520A33F540065C296; 53 | remoteInfo = SleepAccelerometer; 54 | }; 55 | 02C9483020A33F590065C296 /* PBXContainerItemProxy */ = { 56 | isa = PBXContainerItemProxy; 57 | containerPortal = 02C947FE20A33F530065C296 /* Project object */; 58 | proxyType = 1; 59 | remoteGlobalIDString = 02C9482D20A33F580065C296; 60 | remoteInfo = "SleepAccelerometer WatchKit App"; 61 | }; 62 | 02C9483F20A33F590065C296 /* PBXContainerItemProxy */ = { 63 | isa = PBXContainerItemProxy; 64 | containerPortal = 02C947FE20A33F530065C296 /* Project object */; 65 | proxyType = 1; 66 | remoteGlobalIDString = 02C9483C20A33F590065C296; 67 | remoteInfo = "SleepAccelerometer WatchKit Extension"; 68 | }; 69 | /* End PBXContainerItemProxy section */ 70 | 71 | /* Begin PBXCopyFilesBuildPhase section */ 72 | 02C9485120A33F5A0065C296 /* Embed App Extensions */ = { 73 | isa = PBXCopyFilesBuildPhase; 74 | buildActionMask = 2147483647; 75 | dstPath = ""; 76 | dstSubfolderSpec = 13; 77 | files = ( 78 | 02C9483E20A33F590065C296 /* SleepAccelerometer WatchKit Extension.appex in Embed App Extensions */, 79 | ); 80 | name = "Embed App Extensions"; 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | 02C9485520A33F5A0065C296 /* Embed Watch Content */ = { 84 | isa = PBXCopyFilesBuildPhase; 85 | buildActionMask = 2147483647; 86 | dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; 87 | dstSubfolderSpec = 16; 88 | files = ( 89 | 02C9482F20A33F590065C296 /* SleepAccelerometer WatchKit App.app in Embed Watch Content */, 90 | ); 91 | name = "Embed Watch Content"; 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | /* End PBXCopyFilesBuildPhase section */ 95 | 96 | /* Begin PBXFileReference section */ 97 | 0223E13320A7A11D00243F2E /* SleepAccelerometer-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SleepAccelerometer-Bridging-Header.h"; sourceTree = ""; }; 98 | 0223E13420A7A11E00243F2E /* HealthHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HealthHelper.h; sourceTree = ""; }; 99 | 0223E13520A7A11E00243F2E /* HealthHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HealthHelper.m; sourceTree = ""; }; 100 | 0223E13820A7A2C700243F2E /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; 101 | 0223E13A20A7A2C700243F2E /* SleepAccelerometer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SleepAccelerometer.entitlements; sourceTree = ""; }; 102 | 0223E13B20A7A38700243F2E /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS4.3.sdk/System/Library/Frameworks/HealthKit.framework; sourceTree = DEVELOPER_DIR; }; 103 | 0223E13D20A7A38700243F2E /* SleepAccelerometer WatchKit Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "SleepAccelerometer WatchKit Extension.entitlements"; sourceTree = ""; }; 104 | 0226842320A9D2D8001C76AB /* WatchConnectivity.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WatchConnectivity.framework; path = System/Library/Frameworks/WatchConnectivity.framework; sourceTree = SDKROOT; }; 105 | 0226842520A9D59D001C76AB /* WatchConnectivity.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WatchConnectivity.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS4.3.sdk/System/Library/Frameworks/WatchConnectivity.framework; sourceTree = DEVELOPER_DIR; }; 106 | 022BFDDC20A7224900A4CE4D /* MainTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTableViewController.swift; sourceTree = ""; }; 107 | 022BFDDE20A7229500A4CE4D /* SleepEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepEvent.swift; sourceTree = ""; }; 108 | 022BFDE020A740B100A4CE4D /* ConfigurationInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationInterfaceController.swift; sourceTree = ""; }; 109 | 022BFDE620A7550F00A4CE4D /* Data.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Data.xcdatamodel; sourceTree = ""; }; 110 | 022BFDE820A757F900A4CE4D /* CompletionInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletionInterfaceController.swift; sourceTree = ""; }; 111 | 022BFDEA20A75A7300A4CE4D /* WatchManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchManager.swift; sourceTree = ""; }; 112 | 02C842E920CFF95600A7EB3E /* HeartRateHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeartRateHandler.swift; sourceTree = ""; }; 113 | 02C9480620A33F550065C296 /* SleepAccelerometer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SleepAccelerometer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 114 | 02C9480920A33F550065C296 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 115 | 02C9480E20A33F550065C296 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 116 | 02C9481020A33F580065C296 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 117 | 02C9481320A33F580065C296 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 118 | 02C9481520A33F580065C296 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 119 | 02C9481A20A33F580065C296 /* SleepAccelerometerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SleepAccelerometerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 120 | 02C9481E20A33F580065C296 /* SleepAccelerometerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepAccelerometerTests.swift; sourceTree = ""; }; 121 | 02C9482020A33F580065C296 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 122 | 02C9482520A33F580065C296 /* SleepAccelerometerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SleepAccelerometerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 123 | 02C9482920A33F580065C296 /* SleepAccelerometerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepAccelerometerUITests.swift; sourceTree = ""; }; 124 | 02C9482B20A33F580065C296 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 125 | 02C9482E20A33F590065C296 /* SleepAccelerometer WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SleepAccelerometer WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 126 | 02C9483420A33F590065C296 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; 127 | 02C9483620A33F590065C296 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 128 | 02C9483820A33F590065C296 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 129 | 02C9483D20A33F590065C296 /* SleepAccelerometer WatchKit Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SleepAccelerometer WatchKit Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 130 | 02C9484220A33F590065C296 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = ""; }; 131 | 02C9484420A33F590065C296 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; 132 | 02C9484620A33F590065C296 /* NotificationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationController.swift; sourceTree = ""; }; 133 | 02C9484820A33F5A0065C296 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 134 | 02C9484A20A33F5A0065C296 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 135 | 02C9484B20A33F5A0065C296 /* PushNotificationPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushNotificationPayload.apns; sourceTree = ""; }; 136 | 02C9486020A33FA60065C296 /* SleepInterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepInterfaceController.swift; sourceTree = ""; }; 137 | 02D8D93C20A777ED0003A7C0 /* MainTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTableViewCell.swift; sourceTree = ""; }; 138 | /* End PBXFileReference section */ 139 | 140 | /* Begin PBXFrameworksBuildPhase section */ 141 | 02C9480320A33F540065C296 /* Frameworks */ = { 142 | isa = PBXFrameworksBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | 0226842420A9D2D8001C76AB /* WatchConnectivity.framework in Frameworks */, 146 | 0223E13920A7A2C700243F2E /* HealthKit.framework in Frameworks */, 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | }; 150 | 02C9481720A33F580065C296 /* Frameworks */ = { 151 | isa = PBXFrameworksBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | 02C9482220A33F580065C296 /* Frameworks */ = { 158 | isa = PBXFrameworksBuildPhase; 159 | buildActionMask = 2147483647; 160 | files = ( 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | 02C9483A20A33F590065C296 /* Frameworks */ = { 165 | isa = PBXFrameworksBuildPhase; 166 | buildActionMask = 2147483647; 167 | files = ( 168 | 0226842620A9D59D001C76AB /* WatchConnectivity.framework in Frameworks */, 169 | 0223E13C20A7A38700243F2E /* HealthKit.framework in Frameworks */, 170 | ); 171 | runOnlyForDeploymentPostprocessing = 0; 172 | }; 173 | /* End PBXFrameworksBuildPhase section */ 174 | 175 | /* Begin PBXGroup section */ 176 | 0223E13720A7A2C700243F2E /* Frameworks */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 0226842320A9D2D8001C76AB /* WatchConnectivity.framework */, 180 | 0226842520A9D59D001C76AB /* WatchConnectivity.framework */, 181 | 0223E13B20A7A38700243F2E /* HealthKit.framework */, 182 | 0223E13820A7A2C700243F2E /* HealthKit.framework */, 183 | ); 184 | name = Frameworks; 185 | sourceTree = ""; 186 | }; 187 | 02C947FD20A33F530065C296 = { 188 | isa = PBXGroup; 189 | children = ( 190 | 02C9480820A33F550065C296 /* SleepAccelerometer */, 191 | 02C9481D20A33F580065C296 /* SleepAccelerometerTests */, 192 | 02C9482820A33F580065C296 /* SleepAccelerometerUITests */, 193 | 02C9483220A33F590065C296 /* SleepAccelerometer WatchKit App */, 194 | 02C9484120A33F590065C296 /* SleepAccelerometer WatchKit Extension */, 195 | 02C9480720A33F550065C296 /* Products */, 196 | 0223E13720A7A2C700243F2E /* Frameworks */, 197 | ); 198 | sourceTree = ""; 199 | }; 200 | 02C9480720A33F550065C296 /* Products */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 02C9480620A33F550065C296 /* SleepAccelerometer.app */, 204 | 02C9481A20A33F580065C296 /* SleepAccelerometerTests.xctest */, 205 | 02C9482520A33F580065C296 /* SleepAccelerometerUITests.xctest */, 206 | 02C9482E20A33F590065C296 /* SleepAccelerometer WatchKit App.app */, 207 | 02C9483D20A33F590065C296 /* SleepAccelerometer WatchKit Extension.appex */, 208 | ); 209 | name = Products; 210 | sourceTree = ""; 211 | }; 212 | 02C9480820A33F550065C296 /* SleepAccelerometer */ = { 213 | isa = PBXGroup; 214 | children = ( 215 | 0223E13A20A7A2C700243F2E /* SleepAccelerometer.entitlements */, 216 | 0223E13420A7A11E00243F2E /* HealthHelper.h */, 217 | 0223E13520A7A11E00243F2E /* HealthHelper.m */, 218 | 022BFDDC20A7224900A4CE4D /* MainTableViewController.swift */, 219 | 02C842E920CFF95600A7EB3E /* HeartRateHandler.swift */, 220 | 02D8D93C20A777ED0003A7C0 /* MainTableViewCell.swift */, 221 | 022BFDDE20A7229500A4CE4D /* SleepEvent.swift */, 222 | 022BFDEA20A75A7300A4CE4D /* WatchManager.swift */, 223 | 02C9480920A33F550065C296 /* AppDelegate.swift */, 224 | 02C9480D20A33F550065C296 /* Main.storyboard */, 225 | 02C9481020A33F580065C296 /* Assets.xcassets */, 226 | 02C9481220A33F580065C296 /* LaunchScreen.storyboard */, 227 | 02C9481520A33F580065C296 /* Info.plist */, 228 | 022BFDE520A7550F00A4CE4D /* Data.xcdatamodeld */, 229 | 0223E13320A7A11D00243F2E /* SleepAccelerometer-Bridging-Header.h */, 230 | ); 231 | path = SleepAccelerometer; 232 | sourceTree = ""; 233 | }; 234 | 02C9481D20A33F580065C296 /* SleepAccelerometerTests */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | 02C9481E20A33F580065C296 /* SleepAccelerometerTests.swift */, 238 | 02C9482020A33F580065C296 /* Info.plist */, 239 | ); 240 | path = SleepAccelerometerTests; 241 | sourceTree = ""; 242 | }; 243 | 02C9482820A33F580065C296 /* SleepAccelerometerUITests */ = { 244 | isa = PBXGroup; 245 | children = ( 246 | 02C9482920A33F580065C296 /* SleepAccelerometerUITests.swift */, 247 | 02C9482B20A33F580065C296 /* Info.plist */, 248 | ); 249 | path = SleepAccelerometerUITests; 250 | sourceTree = ""; 251 | }; 252 | 02C9483220A33F590065C296 /* SleepAccelerometer WatchKit App */ = { 253 | isa = PBXGroup; 254 | children = ( 255 | 02C9483320A33F590065C296 /* Interface.storyboard */, 256 | 02C9483620A33F590065C296 /* Assets.xcassets */, 257 | 02C9483820A33F590065C296 /* Info.plist */, 258 | ); 259 | path = "SleepAccelerometer WatchKit App"; 260 | sourceTree = ""; 261 | }; 262 | 02C9484120A33F590065C296 /* SleepAccelerometer WatchKit Extension */ = { 263 | isa = PBXGroup; 264 | children = ( 265 | 0223E13D20A7A38700243F2E /* SleepAccelerometer WatchKit Extension.entitlements */, 266 | 02C9484220A33F590065C296 /* InterfaceController.swift */, 267 | 022BFDE820A757F900A4CE4D /* CompletionInterfaceController.swift */, 268 | 02C9484420A33F590065C296 /* ExtensionDelegate.swift */, 269 | 02C9484620A33F590065C296 /* NotificationController.swift */, 270 | 022BFDE020A740B100A4CE4D /* ConfigurationInterfaceController.swift */, 271 | 02C9486020A33FA60065C296 /* SleepInterfaceController.swift */, 272 | 02C9484820A33F5A0065C296 /* Assets.xcassets */, 273 | 02C9484A20A33F5A0065C296 /* Info.plist */, 274 | 02C9484B20A33F5A0065C296 /* PushNotificationPayload.apns */, 275 | ); 276 | path = "SleepAccelerometer WatchKit Extension"; 277 | sourceTree = ""; 278 | }; 279 | /* End PBXGroup section */ 280 | 281 | /* Begin PBXNativeTarget section */ 282 | 02C9480520A33F540065C296 /* SleepAccelerometer */ = { 283 | isa = PBXNativeTarget; 284 | buildConfigurationList = 02C9485620A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometer" */; 285 | buildPhases = ( 286 | 02C9480220A33F540065C296 /* Sources */, 287 | 02C9480320A33F540065C296 /* Frameworks */, 288 | 02C9480420A33F540065C296 /* Resources */, 289 | 02C9485520A33F5A0065C296 /* Embed Watch Content */, 290 | ); 291 | buildRules = ( 292 | ); 293 | dependencies = ( 294 | 02C9483120A33F590065C296 /* PBXTargetDependency */, 295 | ); 296 | name = SleepAccelerometer; 297 | productName = SleepAccelerometer; 298 | productReference = 02C9480620A33F550065C296 /* SleepAccelerometer.app */; 299 | productType = "com.apple.product-type.application"; 300 | }; 301 | 02C9481920A33F580065C296 /* SleepAccelerometerTests */ = { 302 | isa = PBXNativeTarget; 303 | buildConfigurationList = 02C9485920A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometerTests" */; 304 | buildPhases = ( 305 | 02C9481620A33F580065C296 /* Sources */, 306 | 02C9481720A33F580065C296 /* Frameworks */, 307 | 02C9481820A33F580065C296 /* Resources */, 308 | ); 309 | buildRules = ( 310 | ); 311 | dependencies = ( 312 | 02C9481C20A33F580065C296 /* PBXTargetDependency */, 313 | ); 314 | name = SleepAccelerometerTests; 315 | productName = SleepAccelerometerTests; 316 | productReference = 02C9481A20A33F580065C296 /* SleepAccelerometerTests.xctest */; 317 | productType = "com.apple.product-type.bundle.unit-test"; 318 | }; 319 | 02C9482420A33F580065C296 /* SleepAccelerometerUITests */ = { 320 | isa = PBXNativeTarget; 321 | buildConfigurationList = 02C9485C20A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometerUITests" */; 322 | buildPhases = ( 323 | 02C9482120A33F580065C296 /* Sources */, 324 | 02C9482220A33F580065C296 /* Frameworks */, 325 | 02C9482320A33F580065C296 /* Resources */, 326 | ); 327 | buildRules = ( 328 | ); 329 | dependencies = ( 330 | 02C9482720A33F580065C296 /* PBXTargetDependency */, 331 | ); 332 | name = SleepAccelerometerUITests; 333 | productName = SleepAccelerometerUITests; 334 | productReference = 02C9482520A33F580065C296 /* SleepAccelerometerUITests.xctest */; 335 | productType = "com.apple.product-type.bundle.ui-testing"; 336 | }; 337 | 02C9482D20A33F580065C296 /* SleepAccelerometer WatchKit App */ = { 338 | isa = PBXNativeTarget; 339 | buildConfigurationList = 02C9485220A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometer WatchKit App" */; 340 | buildPhases = ( 341 | 02C9482C20A33F580065C296 /* Resources */, 342 | 02C9485120A33F5A0065C296 /* Embed App Extensions */, 343 | ); 344 | buildRules = ( 345 | ); 346 | dependencies = ( 347 | 02C9484020A33F590065C296 /* PBXTargetDependency */, 348 | ); 349 | name = "SleepAccelerometer WatchKit App"; 350 | productName = "SleepAccelerometer WatchKit App"; 351 | productReference = 02C9482E20A33F590065C296 /* SleepAccelerometer WatchKit App.app */; 352 | productType = "com.apple.product-type.application.watchapp2"; 353 | }; 354 | 02C9483C20A33F590065C296 /* SleepAccelerometer WatchKit Extension */ = { 355 | isa = PBXNativeTarget; 356 | buildConfigurationList = 02C9484E20A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometer WatchKit Extension" */; 357 | buildPhases = ( 358 | 02C9483920A33F590065C296 /* Sources */, 359 | 02C9483A20A33F590065C296 /* Frameworks */, 360 | 02C9483B20A33F590065C296 /* Resources */, 361 | ); 362 | buildRules = ( 363 | ); 364 | dependencies = ( 365 | ); 366 | name = "SleepAccelerometer WatchKit Extension"; 367 | productName = "SleepAccelerometer WatchKit Extension"; 368 | productReference = 02C9483D20A33F590065C296 /* SleepAccelerometer WatchKit Extension.appex */; 369 | productType = "com.apple.product-type.watchkit2-extension"; 370 | }; 371 | /* End PBXNativeTarget section */ 372 | 373 | /* Begin PBXProject section */ 374 | 02C947FE20A33F530065C296 /* Project object */ = { 375 | isa = PBXProject; 376 | attributes = { 377 | LastSwiftUpdateCheck = 0930; 378 | LastUpgradeCheck = 0930; 379 | ORGANIZATIONNAME = "Olivia Walch"; 380 | TargetAttributes = { 381 | 02C9480520A33F540065C296 = { 382 | CreatedOnToolsVersion = 9.3; 383 | LastSwiftMigration = 1520; 384 | SystemCapabilities = { 385 | com.apple.HealthKit = { 386 | enabled = 1; 387 | }; 388 | }; 389 | }; 390 | 02C9481920A33F580065C296 = { 391 | CreatedOnToolsVersion = 9.3; 392 | LastSwiftMigration = 1520; 393 | TestTargetID = 02C9480520A33F540065C296; 394 | }; 395 | 02C9482420A33F580065C296 = { 396 | CreatedOnToolsVersion = 9.3; 397 | LastSwiftMigration = 1520; 398 | TestTargetID = 02C9480520A33F540065C296; 399 | }; 400 | 02C9482D20A33F580065C296 = { 401 | CreatedOnToolsVersion = 9.3; 402 | }; 403 | 02C9483C20A33F590065C296 = { 404 | CreatedOnToolsVersion = 9.3; 405 | LastSwiftMigration = 1520; 406 | SystemCapabilities = { 407 | com.apple.HealthKit.watchos = { 408 | enabled = 1; 409 | }; 410 | }; 411 | }; 412 | }; 413 | }; 414 | buildConfigurationList = 02C9480120A33F540065C296 /* Build configuration list for PBXProject "SleepAccelerometer" */; 415 | compatibilityVersion = "Xcode 9.3"; 416 | developmentRegion = en; 417 | hasScannedForEncodings = 0; 418 | knownRegions = ( 419 | en, 420 | Base, 421 | ); 422 | mainGroup = 02C947FD20A33F530065C296; 423 | productRefGroup = 02C9480720A33F550065C296 /* Products */; 424 | projectDirPath = ""; 425 | projectRoot = ""; 426 | targets = ( 427 | 02C9480520A33F540065C296 /* SleepAccelerometer */, 428 | 02C9481920A33F580065C296 /* SleepAccelerometerTests */, 429 | 02C9482420A33F580065C296 /* SleepAccelerometerUITests */, 430 | 02C9482D20A33F580065C296 /* SleepAccelerometer WatchKit App */, 431 | 02C9483C20A33F590065C296 /* SleepAccelerometer WatchKit Extension */, 432 | ); 433 | }; 434 | /* End PBXProject section */ 435 | 436 | /* Begin PBXResourcesBuildPhase section */ 437 | 02C9480420A33F540065C296 /* Resources */ = { 438 | isa = PBXResourcesBuildPhase; 439 | buildActionMask = 2147483647; 440 | files = ( 441 | 02C9481420A33F580065C296 /* LaunchScreen.storyboard in Resources */, 442 | 02C9481120A33F580065C296 /* Assets.xcassets in Resources */, 443 | 02C9480F20A33F550065C296 /* Main.storyboard in Resources */, 444 | ); 445 | runOnlyForDeploymentPostprocessing = 0; 446 | }; 447 | 02C9481820A33F580065C296 /* Resources */ = { 448 | isa = PBXResourcesBuildPhase; 449 | buildActionMask = 2147483647; 450 | files = ( 451 | ); 452 | runOnlyForDeploymentPostprocessing = 0; 453 | }; 454 | 02C9482320A33F580065C296 /* Resources */ = { 455 | isa = PBXResourcesBuildPhase; 456 | buildActionMask = 2147483647; 457 | files = ( 458 | ); 459 | runOnlyForDeploymentPostprocessing = 0; 460 | }; 461 | 02C9482C20A33F580065C296 /* Resources */ = { 462 | isa = PBXResourcesBuildPhase; 463 | buildActionMask = 2147483647; 464 | files = ( 465 | 02C9483720A33F590065C296 /* Assets.xcassets in Resources */, 466 | 02C9483520A33F590065C296 /* Interface.storyboard in Resources */, 467 | ); 468 | runOnlyForDeploymentPostprocessing = 0; 469 | }; 470 | 02C9483B20A33F590065C296 /* Resources */ = { 471 | isa = PBXResourcesBuildPhase; 472 | buildActionMask = 2147483647; 473 | files = ( 474 | 02C9484920A33F5A0065C296 /* Assets.xcassets in Resources */, 475 | ); 476 | runOnlyForDeploymentPostprocessing = 0; 477 | }; 478 | /* End PBXResourcesBuildPhase section */ 479 | 480 | /* Begin PBXSourcesBuildPhase section */ 481 | 02C9480220A33F540065C296 /* Sources */ = { 482 | isa = PBXSourcesBuildPhase; 483 | buildActionMask = 2147483647; 484 | files = ( 485 | 022BFDEB20A75A7300A4CE4D /* WatchManager.swift in Sources */, 486 | 0223E13620A7A11E00243F2E /* HealthHelper.m in Sources */, 487 | 022BFDDD20A7224900A4CE4D /* MainTableViewController.swift in Sources */, 488 | 02D8D93B20A777B60003A7C0 /* Data.xcdatamodeld in Sources */, 489 | 022BFDDF20A7229500A4CE4D /* SleepEvent.swift in Sources */, 490 | 02C842EA20CFF95600A7EB3E /* HeartRateHandler.swift in Sources */, 491 | 02D8D93D20A777ED0003A7C0 /* MainTableViewCell.swift in Sources */, 492 | 02C9480A20A33F550065C296 /* AppDelegate.swift in Sources */, 493 | ); 494 | runOnlyForDeploymentPostprocessing = 0; 495 | }; 496 | 02C9481620A33F580065C296 /* Sources */ = { 497 | isa = PBXSourcesBuildPhase; 498 | buildActionMask = 2147483647; 499 | files = ( 500 | 02C9481F20A33F580065C296 /* SleepAccelerometerTests.swift in Sources */, 501 | ); 502 | runOnlyForDeploymentPostprocessing = 0; 503 | }; 504 | 02C9482120A33F580065C296 /* Sources */ = { 505 | isa = PBXSourcesBuildPhase; 506 | buildActionMask = 2147483647; 507 | files = ( 508 | 02C9482A20A33F580065C296 /* SleepAccelerometerUITests.swift in Sources */, 509 | ); 510 | runOnlyForDeploymentPostprocessing = 0; 511 | }; 512 | 02C9483920A33F590065C296 /* Sources */ = { 513 | isa = PBXSourcesBuildPhase; 514 | buildActionMask = 2147483647; 515 | files = ( 516 | 02C9484720A33F590065C296 /* NotificationController.swift in Sources */, 517 | 02C9484520A33F590065C296 /* ExtensionDelegate.swift in Sources */, 518 | 022BFDE920A757F900A4CE4D /* CompletionInterfaceController.swift in Sources */, 519 | 022BFDE120A740B100A4CE4D /* ConfigurationInterfaceController.swift in Sources */, 520 | 02C9484320A33F590065C296 /* InterfaceController.swift in Sources */, 521 | 02C9486120A33FA60065C296 /* SleepInterfaceController.swift in Sources */, 522 | ); 523 | runOnlyForDeploymentPostprocessing = 0; 524 | }; 525 | /* End PBXSourcesBuildPhase section */ 526 | 527 | /* Begin PBXTargetDependency section */ 528 | 02C9481C20A33F580065C296 /* PBXTargetDependency */ = { 529 | isa = PBXTargetDependency; 530 | target = 02C9480520A33F540065C296 /* SleepAccelerometer */; 531 | targetProxy = 02C9481B20A33F580065C296 /* PBXContainerItemProxy */; 532 | }; 533 | 02C9482720A33F580065C296 /* PBXTargetDependency */ = { 534 | isa = PBXTargetDependency; 535 | target = 02C9480520A33F540065C296 /* SleepAccelerometer */; 536 | targetProxy = 02C9482620A33F580065C296 /* PBXContainerItemProxy */; 537 | }; 538 | 02C9483120A33F590065C296 /* PBXTargetDependency */ = { 539 | isa = PBXTargetDependency; 540 | target = 02C9482D20A33F580065C296 /* SleepAccelerometer WatchKit App */; 541 | targetProxy = 02C9483020A33F590065C296 /* PBXContainerItemProxy */; 542 | }; 543 | 02C9484020A33F590065C296 /* PBXTargetDependency */ = { 544 | isa = PBXTargetDependency; 545 | target = 02C9483C20A33F590065C296 /* SleepAccelerometer WatchKit Extension */; 546 | targetProxy = 02C9483F20A33F590065C296 /* PBXContainerItemProxy */; 547 | }; 548 | /* End PBXTargetDependency section */ 549 | 550 | /* Begin PBXVariantGroup section */ 551 | 02C9480D20A33F550065C296 /* Main.storyboard */ = { 552 | isa = PBXVariantGroup; 553 | children = ( 554 | 02C9480E20A33F550065C296 /* Base */, 555 | ); 556 | name = Main.storyboard; 557 | sourceTree = ""; 558 | }; 559 | 02C9481220A33F580065C296 /* LaunchScreen.storyboard */ = { 560 | isa = PBXVariantGroup; 561 | children = ( 562 | 02C9481320A33F580065C296 /* Base */, 563 | ); 564 | name = LaunchScreen.storyboard; 565 | sourceTree = ""; 566 | }; 567 | 02C9483320A33F590065C296 /* Interface.storyboard */ = { 568 | isa = PBXVariantGroup; 569 | children = ( 570 | 02C9483420A33F590065C296 /* Base */, 571 | ); 572 | name = Interface.storyboard; 573 | sourceTree = ""; 574 | }; 575 | /* End PBXVariantGroup section */ 576 | 577 | /* Begin XCBuildConfiguration section */ 578 | 02C9484C20A33F5A0065C296 /* Debug */ = { 579 | isa = XCBuildConfiguration; 580 | buildSettings = { 581 | ALWAYS_SEARCH_USER_PATHS = NO; 582 | CLANG_ANALYZER_NONNULL = YES; 583 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 584 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 585 | CLANG_CXX_LIBRARY = "libc++"; 586 | CLANG_ENABLE_MODULES = YES; 587 | CLANG_ENABLE_OBJC_ARC = YES; 588 | CLANG_ENABLE_OBJC_WEAK = YES; 589 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 590 | CLANG_WARN_BOOL_CONVERSION = YES; 591 | CLANG_WARN_COMMA = YES; 592 | CLANG_WARN_CONSTANT_CONVERSION = YES; 593 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 594 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 595 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 596 | CLANG_WARN_EMPTY_BODY = YES; 597 | CLANG_WARN_ENUM_CONVERSION = YES; 598 | CLANG_WARN_INFINITE_RECURSION = YES; 599 | CLANG_WARN_INT_CONVERSION = YES; 600 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 601 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 602 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 603 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 604 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 605 | CLANG_WARN_STRICT_PROTOTYPES = YES; 606 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 607 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 608 | CLANG_WARN_UNREACHABLE_CODE = YES; 609 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 610 | CODE_SIGN_IDENTITY = "iPhone Developer"; 611 | COPY_PHASE_STRIP = NO; 612 | DEBUG_INFORMATION_FORMAT = dwarf; 613 | ENABLE_STRICT_OBJC_MSGSEND = YES; 614 | ENABLE_TESTABILITY = YES; 615 | GCC_C_LANGUAGE_STANDARD = gnu11; 616 | GCC_DYNAMIC_NO_PIC = NO; 617 | GCC_NO_COMMON_BLOCKS = YES; 618 | GCC_OPTIMIZATION_LEVEL = 0; 619 | GCC_PREPROCESSOR_DEFINITIONS = ( 620 | "DEBUG=1", 621 | "$(inherited)", 622 | ); 623 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 624 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 625 | GCC_WARN_UNDECLARED_SELECTOR = YES; 626 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 627 | GCC_WARN_UNUSED_FUNCTION = YES; 628 | GCC_WARN_UNUSED_VARIABLE = YES; 629 | IPHONEOS_DEPLOYMENT_TARGET = 14.1; 630 | MTL_ENABLE_DEBUG_INFO = YES; 631 | ONLY_ACTIVE_ARCH = YES; 632 | SDKROOT = iphoneos; 633 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 634 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 635 | }; 636 | name = Debug; 637 | }; 638 | 02C9484D20A33F5A0065C296 /* Release */ = { 639 | isa = XCBuildConfiguration; 640 | buildSettings = { 641 | ALWAYS_SEARCH_USER_PATHS = NO; 642 | CLANG_ANALYZER_NONNULL = YES; 643 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 644 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 645 | CLANG_CXX_LIBRARY = "libc++"; 646 | CLANG_ENABLE_MODULES = YES; 647 | CLANG_ENABLE_OBJC_ARC = YES; 648 | CLANG_ENABLE_OBJC_WEAK = YES; 649 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 650 | CLANG_WARN_BOOL_CONVERSION = YES; 651 | CLANG_WARN_COMMA = YES; 652 | CLANG_WARN_CONSTANT_CONVERSION = YES; 653 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 654 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 655 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 656 | CLANG_WARN_EMPTY_BODY = YES; 657 | CLANG_WARN_ENUM_CONVERSION = YES; 658 | CLANG_WARN_INFINITE_RECURSION = YES; 659 | CLANG_WARN_INT_CONVERSION = YES; 660 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 661 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 662 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 663 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 664 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 665 | CLANG_WARN_STRICT_PROTOTYPES = YES; 666 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 667 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 668 | CLANG_WARN_UNREACHABLE_CODE = YES; 669 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 670 | CODE_SIGN_IDENTITY = "iPhone Developer"; 671 | COPY_PHASE_STRIP = NO; 672 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 673 | ENABLE_NS_ASSERTIONS = NO; 674 | ENABLE_STRICT_OBJC_MSGSEND = YES; 675 | GCC_C_LANGUAGE_STANDARD = gnu11; 676 | GCC_NO_COMMON_BLOCKS = YES; 677 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 678 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 679 | GCC_WARN_UNDECLARED_SELECTOR = YES; 680 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 681 | GCC_WARN_UNUSED_FUNCTION = YES; 682 | GCC_WARN_UNUSED_VARIABLE = YES; 683 | IPHONEOS_DEPLOYMENT_TARGET = 14.1; 684 | MTL_ENABLE_DEBUG_INFO = NO; 685 | SDKROOT = iphoneos; 686 | SWIFT_COMPILATION_MODE = wholemodule; 687 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 688 | VALIDATE_PRODUCT = YES; 689 | }; 690 | name = Release; 691 | }; 692 | 02C9484F20A33F5A0065C296 /* Debug */ = { 693 | isa = XCBuildConfiguration; 694 | buildSettings = { 695 | ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; 696 | CODE_SIGN_ENTITLEMENTS = "SleepAccelerometer WatchKit Extension/SleepAccelerometer WatchKit Extension.entitlements"; 697 | CODE_SIGN_STYLE = Automatic; 698 | CURRENT_PROJECT_VERSION = 6; 699 | DEVELOPMENT_TEAM = VKLYFF6299; 700 | INFOPLIST_FILE = "SleepAccelerometer WatchKit Extension/Info.plist"; 701 | LD_RUNPATH_SEARCH_PATHS = ( 702 | "$(inherited)", 703 | "@executable_path/Frameworks", 704 | "@executable_path/../../Frameworks", 705 | ); 706 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometer.watchkitapp.watchkitextension; 707 | PRODUCT_NAME = "${TARGET_NAME}"; 708 | SDKROOT = watchos; 709 | SKIP_INSTALL = YES; 710 | SWIFT_VERSION = 5.0; 711 | TARGETED_DEVICE_FAMILY = 4; 712 | WATCHOS_DEPLOYMENT_TARGET = 6.0; 713 | }; 714 | name = Debug; 715 | }; 716 | 02C9485020A33F5A0065C296 /* Release */ = { 717 | isa = XCBuildConfiguration; 718 | buildSettings = { 719 | ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; 720 | CODE_SIGN_ENTITLEMENTS = "SleepAccelerometer WatchKit Extension/SleepAccelerometer WatchKit Extension.entitlements"; 721 | CODE_SIGN_STYLE = Automatic; 722 | CURRENT_PROJECT_VERSION = 6; 723 | DEVELOPMENT_TEAM = VKLYFF6299; 724 | INFOPLIST_FILE = "SleepAccelerometer WatchKit Extension/Info.plist"; 725 | LD_RUNPATH_SEARCH_PATHS = ( 726 | "$(inherited)", 727 | "@executable_path/Frameworks", 728 | "@executable_path/../../Frameworks", 729 | ); 730 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometer.watchkitapp.watchkitextension; 731 | PRODUCT_NAME = "${TARGET_NAME}"; 732 | SDKROOT = watchos; 733 | SKIP_INSTALL = YES; 734 | SWIFT_VERSION = 5.0; 735 | TARGETED_DEVICE_FAMILY = 4; 736 | WATCHOS_DEPLOYMENT_TARGET = 6.0; 737 | }; 738 | name = Release; 739 | }; 740 | 02C9485320A33F5A0065C296 /* Debug */ = { 741 | isa = XCBuildConfiguration; 742 | buildSettings = { 743 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 744 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 745 | CODE_SIGN_STYLE = Automatic; 746 | CURRENT_PROJECT_VERSION = 6; 747 | DEVELOPMENT_TEAM = VKLYFF6299; 748 | IBSC_MODULE = SleepAccelerometer_WatchKit_Extension; 749 | INFOPLIST_FILE = "SleepAccelerometer WatchKit App/Info.plist"; 750 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometer.watchkitapp; 751 | PRODUCT_NAME = "$(TARGET_NAME)"; 752 | SDKROOT = watchos; 753 | SKIP_INSTALL = YES; 754 | SWIFT_VERSION = 4.0; 755 | TARGETED_DEVICE_FAMILY = 4; 756 | WATCHOS_DEPLOYMENT_TARGET = 6.0; 757 | }; 758 | name = Debug; 759 | }; 760 | 02C9485420A33F5A0065C296 /* Release */ = { 761 | isa = XCBuildConfiguration; 762 | buildSettings = { 763 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 764 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 765 | CODE_SIGN_STYLE = Automatic; 766 | CURRENT_PROJECT_VERSION = 6; 767 | DEVELOPMENT_TEAM = VKLYFF6299; 768 | IBSC_MODULE = SleepAccelerometer_WatchKit_Extension; 769 | INFOPLIST_FILE = "SleepAccelerometer WatchKit App/Info.plist"; 770 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometer.watchkitapp; 771 | PRODUCT_NAME = "$(TARGET_NAME)"; 772 | SDKROOT = watchos; 773 | SKIP_INSTALL = YES; 774 | SWIFT_VERSION = 4.0; 775 | TARGETED_DEVICE_FAMILY = 4; 776 | WATCHOS_DEPLOYMENT_TARGET = 6.0; 777 | }; 778 | name = Release; 779 | }; 780 | 02C9485720A33F5A0065C296 /* Debug */ = { 781 | isa = XCBuildConfiguration; 782 | buildSettings = { 783 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 784 | CLANG_ENABLE_MODULES = YES; 785 | CODE_SIGN_ENTITLEMENTS = SleepAccelerometer/SleepAccelerometer.entitlements; 786 | CODE_SIGN_STYLE = Automatic; 787 | CURRENT_PROJECT_VERSION = 6; 788 | DEVELOPMENT_TEAM = VKLYFF6299; 789 | INFOPLIST_FILE = SleepAccelerometer/Info.plist; 790 | IPHONEOS_DEPLOYMENT_TARGET = 15; 791 | LD_RUNPATH_SEARCH_PATHS = ( 792 | "$(inherited)", 793 | "@executable_path/Frameworks", 794 | ); 795 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometer; 796 | PRODUCT_NAME = "$(TARGET_NAME)"; 797 | SWIFT_OBJC_BRIDGING_HEADER = "SleepAccelerometer/SleepAccelerometer-Bridging-Header.h"; 798 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 799 | SWIFT_VERSION = 5.0; 800 | TARGETED_DEVICE_FAMILY = "1,2"; 801 | }; 802 | name = Debug; 803 | }; 804 | 02C9485820A33F5A0065C296 /* Release */ = { 805 | isa = XCBuildConfiguration; 806 | buildSettings = { 807 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 808 | CLANG_ENABLE_MODULES = YES; 809 | CODE_SIGN_ENTITLEMENTS = SleepAccelerometer/SleepAccelerometer.entitlements; 810 | CODE_SIGN_STYLE = Automatic; 811 | CURRENT_PROJECT_VERSION = 6; 812 | DEVELOPMENT_TEAM = VKLYFF6299; 813 | INFOPLIST_FILE = SleepAccelerometer/Info.plist; 814 | IPHONEOS_DEPLOYMENT_TARGET = 15; 815 | LD_RUNPATH_SEARCH_PATHS = ( 816 | "$(inherited)", 817 | "@executable_path/Frameworks", 818 | ); 819 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometer; 820 | PRODUCT_NAME = "$(TARGET_NAME)"; 821 | SWIFT_OBJC_BRIDGING_HEADER = "SleepAccelerometer/SleepAccelerometer-Bridging-Header.h"; 822 | SWIFT_VERSION = 5.0; 823 | TARGETED_DEVICE_FAMILY = "1,2"; 824 | }; 825 | name = Release; 826 | }; 827 | 02C9485A20A33F5A0065C296 /* Debug */ = { 828 | isa = XCBuildConfiguration; 829 | buildSettings = { 830 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 831 | BUNDLE_LOADER = "$(TEST_HOST)"; 832 | CODE_SIGN_STYLE = Automatic; 833 | DEVELOPMENT_TEAM = W876MUHJ9H; 834 | INFOPLIST_FILE = SleepAccelerometerTests/Info.plist; 835 | IPHONEOS_DEPLOYMENT_TARGET = 15; 836 | LD_RUNPATH_SEARCH_PATHS = ( 837 | "$(inherited)", 838 | "@executable_path/Frameworks", 839 | "@loader_path/Frameworks", 840 | ); 841 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometerTests; 842 | PRODUCT_NAME = "$(TARGET_NAME)"; 843 | SWIFT_VERSION = 5.0; 844 | TARGETED_DEVICE_FAMILY = "1,2"; 845 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SleepAccelerometer.app/SleepAccelerometer"; 846 | }; 847 | name = Debug; 848 | }; 849 | 02C9485B20A33F5A0065C296 /* Release */ = { 850 | isa = XCBuildConfiguration; 851 | buildSettings = { 852 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 853 | BUNDLE_LOADER = "$(TEST_HOST)"; 854 | CODE_SIGN_STYLE = Automatic; 855 | DEVELOPMENT_TEAM = W876MUHJ9H; 856 | INFOPLIST_FILE = SleepAccelerometerTests/Info.plist; 857 | IPHONEOS_DEPLOYMENT_TARGET = 15; 858 | LD_RUNPATH_SEARCH_PATHS = ( 859 | "$(inherited)", 860 | "@executable_path/Frameworks", 861 | "@loader_path/Frameworks", 862 | ); 863 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometerTests; 864 | PRODUCT_NAME = "$(TARGET_NAME)"; 865 | SWIFT_VERSION = 5.0; 866 | TARGETED_DEVICE_FAMILY = "1,2"; 867 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SleepAccelerometer.app/SleepAccelerometer"; 868 | }; 869 | name = Release; 870 | }; 871 | 02C9485D20A33F5A0065C296 /* Debug */ = { 872 | isa = XCBuildConfiguration; 873 | buildSettings = { 874 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 875 | CODE_SIGN_STYLE = Automatic; 876 | DEVELOPMENT_TEAM = W876MUHJ9H; 877 | INFOPLIST_FILE = SleepAccelerometerUITests/Info.plist; 878 | IPHONEOS_DEPLOYMENT_TARGET = 15; 879 | LD_RUNPATH_SEARCH_PATHS = ( 880 | "$(inherited)", 881 | "@executable_path/Frameworks", 882 | "@loader_path/Frameworks", 883 | ); 884 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometerUITests; 885 | PRODUCT_NAME = "$(TARGET_NAME)"; 886 | SWIFT_VERSION = 5.0; 887 | TARGETED_DEVICE_FAMILY = "1,2"; 888 | TEST_TARGET_NAME = SleepAccelerometer; 889 | }; 890 | name = Debug; 891 | }; 892 | 02C9485E20A33F5A0065C296 /* Release */ = { 893 | isa = XCBuildConfiguration; 894 | buildSettings = { 895 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 896 | CODE_SIGN_STYLE = Automatic; 897 | DEVELOPMENT_TEAM = W876MUHJ9H; 898 | INFOPLIST_FILE = SleepAccelerometerUITests/Info.plist; 899 | IPHONEOS_DEPLOYMENT_TARGET = 15; 900 | LD_RUNPATH_SEARCH_PATHS = ( 901 | "$(inherited)", 902 | "@executable_path/Frameworks", 903 | "@loader_path/Frameworks", 904 | ); 905 | PRODUCT_BUNDLE_IDENTIFIER = com.arcascope.SleepAccelerometerUITests; 906 | PRODUCT_NAME = "$(TARGET_NAME)"; 907 | SWIFT_VERSION = 5.0; 908 | TARGETED_DEVICE_FAMILY = "1,2"; 909 | TEST_TARGET_NAME = SleepAccelerometer; 910 | }; 911 | name = Release; 912 | }; 913 | /* End XCBuildConfiguration section */ 914 | 915 | /* Begin XCConfigurationList section */ 916 | 02C9480120A33F540065C296 /* Build configuration list for PBXProject "SleepAccelerometer" */ = { 917 | isa = XCConfigurationList; 918 | buildConfigurations = ( 919 | 02C9484C20A33F5A0065C296 /* Debug */, 920 | 02C9484D20A33F5A0065C296 /* Release */, 921 | ); 922 | defaultConfigurationIsVisible = 0; 923 | defaultConfigurationName = Release; 924 | }; 925 | 02C9484E20A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometer WatchKit Extension" */ = { 926 | isa = XCConfigurationList; 927 | buildConfigurations = ( 928 | 02C9484F20A33F5A0065C296 /* Debug */, 929 | 02C9485020A33F5A0065C296 /* Release */, 930 | ); 931 | defaultConfigurationIsVisible = 0; 932 | defaultConfigurationName = Release; 933 | }; 934 | 02C9485220A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometer WatchKit App" */ = { 935 | isa = XCConfigurationList; 936 | buildConfigurations = ( 937 | 02C9485320A33F5A0065C296 /* Debug */, 938 | 02C9485420A33F5A0065C296 /* Release */, 939 | ); 940 | defaultConfigurationIsVisible = 0; 941 | defaultConfigurationName = Release; 942 | }; 943 | 02C9485620A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometer" */ = { 944 | isa = XCConfigurationList; 945 | buildConfigurations = ( 946 | 02C9485720A33F5A0065C296 /* Debug */, 947 | 02C9485820A33F5A0065C296 /* Release */, 948 | ); 949 | defaultConfigurationIsVisible = 0; 950 | defaultConfigurationName = Release; 951 | }; 952 | 02C9485920A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometerTests" */ = { 953 | isa = XCConfigurationList; 954 | buildConfigurations = ( 955 | 02C9485A20A33F5A0065C296 /* Debug */, 956 | 02C9485B20A33F5A0065C296 /* Release */, 957 | ); 958 | defaultConfigurationIsVisible = 0; 959 | defaultConfigurationName = Release; 960 | }; 961 | 02C9485C20A33F5A0065C296 /* Build configuration list for PBXNativeTarget "SleepAccelerometerUITests" */ = { 962 | isa = XCConfigurationList; 963 | buildConfigurations = ( 964 | 02C9485D20A33F5A0065C296 /* Debug */, 965 | 02C9485E20A33F5A0065C296 /* Release */, 966 | ); 967 | defaultConfigurationIsVisible = 0; 968 | defaultConfigurationName = Release; 969 | }; 970 | /* End XCConfigurationList section */ 971 | 972 | /* Begin XCVersionGroup section */ 973 | 022BFDE520A7550F00A4CE4D /* Data.xcdatamodeld */ = { 974 | isa = XCVersionGroup; 975 | children = ( 976 | 022BFDE620A7550F00A4CE4D /* Data.xcdatamodel */, 977 | ); 978 | currentVersion = 022BFDE620A7550F00A4CE4D /* Data.xcdatamodel */; 979 | path = Data.xcdatamodeld; 980 | sourceTree = ""; 981 | versionGroupType = wrapper.xcdatamodel; 982 | }; 983 | /* End XCVersionGroup section */ 984 | }; 985 | rootObject = 02C947FE20A33F530065C296 /* Project object */; 986 | } 987 | --------------------------------------------------------------------------------