diff --git a/.DS_Store b/.DS_Store index 0f86a04..22e985f 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/FoodForThought.xcodeproj/project.pbxproj b/FoodForThought.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index aa2e263..9843d76 --- a/FoodForThought.xcodeproj/project.pbxproj +++ b/FoodForThought.xcodeproj/project.pbxproj @@ -7,6 +7,18 @@ objects = { /* Begin PBXBuildFile section */ + DF47C74C20E69A3E002F1D8A /* MealTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF47C74B20E69A3E002F1D8A /* MealTableViewCell.swift */; }; + DF47C74E20E69F8A002F1D8A /* ScheduledMeal.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF47C74D20E69F8A002F1D8A /* ScheduledMeal.swift */; }; + DF707BC020F68ABF006B611A /* StartMealViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF707BBF20F68ABF006B611A /* StartMealViewController.swift */; }; + DF76E74120F6A85700AE5236 /* InMealViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF76E74020F6A85700AE5236 /* InMealViewController.swift */; }; + DF86C5E720ED5FA5001F3778 /* MusicController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF86C5E620ED5FA4001F3778 /* MusicController.swift */; }; + DFA39A1620E80AAE00E54064 /* MealTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFA39A1520E80AAE00E54064 /* MealTableViewController.swift */; }; + DFE0DACC20E56628000D63E1 /* MealProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFE0DACB20E56628000D63E1 /* MealProfileViewController.swift */; }; + DFECD16D20ED70D000515451 /* Kiss The Rain.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = DFECD16920ED70D000515451 /* Kiss The Rain.mp3 */; }; + DFECD16E20ED70D000515451 /* m.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = DFECD16A20ED70D000515451 /* m.mp3 */; }; + DFECD16F20ED70D000515451 /* October.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = DFECD16B20ED70D000515451 /* October.mp3 */; }; + DFECD17020ED70D000515451 /* The Truth That You Leave.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = DFECD16C20ED70D000515451 /* The Truth That You Leave.mp3 */; }; + DFECD17220ED732300515451 /* mealProfile.xml in Resources */ = {isa = PBXBuildFile; fileRef = DFECD17120ED732300515451 /* mealProfile.xml */; }; F632C3F820E48DD0005D5805 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F632C3F720E48DD0005D5805 /* AppDelegate.swift */; }; F632C3FA20E48DD0005D5805 /* FirstViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F632C3F920E48DD0005D5805 /* FirstViewController.swift */; }; F632C3FC20E48DD0005D5805 /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F632C3FB20E48DD0005D5805 /* SecondViewController.swift */; }; @@ -35,6 +47,18 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + DF47C74B20E69A3E002F1D8A /* MealTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealTableViewCell.swift; sourceTree = ""; }; + DF47C74D20E69F8A002F1D8A /* ScheduledMeal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScheduledMeal.swift; sourceTree = ""; }; + DF707BBF20F68ABF006B611A /* StartMealViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartMealViewController.swift; sourceTree = ""; }; + DF76E74020F6A85700AE5236 /* InMealViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InMealViewController.swift; sourceTree = ""; }; + DF86C5E620ED5FA4001F3778 /* MusicController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MusicController.swift; sourceTree = ""; }; + DFA39A1520E80AAE00E54064 /* MealTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealTableViewController.swift; sourceTree = ""; }; + DFE0DACB20E56628000D63E1 /* MealProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MealProfileViewController.swift; sourceTree = ""; }; + DFECD16920ED70D000515451 /* Kiss The Rain.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "Kiss The Rain.mp3"; sourceTree = ""; }; + DFECD16A20ED70D000515451 /* m.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = m.mp3; sourceTree = ""; }; + DFECD16B20ED70D000515451 /* October.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = October.mp3; sourceTree = ""; }; + DFECD16C20ED70D000515451 /* The Truth That You Leave.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "The Truth That You Leave.mp3"; sourceTree = ""; }; + DFECD17120ED732300515451 /* mealProfile.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = mealProfile.xml; sourceTree = ""; }; F632C3F420E48DD0005D5805 /* FoodForThought.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FoodForThought.app; sourceTree = BUILT_PRODUCTS_DIR; }; F632C3F720E48DD0005D5805 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; F632C3F920E48DD0005D5805 /* FirstViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstViewController.swift; sourceTree = ""; }; @@ -76,6 +100,17 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + DFECD16820ED70D000515451 /* Music */ = { + isa = PBXGroup; + children = ( + DFECD16920ED70D000515451 /* Kiss The Rain.mp3 */, + DFECD16A20ED70D000515451 /* m.mp3 */, + DFECD16B20ED70D000515451 /* October.mp3 */, + DFECD16C20ED70D000515451 /* The Truth That You Leave.mp3 */, + ); + path = Music; + sourceTree = ""; + }; F632C3EB20E48DD0005D5805 = { isa = PBXGroup; children = ( @@ -99,13 +134,22 @@ F632C3F620E48DD0005D5805 /* FoodForThought */ = { isa = PBXGroup; children = ( + DFECD17120ED732300515451 /* mealProfile.xml */, + DFECD16820ED70D000515451 /* Music */, F632C3F720E48DD0005D5805 /* AppDelegate.swift */, F632C3F920E48DD0005D5805 /* FirstViewController.swift */, F632C3FB20E48DD0005D5805 /* SecondViewController.swift */, F632C3FD20E48DD0005D5805 /* Main.storyboard */, + DF76E74020F6A85700AE5236 /* InMealViewController.swift */, + DF707BBF20F68ABF006B611A /* StartMealViewController.swift */, + DF47C74B20E69A3E002F1D8A /* MealTableViewCell.swift */, F632C40020E48DD0005D5805 /* Assets.xcassets */, F632C40220E48DD0005D5805 /* LaunchScreen.storyboard */, F632C40520E48DD0005D5805 /* Info.plist */, + DFE0DACB20E56628000D63E1 /* MealProfileViewController.swift */, + DFA39A1520E80AAE00E54064 /* MealTableViewController.swift */, + DF47C74D20E69F8A002F1D8A /* ScheduledMeal.swift */, + DF86C5E620ED5FA4001F3778 /* MusicController.swift */, ); path = FoodForThought; sourceTree = ""; @@ -196,6 +240,7 @@ TargetAttributes = { F632C3F320E48DD0005D5805 = { CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 0920; ProvisioningStyle = Automatic; }; F632C40920E48DD0005D5805 = { @@ -235,8 +280,13 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + DFECD16E20ED70D000515451 /* m.mp3 in Resources */, F632C40420E48DD0005D5805 /* LaunchScreen.storyboard in Resources */, + DFECD16F20ED70D000515451 /* October.mp3 in Resources */, F632C40120E48DD0005D5805 /* Assets.xcassets in Resources */, + DFECD16D20ED70D000515451 /* Kiss The Rain.mp3 in Resources */, + DFECD17020ED70D000515451 /* The Truth That You Leave.mp3 in Resources */, + DFECD17220ED732300515451 /* mealProfile.xml in Resources */, F632C3FF20E48DD0005D5805 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -262,8 +312,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DF707BC020F68ABF006B611A /* StartMealViewController.swift in Sources */, + DF47C74E20E69F8A002F1D8A /* ScheduledMeal.swift in Sources */, F632C3FC20E48DD0005D5805 /* SecondViewController.swift in Sources */, + DFE0DACC20E56628000D63E1 /* MealProfileViewController.swift in Sources */, F632C3F820E48DD0005D5805 /* AppDelegate.swift in Sources */, + DF47C74C20E69A3E002F1D8A /* MealTableViewCell.swift in Sources */, + DF86C5E720ED5FA5001F3778 /* MusicController.swift in Sources */, + DFA39A1620E80AAE00E54064 /* MealTableViewController.swift in Sources */, + DF76E74120F6A85700AE5236 /* InMealViewController.swift in Sources */, F632C3FA20E48DD0005D5805 /* FirstViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -430,11 +487,17 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = DB3D83U263; + HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = FoodForThought/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = edu.self.FoodForThought; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -444,11 +507,16 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = DB3D83U263; + HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = FoodForThought/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + OTHER_LDFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = edu.self.FoodForThought; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/FoodForThought.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/FoodForThought.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100644 new mode 100755 index 8ba2fee..919434a --- a/FoodForThought.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/FoodForThought.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/FoodForThought.xcodeproj/project.xcworkspace/contents.xcworkspacedata.xml b/FoodForThought.xcodeproj/project.xcworkspace/contents.xcworkspacedata.xml new file mode 100755 index 0000000..8ba2fee --- /dev/null +++ b/FoodForThought.xcodeproj/project.xcworkspace/contents.xcworkspacedata.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/FoodForThought.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/FoodForThought.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100755 index 0000000..0c67376 --- /dev/null +++ b/FoodForThought.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/FoodForThought.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings.xml b/FoodForThought.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings.xml new file mode 100755 index 0000000..0c67376 --- /dev/null +++ b/FoodForThought.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/UserInterfaceState.xcuserstate b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100755 index 0000000..2eb52cd Binary files /dev/null and b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/WorkspaceSettings.xcsettings b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100755 index 0000000..f25782d --- /dev/null +++ b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,18 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildLocationType + RelativeToDerivedData + DerivedDataLocationStyle + Default + EnabledFullIndexStoreVisibility + + IssueFilterStyle + ShowActiveSchemeOnly + LiveSourceIssuesEnabled + + + diff --git a/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/WorkspaceSettings.xcsettings.xml b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/WorkspaceSettings.xcsettings.xml new file mode 100755 index 0000000..f25782d --- /dev/null +++ b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/awadams.xcuserdatad/WorkspaceSettings.xcsettings.xml @@ -0,0 +1,18 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildLocationType + RelativeToDerivedData + DerivedDataLocationStyle + Default + EnabledFullIndexStoreVisibility + + IssueFilterStyle + ShowActiveSchemeOnly + LiveSourceIssuesEnabled + + + diff --git a/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/jehrenho.xcuserdatad/UserInterfaceState.xcuserstate b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/jehrenho.xcuserdatad/UserInterfaceState.xcuserstate old mode 100644 new mode 100755 index 6347d99..ec85160 Binary files a/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/jehrenho.xcuserdatad/UserInterfaceState.xcuserstate and b/FoodForThought.xcodeproj/project.xcworkspace/xcuserdata/jehrenho.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100755 index 0000000..fe2b454 --- /dev/null +++ b/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist.xml b/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist.xml new file mode 100755 index 0000000..1d589f4 --- /dev/null +++ b/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcschemes/xcschememanagement.plist b/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100755 index 0000000..3a23ff6 --- /dev/null +++ b/FoodForThought.xcodeproj/xcuserdata/awadams.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + FoodForThought.xcscheme + + orderHint + 0 + + + + diff --git a/FoodForThought.xcodeproj/xcuserdata/jehrenho.xcuserdatad/xcschemes/xcschememanagement.plist b/FoodForThought.xcodeproj/xcuserdata/jehrenho.xcuserdatad/xcschemes/xcschememanagement.plist old mode 100644 new mode 100755 diff --git a/FoodForThought/.DS_Store b/FoodForThought/.DS_Store new file mode 100755 index 0000000..dffc04e Binary files /dev/null and b/FoodForThought/.DS_Store differ diff --git a/FoodForThought/AppDelegate.swift b/FoodForThought/AppDelegate.swift old mode 100644 new mode 100755 index 144607e..766fe86 --- a/FoodForThought/AppDelegate.swift +++ b/FoodForThought/AppDelegate.swift @@ -7,17 +7,57 @@ // import UIKit +import UserNotifications @UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { +class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { var window: UIWindow? + var isGrantedAccess = false - + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping ([UNNotificationPresentationOptions]) -> Void) { + completionHandler([.alert, .sound]) + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + } + + func requestAuthorization(options: UNAuthorizationOptions = [], + completionHandler: @escaping (Bool, Error?) -> Void) { + + } + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. + UNUserNotificationCenter.current().delegate = self + UNUserNotificationCenter.current().requestAuthorization( + options: [.alert,.sound,.badge], + completionHandler: { (granted,error) in + self.isGrantedAccess = granted + if granted{ + self.setCategories() + } else { + let alert = UIAlertController(title: "Notification Access", message: "In order to use this application, turn on notification permissions.", preferredStyle: .alert) + let alertAction = UIAlertAction(title: "Okay", style: .default, handler: nil) + alert.addAction(alertAction) + self.window?.rootViewController?.present(alert , animated: true, completion: nil) + } + }) return true } + + func setCategories() { + + } + + func addNotification(content:UNNotificationContent, trigger:UNNotificationTrigger?, indentifier:String) { + let request = UNNotificationRequest(identifier: indentifier, content: content, trigger: trigger) + UNUserNotificationCenter.current().add(request, withCompletionHandler: { (errorObject) in + if let error = errorObject { + print("Error \(error.localizedDescription) in notification \(indentifier)") + } + }) + } func applicationWillResignActive(_ application: UIApplication) { // 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. diff --git a/FoodForThought/Assets.xcassets/AppIcon.appiconset/Contents.json b/FoodForThought/Assets.xcassets/AppIcon.appiconset/Contents.json old mode 100644 new mode 100755 index 36d2c80..d8db8d6 --- a/FoodForThought/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/FoodForThought/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -30,6 +40,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -59,6 +79,16 @@ "idiom" : "ipad", "size" : "76x76", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/FoodForThought/Assets.xcassets/first.imageset/Contents.json b/FoodForThought/Assets.xcassets/first.imageset/Contents.json old mode 100644 new mode 100755 diff --git a/FoodForThought/Assets.xcassets/first.imageset/first.pdf b/FoodForThought/Assets.xcassets/first.imageset/first.pdf old mode 100644 new mode 100755 diff --git a/FoodForThought/Assets.xcassets/second.imageset/Contents.json b/FoodForThought/Assets.xcassets/second.imageset/Contents.json old mode 100644 new mode 100755 diff --git a/FoodForThought/Assets.xcassets/second.imageset/second.pdf b/FoodForThought/Assets.xcassets/second.imageset/second.pdf old mode 100644 new mode 100755 diff --git a/FoodForThought/Base.lproj/.DS_Store b/FoodForThought/Base.lproj/.DS_Store new file mode 100755 index 0000000..aa8df9d Binary files /dev/null and b/FoodForThought/Base.lproj/.DS_Store differ diff --git a/FoodForThought/Base.lproj/LaunchScreen.storyboard b/FoodForThought/Base.lproj/LaunchScreen.storyboard old mode 100644 new mode 100755 diff --git a/FoodForThought/Base.lproj/Main.storyboard b/FoodForThought/Base.lproj/Main.storyboard old mode 100644 new mode 100755 index f9046e2..41d322d --- a/FoodForThought/Base.lproj/Main.storyboard +++ b/FoodForThought/Base.lproj/Main.storyboard @@ -33,106 +33,411 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + + - + - - + + - - + + - - - - - - - - - + + - + + + + + + + + + + - + + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + - + - + - + @@ -157,7 +462,7 @@ - + @@ -169,20 +474,131 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FoodForThought/FirstViewController.swift b/FoodForThought/FirstViewController.swift old mode 100644 new mode 100755 index 6f52541..0d27760 --- a/FoodForThought/FirstViewController.swift +++ b/FoodForThought/FirstViewController.swift @@ -7,19 +7,29 @@ // import UIKit +import UserNotifications class FirstViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. + self.navigationController?.isNavigationBarHidden = true + } + + override func viewWillAppear(_ animated: Bool) { + self.tabBarController?.tabBar.isHidden = false + // let center = UNUserNotificationCenter.current() +// center.getPendingNotificationRequests { (notifications) in +// print("Count: \(notifications.count)") +// for item in notifications { +// print(item.content) +// } +// } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } - - } diff --git a/FoodForThought/InMealViewController.swift b/FoodForThought/InMealViewController.swift new file mode 100755 index 0000000..7361418 --- /dev/null +++ b/FoodForThought/InMealViewController.swift @@ -0,0 +1,39 @@ +// +// InMealViewController.swift +// FoodForThought +// +// Created by Andy Adams on 7/11/18. +// Copyright © 2018 Jordan Ehrenholz. All rights reserved. +// + +import UIKit + +class InMealViewController: UIViewController { + + override func viewWillAppear(_ animated: Bool) { + self.tabBarController?.tabBar.isHidden = true + } + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/FoodForThought/Info.plist b/FoodForThought/Info.plist old mode 100644 new mode 100755 index 6873106..2c651e4 --- a/FoodForThought/Info.plist +++ b/FoodForThought/Info.plist @@ -20,6 +20,11 @@ 1 LSRequiresIPhoneOS + UIBackgroundModes + + audio + remote-notification + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/FoodForThought/MealProfileViewController.swift b/FoodForThought/MealProfileViewController.swift new file mode 100755 index 0000000..7acc814 --- /dev/null +++ b/FoodForThought/MealProfileViewController.swift @@ -0,0 +1,135 @@ +// +// MealProfileViewController.swift +// FoodForThought +// +// Created by Andy Adams on 6/28/18. +// Copyright © 2018 Jordan Ehrenholz. All rights reserved. +// + +import UIKit + +class MealProfileViewController: UIViewController, UITextFieldDelegate { + + // MARK: Outlets + @IBOutlet weak var mealTable: UIView! + @IBOutlet weak var newMealName: UITextField! + @IBOutlet weak var newMealTime: UITextField! + @IBOutlet weak var newMealDuration: UITextField! + @IBOutlet weak var newMealNameWarning: UILabel! + @IBOutlet weak var newMealTimeWarning: UILabel! + @IBOutlet weak var newMealDurationWarning: UILabel! + + var mealTableViewController: MealTableViewController? + + // MARK: Actions + // Adds a new meal to scheduled meals + @IBAction func addMeal(_ sender: UIButton) { + // If no value entered for meal name or time, tell + // user these must be entered + var ready: Bool = true + if newMealName.text == "" { + newMealNameWarning.text = "Enter meal name" + ready = false + } + if newMealTime.text == "" { + newMealTimeWarning.text = "Enter meal time" + ready = false + } + if newMealDuration.text == "" { + newMealDurationWarning.text = "Enter meal duration" + ready = false + } + + // If all values have been entered, created new meal based + // on user input and add to table + if ready { + guard let newMeal: ScheduledMeal = ScheduledMeal(mealName: newMealName.text!, mealTime: newMealTime.text!, mealDuration: newMealDuration.text!) else { + fatalError("Unable to instantiate new meal") + } + + mealTableViewController?.addMeal(newMeal: newMeal) + + // Reset fields + newMealName.text = "" + newMealTime.text = "" + newMealDuration.text = "" + newMealNameWarning.text = "" + newMealTimeWarning.text = "" + newMealDurationWarning.text = "" + } + } + + @IBAction func saveMealProfile(_ sender: UIButton) { + self.mealTableViewController?.saveScheduledMeals() + self.mealTableViewController?.setMealNotifications() + } + + override func viewDidLoad() { + super.viewDidLoad() + self.newMealName.delegate = self + self.newMealTime.delegate = self + self.newMealDuration.delegate = self + + var timePickerView: UIDatePicker = UIDatePicker() + timePickerView.datePickerMode = UIDatePickerMode.time + + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "HH:mm" + timePickerView.date = dateFormatter.date(from: "00:00")! + + newMealTime.inputView = timePickerView + + // datepicker toolbar setup + let toolBar = UIToolbar() + toolBar.barStyle = UIBarStyle.default + toolBar.isTranslucent = true + let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil) + let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(doneDatePickerPressed)) + toolBar.setItems([space, doneButton], animated: false) + toolBar.isUserInteractionEnabled = true + toolBar.sizeToFit() + + newMealTime.inputAccessoryView = toolBar + + timePickerView.addTarget(self, action: #selector(self.handleDatePicker), for: UIControlEvents.valueChanged) + } + + override func viewWillAppear(_ animated: Bool) { + self.tabBarController?.tabBar.isHidden = true + } + + @objc func handleDatePicker(sender: UIDatePicker) { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "HH:mm" + newMealTime.text = dateFormatter.string(from: sender.date) + } + + @objc func doneDatePickerPressed(){ + newMealTimeWarning.text = "" + newMealTime.endEditing(true) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.endEditing(true) + textField.resignFirstResponder() + if textField == newMealName { + newMealNameWarning.text = "" + } else if textField == newMealDuration { + newMealDurationWarning.text = "" + } + return false + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if segue.identifier == "embeddedMealTable" { + if let viewController1 = segue.destination as? MealTableViewController { + self.mealTableViewController = viewController1 + } + } + } +} diff --git a/FoodForThought/MealTableViewCell.swift b/FoodForThought/MealTableViewCell.swift new file mode 100755 index 0000000..d6b05cd --- /dev/null +++ b/FoodForThought/MealTableViewCell.swift @@ -0,0 +1,168 @@ +// +// ScheduledMealTableViewCell.swift +// FoodForThought +// +// Created by Andy Adams on 6/29/18. +// Copyright © 2018 Jordan Ehrenholz. All rights reserved. +// + +import UIKit + +class MealTableViewCell: UITableViewCell, UIPickerViewDelegate, UITextFieldDelegate { + + // MARK: Properties + @IBOutlet weak var mealName: UITextField! + @IBOutlet weak var mealTime: UITextField! + @IBOutlet weak var mealDuration: UITextField! + @IBOutlet weak var deleteMealButton: UIButton! + + var activeTextField: UITextField? + var activeTextFieldTextBeforeEdit: String = String() + var mealCellDelegate: MealCellDelegate? + var indexPathRow: Int = 0 + + // MARK: Actions + // Deletes scheduled meal in cell + @IBAction func deleteMeal(_ sender: UIButton) { + mealName.text = "" + mealTime.text = "" + mealDuration.text = "" + self.mealCellDelegate?.mealWasDeleted(row: indexPathRow) + } + + // Edits meal name of meal in cell + @IBAction func editMealName(_ sender: UITextField) { + if sender.text == "" { + sender.text = activeTextFieldTextBeforeEdit + } + self.mealCellDelegate?.nameWasEdited((sender.text)!, row: indexPathRow) + } + + // Edits meal time of meal in cell + @IBAction func setTime(_ sender: UITextField) { + activeTextField = sender + + var TimePickerView: UIDatePicker = UIDatePicker() + TimePickerView.datePickerMode = UIDatePickerMode.time + + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "HH:mm" + TimePickerView.date = dateFormatter.date(from: mealTime.text!)! + + sender.inputView = TimePickerView + + // Set up timepicker tool bar + let toolBar = UIToolbar() + toolBar.barStyle = UIBarStyle.default + toolBar.isTranslucent = true + let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil) + let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(doneTimePickerPressed)) + toolBar.setItems([space, doneButton], animated: false) + toolBar.isUserInteractionEnabled = true + toolBar.sizeToFit() + + sender.inputAccessoryView = toolBar + + TimePickerView.addTarget(self, action: #selector(self.handleDatePicker), for: UIControlEvents.valueChanged) + } + + // Update time value in textfield as timepicker is changed + @objc func handleDatePicker(sender: UIDatePicker) { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "HH:mm" + mealTime.text = dateFormatter.string(from: sender.date) + } + + // Finishes using timepicker to edit meal time + @objc func doneTimePickerPressed(){ + self.endEditing(true) + self.mealCellDelegate?.timeWasEdited(activeTextField!.text!, row: indexPathRow) + } + + // Edit meal duration + @IBAction func editDuration(_ sender: UITextField) { + if sender.text == "" { + sender.text = activeTextFieldTextBeforeEdit + } + self.mealCellDelegate?.durationWasEdited(duration: sender.text!, row: indexPathRow) + } + + // If there are no scheduled meals, hide/disable all fields in cell + func displayNoMealsScheduled(){ + mealName.isHidden = true + mealTime.isHidden = true + mealDuration.isHidden = true + deleteMealButton.isHidden = true + deleteMealButton.isEnabled = false + } + + // Sets meal properties from data in a ScheduledMeal object + func setMealProperties(meal: ScheduledMeal) { + // Unhide and enable all fields in cell + mealName.isHidden = false + mealTime.isHidden = false + mealDuration.isHidden = false + deleteMealButton.isHidden = false + deleteMealButton.isEnabled = true + + mealName.text = meal.mealName + + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "HH:mm" + let date = dateFormatter.date(from: meal.mealTime) + let time = dateFormatter.string(from: date!) + mealTime.text = time + + mealDuration.text = meal.mealDuration + } + + func textFieldDidBeginEditing(_ textField: UITextField) { + activeTextField = textField + activeTextFieldTextBeforeEdit = (activeTextField?.text)! + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + if activeTextField == mealName { + if textField.text != "" { + if (self.mealCellDelegate?.isNameUnique(mealName: textField.text!))! || textField.text == activeTextFieldTextBeforeEdit { + textField.endEditing(true) + textField.resignFirstResponder() + } else { + textField.text = activeTextFieldTextBeforeEdit + } + } + } else if activeTextField == mealDuration { + textField.endEditing(true) + textField.resignFirstResponder() + } + return false + } + + func textFieldDidEndEditing(_ textField: UITextField) { + if textField.text == "" { + textField.text = activeTextFieldTextBeforeEdit + } + } + + + override func awakeFromNib() { + super.awakeFromNib() + mealName.delegate = self + mealDuration.delegate = self + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + } + +} + +// Custom protocol to enable MealTableViewController to update meal data source +// with edited values +protocol MealCellDelegate { + func nameWasEdited(_ mealName: String, row: Int) + func isNameUnique(mealName: String) -> Bool + func timeWasEdited(_ mealTime: String, row: Int) + func durationWasEdited(duration: String, row: Int) + func mealWasDeleted(row: Int) +} diff --git a/FoodForThought/MealTableViewController.swift b/FoodForThought/MealTableViewController.swift new file mode 100755 index 0000000..e71d456 --- /dev/null +++ b/FoodForThought/MealTableViewController.swift @@ -0,0 +1,288 @@ +// +// MealTableViewController.swift +// FoodForThought +// +// Created by Andy Adams on 2018-06-30. +// Copyright © 2018 Jordan Ehrenholz. All rights reserved. +// + +import UIKit +import UserNotifications + +class MealTableViewController: UITableViewController, UITextFieldDelegate, UIPickerViewDelegate, MealCellDelegate, XMLParserDelegate { + + + + // MARK: Table view data source + var scheduledMeals = [ScheduledMeal]() + + // MARK: Properties + var activeTextField: UITextField? + var eName: String = String() + var mealName: String = String() + var mealTime: String = String() + var mealDuration: String = String() + var mealProfileURL: NSURL? + + // MARK: Outlets + @IBOutlet var mealTable: UITableView! + + override func viewDidLoad() { + super.viewDidLoad() + + // Access mealProfile.xml file from user's documents directory; if file exists, + // load saved meals based on file data; if file does not exist, create it + var documentsDirectory: NSURL? + documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! as NSURL + mealProfileURL = documentsDirectory!.appendingPathComponent("mealProfile.xml")! as NSURL + + if (mealProfileURL!.checkResourceIsReachableAndReturnError(nil)) { + self.loadSavedMeals() + }else{ + NSData().write(to: mealProfileURL! as URL, atomically:true) + } + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + // Load saved meal information from mealProfile.xml + func loadSavedMeals() { + // Parse mealProfile.xml; parser methods create ScheduledMeal objects + // and load them into the scheduledMeals data source array + if let parser = XMLParser(contentsOf: mealProfileURL! as URL) { + parser.delegate = self + parser.parse() + } + } + + // Add new meal + func addMeal(newMeal: ScheduledMeal) { + // Add newly scheduled meal to scheduledMeals data source array, + // then sort array by meal time so meals are displayed in chronological order + scheduledMeals.append(newMeal) + scheduledMeals.sort { + $0.mealTime < $1.mealTime + } + tableView.reloadData() + } + + + // MEAL CELL DELEGATE METHODS + + // Checks that the entered name is a unique name among saved meals + func isNameUnique(mealName: String) -> Bool { + var uniqueName = true + print("in uniqueName") + for each in scheduledMeals { + if each.mealName == mealName { + print("meal names equal") + uniqueName = false + print(uniqueName) + } + } + print(uniqueName) + return uniqueName + } + + // Update edited mealName + func nameWasEdited(_ mealName: String, row: Int) { + scheduledMeals[row].mealName = mealName + } + + // Update edited mealTime + func timeWasEdited(_ mealTime: String, row: Int) { + // Update data source with edited meal time value, then sort meals + // by time to display in chronological order + scheduledMeals[row].mealTime = mealTime + scheduledMeals.sort { + $0.mealTime < $1.mealTime + } + tableView.reloadData() + } + + // Update edited mealDuration + func durationWasEdited(duration: String, row: Int) { + scheduledMeals[row].mealDuration = duration + tableView.reloadData() + } + + // Delete meal cell if "delete" button pressed + func mealWasDeleted(row: Int) { + scheduledMeals.remove(at: row) + tableView.reloadData() + } + + + + + + func saveScheduledMeals() { + // For each meal in scheduled meal, create an XML string and append it + // to the growing master string; then append closing tag + var masterXMLString: String = "\n\n" + for each in scheduledMeals { + masterXMLString.append(createXMLString(meal: each)) + } + masterXMLString.append("\n") + + // Write XML data to mealProfile.xml + let data = Data(masterXMLString.utf8) + do { + try data.write(to: mealProfileURL! as URL, options: .atomic) + } catch { + print(error) + } + } + + // Sets notifications to warn user of impending start times of all scheduled meals + func setMealNotifications() { + // Remove previously saved notifications + UNUserNotificationCenter.current().removeAllPendingNotificationRequests() + + // For every scheduled meal, create a notification trigger based on the meal time; + // schedule notification to repeat daily based on meal time trigger. + // Default warning time for notification is 30 minutes. + var identifier: String = "" + var mealAlertHour: Int = 0 + var mealAlertMinute: Int = 0 + let mealAlertWarningTime: Int = 30 + for each in scheduledMeals { + // Create new notification based on current element in scheduledMeals + identifier = each.mealName + let content = UNMutableNotificationContent() + content.title = "Time to eat soon." + content.subtitle = "What are you hungry for?" + content.body = each.mealName + " is coming up in " + String(mealAlertWarningTime) + " minutes." + content.sound = UNNotificationSound.default() + content.setValue("YES", forKeyPath: "shouldAlwaysAlertWhileAppIsForeground") + + // Get hour and minute of meal for calculating notification time + var hourAndMinute = [Int]() + let timeArray = each.mealTime.split(separator: ":") + for each in timeArray { + if let intVal = Int(each) { + hourAndMinute.append(intVal) + } + } + + // Calculate notification time (mealAlertHour and mealAlertMinuted) + // based on meal time and how much of a warning is to be given + if hourAndMinute[1] < mealAlertWarningTime { + mealAlertHour = hourAndMinute[0] - 1 + mealAlertMinute = 60 - (mealAlertWarningTime - hourAndMinute[1]) + } else { + mealAlertHour = hourAndMinute[0] + mealAlertMinute = hourAndMinute[1] - mealAlertWarningTime + } + + // Create repeating notification trigger based on date/time + let date = Calendar.current.date(bySettingHour: mealAlertHour, minute: mealAlertMinute, second: 0, of: Date())! + let triggerDaily = Calendar.current.dateComponents([.hour,.minute,.second,], from: date) + let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true) + + // Create notification request based on trigger and add to notification center + let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) + UNUserNotificationCenter.current().add(request, withCompletionHandler: {(error) in + if let error = error { + print("SOMETHING WENT WRONG") + } + }) + } + } + + // Creates an XML string from meal data + private func createXMLString(meal: ScheduledMeal) -> String { + var mealXML: String = "\n\n" + mealXML.append(meal.mealName) + mealXML.append("\n\n\n\n") + mealXML.append(meal.mealDuration) + mealXML.append("\n\n\n") + return mealXML + } + + // TABLE VIEW CONTROLLER METHODS + override func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if scheduledMeals.count == 0 { + return 1 + } else { + return scheduledMeals.count + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + // Table view cells are reused and should be dequeued using a cell identifier. + let cellIdentifier = "mealTableViewCell" + guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: + indexPath) as? MealTableViewCell else { + fatalError("The dequeued cell is not an instance of MealTableViewCell.") + } + + cell.mealCellDelegate = self + + // If there are no saved meals, display empty cell; + // else, populate cell with meal info from saved meal + if scheduledMeals.count == 0 { + cell.displayNoMealsScheduled() + } else { + let cellMeal = scheduledMeals[indexPath.row] + cell.setMealProperties(meal: cellMeal) + cell.indexPathRow = indexPath.row + } + return cell + } + + // TEXTFIELD DELEGATE FUNCTIONS + func textFieldDidBeginEditing(_ textField: UITextField) { + activeTextField = textField + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.endEditing(true) + textField.resignFirstResponder() + return false + } + + func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { + return true + } + + + // PARSER DELEGATE FUNCTIONS + func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { + eName = elementName + if elementName == "meal" { + mealName = String() + mealTime = String() + mealDuration = String() + } + } + + func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { + if elementName == "meal" { + let meal = ScheduledMeal(mealName: self.mealName, mealTime: self.mealTime, mealDuration: self.mealDuration) + scheduledMeals.append(meal!) + } + } + + func parser(_ parser: XMLParser, foundCharacters string: String) { + let data = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) + if (!data.isEmpty) { + if eName == "name" { + mealName += data + } else if eName == "time" { + mealTime += data + } else if eName == "duration" { + mealDuration += data + } + } + } +} diff --git a/FoodForThought/Music/Kiss The Rain.mp3 b/FoodForThought/Music/Kiss The Rain.mp3 new file mode 100755 index 0000000..7ae9bd1 Binary files /dev/null and b/FoodForThought/Music/Kiss The Rain.mp3 differ diff --git a/FoodForThought/Music/October.mp3 b/FoodForThought/Music/October.mp3 new file mode 100755 index 0000000..23654b9 Binary files /dev/null and b/FoodForThought/Music/October.mp3 differ diff --git a/FoodForThought/Music/The Truth That You Leave.mp3 b/FoodForThought/Music/The Truth That You Leave.mp3 new file mode 100755 index 0000000..44ba43f Binary files /dev/null and b/FoodForThought/Music/The Truth That You Leave.mp3 differ diff --git a/FoodForThought/Music/m.mp3 b/FoodForThought/Music/m.mp3 new file mode 100755 index 0000000..d64714c Binary files /dev/null and b/FoodForThought/Music/m.mp3 differ diff --git a/FoodForThought/MusicController.swift b/FoodForThought/MusicController.swift new file mode 100755 index 0000000..ec5fc55 --- /dev/null +++ b/FoodForThought/MusicController.swift @@ -0,0 +1,168 @@ + +// +// FirstViewController.swift +// FoodForThought +// +// Created by Jordan Ehrenholz on 6/27/18. +// Copyright © 2018 Jordan Ehrenholz. All rights reserved. +// + +import UIKit +import AVFoundation + +class musicController: UIViewController { + //set up audio player + var audioPlayer = AVAudioPlayer() + + //todo: change the list to automatic generation. (done) + + var audioList = [[String]]() + var itr = 0 + var timer = Timer() + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + + //Automatic Music list generation (mp3 only) + let docsPath = Bundle.main.resourcePath! + + let fileManager = FileManager.default + do{ + //getting all files + var docsArray = try fileManager.contentsOfDirectory(atPath: docsPath) + + //exctract .mp3 files + var i = 0 + for each in docsArray{ + if each.range(of: ".mp3") != nil{ + }else{ + docsArray.remove(at: i) + i -= 1 + } + i += 1 + } + //adding to audioList + for each in docsArray{ + audioList.append(each.components(separatedBy: ".")) + } + }catch{ + print(error) + } + + + //Audio setup + + do{ + audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: audioList[0][0], ofType: audioList[0][1])!)) + audioPlayer.prepareToPlay() + + //set up backgroud music playing + let audioSession = AVAudioSession.sharedInstance() + do { + try audioSession.setCategory(AVAudioSessionCategoryPlayback) + } + } + catch{ + print(error) + } + //end Audio setup + + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + //@IBOutlet weak var musicTimeDisplay: UILabel! + //@IBOutlet weak var musicCurrentDisplay: UILabel! + + //Music functions + func play(){ + audioPlayer.play() + + // todo: creat a thread that call next up on finish playing.(done) + DispatchQueue.global(qos: .background).async { + + while(self.audioPlayer.duration - self.audioPlayer.currentTime > 1){ + sleep(1) + } + self.next() + } + } + + + @IBOutlet weak var musicDragBar: UISlider? + @IBOutlet weak var musicTimeDisplay: UILabel? + @IBOutlet weak var musicCurrentDisplay: UILabel? + + @objc func lableUpdate(){ + //Total duration of play. + if((Int(audioPlayer.duration) % 60) > 9){ + musicTimeDisplay?.text = "\(Int(audioPlayer.duration) / 60):\(Int(audioPlayer.duration) % 60)" + }else{ + musicTimeDisplay?.text = "\(Int(audioPlayer.duration) / 60):0\(Int(audioPlayer.duration) % 60)" + } + //currentTime of play + if((Int(audioPlayer.currentTime) % 60) > 9){ + musicCurrentDisplay?.text = "\(Int(audioPlayer.currentTime) / 60):\(Int(audioPlayer.currentTime) % 60)" + }else{ + musicCurrentDisplay?.text = "\(Int(audioPlayer.currentTime) / 60):0\(Int(audioPlayer.currentTime) % 60)" + } + + musicDragBar?.setValue(Float(audioPlayer.currentTime / audioPlayer.duration), animated: true) + + } + + func next(){ + do{ + audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: audioList[(itr+1) % audioList.count][0], ofType: audioList[(itr+1) % audioList.count][1])!)) + itr += 1 + audioPlayer.prepareToPlay() + play() + }catch{ + print(error) + } + } + + @IBAction func musicDrag(_ sender: UISlider) { + audioPlayer.currentTime = TimeInterval(Int((musicDragBar?.value)! * Float(audioPlayer.duration))) + } + + @IBAction func play(_ sender: UIButton) { + play() + timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(lableUpdate), userInfo: nil, repeats: true) + + } + + @IBAction func pause(_ sender: UIButton) { + if audioPlayer.isPlaying{ + audioPlayer.pause() + } + } + + @IBAction func restart(_ sender: UIButton) { + if audioPlayer.isPlaying{ + audioPlayer.currentTime = 0 + play() + } + } + + @IBAction func next(_ sender: UIButton){ + next() + } + @IBAction func prev(_ sender: UIButton){ + do{ + audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: audioList[(itr-1) % audioList.count][0], ofType: audioList[(itr-1) % audioList.count][1])!)) + itr -= 1 + audioPlayer.prepareToPlay() + play() + }catch{ + print(error) + } + + } + + //end Music functions +} diff --git a/FoodForThought/ScheduledMeal.swift b/FoodForThought/ScheduledMeal.swift new file mode 100755 index 0000000..4806e9d --- /dev/null +++ b/FoodForThought/ScheduledMeal.swift @@ -0,0 +1,31 @@ +// +// ScheduledMeal.swift +// A data model for a ScheduledMeal object +// FoodForThought +// +// Created by Andy Adams on 6/29/18. +// Copyright © 2018 Jordan Ehrenholz. All rights reserved. +// + +import UIKit + +class ScheduledMeal{ + + //MARK: Properties + var mealName: String + var mealTime: String + var mealDuration: String + + init?(mealName: String, mealTime: String, mealDuration: String) { + // Initialization should fail if there is no name or values are negative + if mealName.isEmpty || mealTime.isEmpty || mealDuration.isEmpty { + return nil + } + + self.mealName = mealName + self.mealTime = mealTime + self.mealDuration = mealDuration + } + + +} diff --git a/FoodForThought/SecondViewController.swift b/FoodForThought/SecondViewController.swift old mode 100644 new mode 100755 index 590bfec..0d760dd --- a/FoodForThought/SecondViewController.swift +++ b/FoodForThought/SecondViewController.swift @@ -10,6 +10,12 @@ import UIKit class SecondViewController: UIViewController { +// override func viewWillAppear(_ animated: Bool) { +// // Show tab bar and ensure Journal tab (index = 1) is selected +// self.tabBarController?.tabBar.isHidden = false +// self.tabBarController?.selectedIndex = 1 +// } +// override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. diff --git a/FoodForThought/StartMealViewController.swift b/FoodForThought/StartMealViewController.swift new file mode 100755 index 0000000..6a71eba --- /dev/null +++ b/FoodForThought/StartMealViewController.swift @@ -0,0 +1,49 @@ +// +// StartMealViewController.swift +// FoodForThought +// +// Created by Andy Adams on 7/11/18. +// Copyright © 2018 Jordan Ehrenholz. All rights reserved. +// + +import UIKit + +class StartMealViewController: UIViewController { + + @IBOutlet weak var hungerSlider: UISlider! + + var preMealHunger: Int = 0 + + @IBAction func hungerValueChanged(_ sender: UISlider) { + sender.setValue(Float(lroundf(hungerSlider.value)), animated: true) + preMealHunger = lroundf(hungerSlider.value) + print(preMealHunger) + } + + override func viewDidLoad() { + super.viewDidLoad() + let x = hungerSlider.frame.minX + print(x) + + + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + + + + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destinationViewController. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/FoodForThought/mealProfile.xml b/FoodForThought/mealProfile.xml new file mode 100755 index 0000000..4cf6335 --- /dev/null +++ b/FoodForThought/mealProfile.xml @@ -0,0 +1,20 @@ + + + + + Breakfast + + + + + + Lunch + + + + + diff --git a/FoodForThoughtTests/FoodForThoughtTests.swift b/FoodForThoughtTests/FoodForThoughtTests.swift old mode 100644 new mode 100755 diff --git a/FoodForThoughtTests/Info.plist b/FoodForThoughtTests/Info.plist old mode 100644 new mode 100755 diff --git a/FoodForThoughtUITests/FoodForThoughtUITests.swift b/FoodForThoughtUITests/FoodForThoughtUITests.swift old mode 100644 new mode 100755 diff --git a/FoodForThoughtUITests/Info.plist b/FoodForThoughtUITests/Info.plist old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755