diff --git a/CookCookMom.xcodeproj/project.pbxproj b/CookCookMom.xcodeproj/project.pbxproj index 79eba2e..ec4ddf8 100644 --- a/CookCookMom.xcodeproj/project.pbxproj +++ b/CookCookMom.xcodeproj/project.pbxproj @@ -13,11 +13,14 @@ 187ADF0329FA5D8500C4CDCD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 187ADF0229FA5D8500C4CDCD /* Preview Assets.xcassets */; }; 187ADF0A29FA5F2500C4CDCD /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = 187ADF0929FA5F2500C4CDCD /* .gitignore */; }; 18DA57232A08EDE600EE16EA /* CentralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DA57222A08EDE600EE16EA /* CentralViewModel.swift */; }; - 18DA57252A08EE1600EE16EA /* PeripheralViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DA57242A08EE1600EE16EA /* PeripheralViewModel.swift */; }; 18DA57282A08EE8F00EE16EA /* TransferService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DA57272A08EE8F00EE16EA /* TransferService.swift */; }; 18DA572A2A08EEDC00EE16EA /* SendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DA57292A08EEDC00EE16EA /* SendView.swift */; }; 18DA572D2A08EF0C00EE16EA /* SendIngredientsButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DA572C2A08EF0C00EE16EA /* SendIngredientsButton.swift */; }; 18DA572F2A09222C00EE16EA /* CentralView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DA572E2A09222C00EE16EA /* CentralView.swift */; }; + 363087C12A0B69100062DDC9 /* NotificationListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 363087C02A0B69100062DDC9 /* NotificationListView.swift */; }; + 363087C32A0B69240062DDC9 /* NotificationRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 363087C22A0B69240062DDC9 /* NotificationRowView.swift */; }; + 363087C62A0B69620062DDC9 /* (null) in Sources */ = {isa = PBXBuildFile; }; + 363087CA2A0E1B3B0062DDC9 /* DescriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 363087C92A0E1B3B0062DDC9 /* DescriptionView.swift */; }; 363BE19D2A0A3070005E2876 /* CartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 363BE19C2A0A3070005E2876 /* CartView.swift */; }; 36673D292A00D1DA001EEB19 /* NotificationButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36673D282A00D1DA001EEB19 /* NotificationButton.swift */; }; 36673D2B2A00D1E2001EEB19 /* IngredientButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36673D2A2A00D1E2001EEB19 /* IngredientButton.swift */; }; @@ -26,6 +29,9 @@ 36673D512A0136F0001EEB19 /* ShoppingCart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36673D502A0136F0001EEB19 /* ShoppingCart.swift */; }; 36673D532A023BDD001EEB19 /* Ingredient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36673D522A023BDD001EEB19 /* Ingredient.swift */; }; 36673D552A0282E5001EEB19 /* IngredientC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36673D542A0282E5001EEB19 /* IngredientC.swift */; }; + 402F505B2A0AB4B70093C94B /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 402F505A2A0AB4B70093C94B /* PersistenceController.swift */; }; + 402F505E2A0AB4DE0093C94B /* CookCookMom.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 402F505C2A0AB4DE0093C94B /* CookCookMom.xcdatamodeld */; }; + 6F8565BC2A12277500FD0A58 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8565BB2A12277500FD0A58 /* NetworkManager.swift */; }; 6FCE85852A08D43E0086FB52 /* IngredientModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCE85842A08D43E0086FB52 /* IngredientModel.swift */; }; 6FCE85882A08D4BE0086FB52 /* TestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCE85872A08D4BE0086FB52 /* TestView.swift */; }; 6FCE858A2A08D4C70086FB52 /* IngredientsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCE85892A08D4C70086FB52 /* IngredientsViewModel.swift */; }; @@ -39,11 +45,13 @@ 187ADF0229FA5D8500C4CDCD /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 187ADF0929FA5F2500C4CDCD /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 18DA57222A08EDE600EE16EA /* CentralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CentralViewModel.swift; sourceTree = ""; }; - 18DA57242A08EE1600EE16EA /* PeripheralViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralViewModel.swift; sourceTree = ""; }; 18DA57272A08EE8F00EE16EA /* TransferService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransferService.swift; sourceTree = ""; }; 18DA57292A08EEDC00EE16EA /* SendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SendView.swift; path = CookCookMom/Constants/SendView.swift; sourceTree = SOURCE_ROOT; }; 18DA572C2A08EF0C00EE16EA /* SendIngredientsButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendIngredientsButton.swift; sourceTree = ""; }; 18DA572E2A09222C00EE16EA /* CentralView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CentralView.swift; sourceTree = ""; }; + 363087C02A0B69100062DDC9 /* NotificationListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationListView.swift; sourceTree = ""; }; + 363087C22A0B69240062DDC9 /* NotificationRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationRowView.swift; sourceTree = ""; }; + 363087C92A0E1B3B0062DDC9 /* DescriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DescriptionView.swift; sourceTree = ""; }; 363BE19C2A0A3070005E2876 /* CartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CartView.swift; sourceTree = ""; }; 36673D282A00D1DA001EEB19 /* NotificationButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationButton.swift; sourceTree = ""; }; 36673D2A2A00D1E2001EEB19 /* IngredientButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IngredientButton.swift; sourceTree = ""; }; @@ -52,6 +60,11 @@ 36673D502A0136F0001EEB19 /* ShoppingCart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCart.swift; sourceTree = ""; }; 36673D522A023BDD001EEB19 /* Ingredient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ingredient.swift; sourceTree = ""; }; 36673D542A0282E5001EEB19 /* IngredientC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IngredientC.swift; sourceTree = ""; }; + 402F50582A0AB3F70093C94B /* CookCookMom.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CookCookMom.entitlements; sourceTree = ""; }; + 402F50592A0AB4220093C94B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 402F505A2A0AB4B70093C94B /* PersistenceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceController.swift; sourceTree = ""; }; + 402F505D2A0AB4DE0093C94B /* CookCookMom.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = CookCookMom.xcdatamodel; sourceTree = ""; }; + 6F8565BB2A12277500FD0A58 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; 6FCE85842A08D43E0086FB52 /* IngredientModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IngredientModel.swift; sourceTree = ""; }; 6FCE85872A08D4BE0086FB52 /* TestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestView.swift; sourceTree = ""; }; 6FCE85892A08D4C70086FB52 /* IngredientsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IngredientsViewModel.swift; sourceTree = ""; }; @@ -71,6 +84,7 @@ 187ADEEF29FA5D8400C4CDCD = { isa = PBXGroup; children = ( + 6F8565BA2A12271800FD0A58 /* Utils */, 187ADF0929FA5F2500C4CDCD /* .gitignore */, 187ADEFA29FA5D8400C4CDCD /* CookCookMom */, 187ADEF929FA5D8400C4CDCD /* Products */, @@ -88,6 +102,8 @@ 187ADEFA29FA5D8400C4CDCD /* CookCookMom */ = { isa = PBXGroup; children = ( + 402F50592A0AB4220093C94B /* Info.plist */, + 402F50582A0AB3F70093C94B /* CookCookMom.entitlements */, 18DA57262A08EE7100EE16EA /* Constants */, 18DA57092A08E29C00EE16EA /* Model */, 18DA57082A08E29000EE16EA /* View */, @@ -101,6 +117,7 @@ 36673D522A023BDD001EEB19 /* Ingredient.swift */, 36673D542A0282E5001EEB19 /* IngredientC.swift */, 187ADEFF29FA5D8500C4CDCD /* Assets.xcassets */, + 402F505C2A0AB4DE0093C94B /* CookCookMom.xcdatamodeld */, 187ADF0129FA5D8500C4CDCD /* Preview Content */, ); path = CookCookMom; @@ -118,7 +135,6 @@ isa = PBXGroup; children = ( 18DA571F2A08ED7F00EE16EA /* Central */, - 18DA57212A08ED9200EE16EA /* Peripheral */, 18DA57202A08ED8600EE16EA /* SendIngredients */, ); path = ViewModel; @@ -130,6 +146,9 @@ 18DA572B2A08EEE000EE16EA /* Components */, 18DA57292A08EEDC00EE16EA /* SendView.swift */, 18DA572E2A09222C00EE16EA /* CentralView.swift */, + 363087C02A0B69100062DDC9 /* NotificationListView.swift */, + 363087C22A0B69240062DDC9 /* NotificationRowView.swift */, + 363087C92A0E1B3B0062DDC9 /* DescriptionView.swift */, ); path = View; sourceTree = ""; @@ -138,6 +157,7 @@ isa = PBXGroup; children = ( 6FCE85842A08D43E0086FB52 /* IngredientModel.swift */, + 402F505A2A0AB4B70093C94B /* PersistenceController.swift */, ); path = Model; sourceTree = ""; @@ -158,14 +178,6 @@ path = SendIngredients; sourceTree = ""; }; - 18DA57212A08ED9200EE16EA /* Peripheral */ = { - isa = PBXGroup; - children = ( - 18DA57242A08EE1600EE16EA /* PeripheralViewModel.swift */, - ); - path = Peripheral; - sourceTree = ""; - }; 18DA57262A08EE7100EE16EA /* Constants */ = { isa = PBXGroup; children = ( @@ -185,6 +197,14 @@ path = Components; sourceTree = ""; }; + 6F8565BA2A12271800FD0A58 /* Utils */ = { + isa = PBXGroup; + children = ( + 6F8565BB2A12277500FD0A58 /* NetworkManager.swift */, + ); + path = Utils; + sourceTree = ""; + }; 6FCE85862A08D4980086FB52 /* Test */ = { isa = PBXGroup; children = ( @@ -265,6 +285,7 @@ buildActionMask = 2147483647; files = ( 18DA57282A08EE8F00EE16EA /* TransferService.swift in Sources */, + 363087C62A0B69620062DDC9 /* (null) in Sources */, 36673D2F2A00D1EC001EEB19 /* SelectView.swift in Sources */, 36673D292A00D1DA001EEB19 /* NotificationButton.swift in Sources */, 187ADEFE29FA5D8400C4CDCD /* ContentView.swift in Sources */, @@ -277,12 +298,17 @@ 36673D2B2A00D1E2001EEB19 /* IngredientButton.swift in Sources */, 6FCE858A2A08D4C70086FB52 /* IngredientsViewModel.swift in Sources */, 18DA572F2A09222C00EE16EA /* CentralView.swift in Sources */, - 18DA57252A08EE1600EE16EA /* PeripheralViewModel.swift in Sources */, + 363087C32A0B69240062DDC9 /* NotificationRowView.swift in Sources */, + 363087C12A0B69100062DDC9 /* NotificationListView.swift in Sources */, 187ADEFC29FA5D8400C4CDCD /* CookCookMomApp.swift in Sources */, 36673D512A0136F0001EEB19 /* ShoppingCart.swift in Sources */, 18DA572A2A08EEDC00EE16EA /* SendView.swift in Sources */, 363BE19D2A0A3070005E2876 /* CartView.swift in Sources */, 36673D552A0282E5001EEB19 /* IngredientC.swift in Sources */, + 402F505E2A0AB4DE0093C94B /* CookCookMom.xcdatamodeld in Sources */, + 6F8565BC2A12277500FD0A58 /* NetworkManager.swift in Sources */, + 402F505B2A0AB4B70093C94B /* PersistenceController.swift in Sources */, + 363087CA2A0E1B3B0062DDC9 /* DescriptionView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -408,12 +434,15 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = CookCookMom/CookCookMom.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"CookCookMom/Preview Content\""; - DEVELOPMENT_TEAM = L4S47TM436; + DEVELOPMENT_TEAM = M8JXU75248; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = CookCookMom/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = ChopChopMom; INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "\"CookCookMom\" use bluetooth"; INFOPLIST_KEY_NSBluetoothPeripheralUsageDescription = "\"CookCookMom\" use bluetooth"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -427,7 +456,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.cookcookmom.mom; + PRODUCT_BUNDLE_IDENTIFIER = com.myApp.container; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -440,12 +469,15 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = CookCookMom/CookCookMom.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"CookCookMom/Preview Content\""; - DEVELOPMENT_TEAM = L4S47TM436; + DEVELOPMENT_TEAM = M8JXU75248; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = CookCookMom/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = ChopChopMom; INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "\"CookCookMom\" use bluetooth"; INFOPLIST_KEY_NSBluetoothPeripheralUsageDescription = "\"CookCookMom\" use bluetooth"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -489,6 +521,19 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + 402F505C2A0AB4DE0093C94B /* CookCookMom.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + 402F505D2A0AB4DE0093C94B /* CookCookMom.xcdatamodel */, + ); + currentVersion = 402F505D2A0AB4DE0093C94B /* CookCookMom.xcdatamodel */; + path = CookCookMom.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ }; rootObject = 187ADEF029FA5D8400C4CDCD /* Project object */; } diff --git a/CookCookMom/Assets.xcassets/AppIcon.appiconset/Contents.json b/CookCookMom/Assets.xcassets/AppIcon.appiconset/Contents.json index 13613e3..1915845 100644 --- a/CookCookMom/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/CookCookMom/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,6 +1,7 @@ { "images" : [ { + "filename" : "appIcon.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" diff --git a/CookCookMom/Assets.xcassets/AppIcon.appiconset/appIcon.png b/CookCookMom/Assets.xcassets/AppIcon.appiconset/appIcon.png new file mode 100644 index 0000000..58b8959 Binary files /dev/null and b/CookCookMom/Assets.xcassets/AppIcon.appiconset/appIcon.png differ diff --git a/CookCookMom/Assets.xcassets/LaunchScreenImage.imageset/Contents.json b/CookCookMom/Assets.xcassets/LaunchScreenImage.imageset/Contents.json new file mode 100644 index 0000000..56f20a8 --- /dev/null +++ b/CookCookMom/Assets.xcassets/LaunchScreenImage.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "LaunchScreenImage.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CookCookMom/Assets.xcassets/LaunchScreenImage.imageset/LaunchScreenImage.png b/CookCookMom/Assets.xcassets/LaunchScreenImage.imageset/LaunchScreenImage.png new file mode 100644 index 0000000..4de6dac Binary files /dev/null and b/CookCookMom/Assets.xcassets/LaunchScreenImage.imageset/LaunchScreenImage.png differ diff --git a/CookCookMom/Assets.xcassets/clickCarrot.imageset/Contents.json b/CookCookMom/Assets.xcassets/clickCarrot.imageset/Contents.json new file mode 100644 index 0000000..6b9a13b --- /dev/null +++ b/CookCookMom/Assets.xcassets/clickCarrot.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "clickCarrot.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CookCookMom/Assets.xcassets/clickCarrot.imageset/clickCarrot.svg b/CookCookMom/Assets.xcassets/clickCarrot.imageset/clickCarrot.svg new file mode 100644 index 0000000..0621dca --- /dev/null +++ b/CookCookMom/Assets.xcassets/clickCarrot.imageset/clickCarrot.svg @@ -0,0 +1,35 @@ + + + Group 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CookCookMom/Assets.xcassets/hands.imageset/Contents.json b/CookCookMom/Assets.xcassets/hands.imageset/Contents.json new file mode 100644 index 0000000..2fe1931 --- /dev/null +++ b/CookCookMom/Assets.xcassets/hands.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "hands.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CookCookMom/Assets.xcassets/hands.imageset/hands.svg b/CookCookMom/Assets.xcassets/hands.imageset/hands.svg new file mode 100644 index 0000000..c6ab322 --- /dev/null +++ b/CookCookMom/Assets.xcassets/hands.imageset/hands.svg @@ -0,0 +1,12 @@ + + + Group 4 + + + + + + + + + \ No newline at end of file diff --git a/CookCookMom/Assets.xcassets/momKid.imageset/Contents.json b/CookCookMom/Assets.xcassets/momKid.imageset/Contents.json new file mode 100644 index 0000000..3af7070 --- /dev/null +++ b/CookCookMom/Assets.xcassets/momKid.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "momKid.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/CookCookMom/Assets.xcassets/momKid.imageset/momKid.svg b/CookCookMom/Assets.xcassets/momKid.imageset/momKid.svg new file mode 100644 index 0000000..580c82f --- /dev/null +++ b/CookCookMom/Assets.xcassets/momKid.imageset/momKid.svg @@ -0,0 +1,9 @@ + + + figure.and.child.holdinghands@2x + + + + + + \ No newline at end of file diff --git a/CookCookMom/Constants/SendView.swift b/CookCookMom/Constants/SendView.swift index 4e5a628..6ca5649 100644 --- a/CookCookMom/Constants/SendView.swift +++ b/CookCookMom/Constants/SendView.swift @@ -6,104 +6,226 @@ // import SwiftUI +import CloudKit + +class CloudKitPushNotificationViewModel: ObservableObject { + func requestNotiPermision() { + let option: UNAuthorizationOptions = [.alert,.sound,.badge] + + UNUserNotificationCenter.current().requestAuthorization(options: option) { success, error in + if let error = error { + print(error) + } else if success { + print("notification permissions success!") + DispatchQueue.main.sync { + UIApplication.shared.registerForRemoteNotifications() + } + } else { + print("notification permissions failure!") + } + } + } + + func subscribeToNoti() { + let predicate = NSPredicate(value: true) + let subscription = CKQuerySubscription(recordType: "CD_ChoppedIngredient", predicate: predicate, subscriptionID: "ChoppedIngredient_added_to_database", options: .firesOnRecordCreation ) + let notification = CKSubscription.NotificationInfo() + notification.title = "아이가 재료를 손질해서 보냈어요!" + notification.alertBody = "아이에게 칭찬의 한마디 부탁드립니다 :)" + notification.soundName = "default" + + subscription.notificationInfo = notification + + CKContainer.default().privateCloudDatabase.save(subscription) { returnedSubscription, returnedError in + if let error = returnedError { + print(error) + } else { + print("Successfully subscribed to notifications!") + } + + } + } +} struct SendView: View { - @StateObject var ingredientsViewModel: IngredientsViewModel - @StateObject var peripheral: PeripheralViewModel + + @Environment(\.managedObjectContext) private var viewContext + + @FetchRequest( + sortDescriptors: [NSSortDescriptor(keyPath: \RawIngredients.timestamp, ascending: true)], + animation: .default) + private var rawIngredients: FetchedResults + + @FetchRequest( + sortDescriptors: [NSSortDescriptor(keyPath: \ChoppedIngredient.timestamp, ascending: true)], + animation: .default) + private var choppedIngredients: FetchedResults + + + @ObservedObject var ingredientsViewModel: IngredientsViewModel + + @State private var showModal = false + @State private var showingAlert = false + + @StateObject private var vm = CloudKitPushNotificationViewModel() + + @Environment(\.presentationMode) var presentationMode + @State var isLoading: Bool = true + + @ObservedObject var networkManager = NetworkManager() var body: some View { - ZStack{ - Color(red: 242 / 255, green: 242 / 255, blue: 247 / 255) - .ignoresSafeArea() - VStack { - NotificationButton() - CartView(ingredientsViewModel: ingredientsViewModel) - .padding(10) - Text("아이에게 어떤 재료를 보낼까요?") - .font(.title2) - .bold() - .padding(20) - ForEach(0..<3) { stack in - HStack{ - ForEach(stack*3.. + + + + aps-environment + development + com.apple.developer.icloud-container-identifiers + + iCloud.com.myApp.container + + com.apple.developer.icloud-services + + CloudKit + + + diff --git a/CookCookMom/CookCookMom.xcdatamodeld/CookCookMom.xcdatamodel/contents b/CookCookMom/CookCookMom.xcdatamodeld/CookCookMom.xcdatamodel/contents new file mode 100644 index 0000000..2d97c61 --- /dev/null +++ b/CookCookMom/CookCookMom.xcdatamodeld/CookCookMom.xcdatamodel/contents @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/CookCookMom/CookCookMomApp.swift b/CookCookMom/CookCookMomApp.swift index 454f178..436de55 100644 --- a/CookCookMom/CookCookMomApp.swift +++ b/CookCookMom/CookCookMomApp.swift @@ -9,9 +9,12 @@ import SwiftUI @main struct CookCookMomApp: App { + var body: some Scene { WindowGroup { ContentView() + + } } } diff --git a/CookCookMom/Info.plist b/CookCookMom/Info.plist new file mode 100644 index 0000000..ca9a074 --- /dev/null +++ b/CookCookMom/Info.plist @@ -0,0 +1,10 @@ + + + + + UIBackgroundModes + + remote-notification + + + diff --git a/CookCookMom/Model.xcdatamodeld/Model.xcdatamodel/contents b/CookCookMom/Model.xcdatamodeld/Model.xcdatamodel/contents new file mode 100644 index 0000000..8c8a0fc --- /dev/null +++ b/CookCookMom/Model.xcdatamodeld/Model.xcdatamodel/contents @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/CookCookMom/Model/PersistenceController.swift b/CookCookMom/Model/PersistenceController.swift new file mode 100644 index 0000000..6d18726 --- /dev/null +++ b/CookCookMom/Model/PersistenceController.swift @@ -0,0 +1,68 @@ +// + +// PersistenceController.swift +// CookCookMom +// +// Created by JaeUngJang on 2023/05/10. +// + +import CoreData + +struct PersistenceController { + static let shared = PersistenceController() + + static var preview: PersistenceController = { + let result = PersistenceController(inMemory: true) + let viewContext = result.container.viewContext + for _ in 0..<10 { + let newItem = RawIngredients(context: viewContext) + + newItem.timestamp = Date() + } + do { + try viewContext.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nsError = error as NSError + fatalError("Unresolved error \(nsError), \(nsError.userInfo)") + } + return result + }() + + + let container: NSPersistentCloudKitContainer + + init(inMemory: Bool = false) { + container = NSPersistentCloudKitContainer(name: "CookCookMom") + + if inMemory { + container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") + } + container.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error as NSError? { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + /* + Typical reasons for an error here include: + * The parent directory does not exist, cannot be created, or disallows writing. + * The persistent store is not accessible, due to permissions or data protection when the device is locked. + * The device is out of space. + * The store could not be migrated to the current model version. + Check the error message to determine what the actual problem was. + */ + fatalError("Unresolved error \(error), \(error.userInfo)") + } + }) + container.viewContext.automaticallyMergesChangesFromParent = true + + container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy + do { + try container.viewContext.setQueryGenerationFrom(.current) + } catch { + fatalError("Failed to pin viewContext to the current generation:\(error)") + } + + } +} diff --git a/CookCookMom/View/Components/IngredientButton.swift b/CookCookMom/View/Components/IngredientButton.swift index 052fa36..14d3c6a 100644 --- a/CookCookMom/View/Components/IngredientButton.swift +++ b/CookCookMom/View/Components/IngredientButton.swift @@ -9,7 +9,6 @@ import SwiftUI struct IngredientButton: View { @StateObject var ingredientsViewModel: IngredientsViewModel - @StateObject var peripheral: PeripheralViewModel = PeripheralViewModel() var index: Int diff --git a/CookCookMom/View/Components/SendIngredientsButton.swift b/CookCookMom/View/Components/SendIngredientsButton.swift index ba38c71..f90e231 100644 --- a/CookCookMom/View/Components/SendIngredientsButton.swift +++ b/CookCookMom/View/Components/SendIngredientsButton.swift @@ -8,15 +8,12 @@ import SwiftUI struct SendIngredientsButton: View { - @StateObject var peripheral: PeripheralViewModel = PeripheralViewModel() @StateObject var sendViewModel: IngredientsViewModel @Binding var sendable: Bool var body: some View { Button(action: { - peripheral.message = sendViewModel.sendIngredientsMessage() - print(peripheral.message) - peripheral.isPossibleToSend = sendable + }) { Text("재료 보내기") .frame(width: 280, height: 50) diff --git a/CookCookMom/View/Components/descriptionButton.swift b/CookCookMom/View/Components/descriptionButton.swift new file mode 100644 index 0000000..b201ca8 --- /dev/null +++ b/CookCookMom/View/Components/descriptionButton.swift @@ -0,0 +1,27 @@ +// +// descriptionButton.swift +// CookCookMom +// +// Created by 김수인 on 2023/05/12. +// + +import SwiftUI + +struct descriptionButton: View { + var body: some View { + Button(action: {print("설명")}) { + Image(systemName: "info.circle.fill") + .resizable() + .frame(width: 25, height: 25) + .foregroundColor(.black) + .padding(.top) + .padding(.trailing, 300) + } + } +} + +struct descriptionButton_Previews: PreviewProvider { + static var previews: some View { + descriptionButton() + } +} diff --git a/CookCookMom/View/DescriptionView.swift b/CookCookMom/View/DescriptionView.swift new file mode 100644 index 0000000..e9dc965 --- /dev/null +++ b/CookCookMom/View/DescriptionView.swift @@ -0,0 +1,126 @@ +// +// descriptionView.swift +// CookCookMom +// +// Created by 김수인 on 2023/05/12. +// + +import SwiftUI + +struct DescriptionView: View { + @Environment(\.presentationMode) var presentationMode + var body: some View { + NavigationView { + ScrollView { + VStack { + HStack { + Image("clickCarrot") + .resizable() + .frame(width: 111.31, height: 125.49) + .padding(.leading) + VStack { + Text("재료 선택하기") + .font(.title3) + .bold() + .foregroundColor(.blue) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading,.top,.bottom]) + Text("오늘 할 요리에 들어갈 재료를 선택해주세요.") + .font(.body) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading,.bottom]) + .foregroundColor(.secondary) + } + + } + + HStack { + VStack { + Text("재료 보내기") + .font(.title3) + .bold() + .foregroundColor(.blue) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading,.bottom,.top]) + Text("선택한 재료를 [재료 보내기] 버튼을 눌러 아이에게 보내주세요.") + .font(.body) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading,.bottom]) + .foregroundColor(.secondary) + } + Button { + } label: { + Text("재료 보내기") + .frame(width: 150, height: 46.3) + .fontWeight(.semibold) + .foregroundColor(.white) + .background(Color.blue) + .cornerRadius(30) + }.padding(.trailing) + } + + HStack { + Image("momKid") + .resizable() + .frame(width: 81.39, height: 94) + .padding(.leading) + VStack { + Text("아이와 함께하기") + .font(.title3) + .bold() + .foregroundColor(.blue) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading,.bottom,.top]) + Text("재료를 보내고 아이에게 \n\"오늘 요리 같이 해볼래?\" \n라고 말해주세요.") + .font(.body) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading,.bottom]) + .foregroundColor(.secondary) + } + } + + HStack { + VStack { + Text("아이 칭찬하기") + .font(.title3) + .bold() + .foregroundColor(.blue) + .frame(maxWidth: .infinity, alignment: .leading) + .padding([.leading,.bottom,.top]) + Text("아이가 손질한 재료를 받으면 아이를 칭찬해주세요❤️") + .font(.body) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading) + .foregroundColor(.secondary) + } + Image("hands") + .resizable() + .frame(width: 120.25, height: 91) + .padding(.trailing) + } + + + }//VStack + .navigationTitle("이렇게 써보세요!") + .navigationBarTitleDisplayMode(.large) + .toolbar{ + ToolbarItem(placement: .navigationBarTrailing){ + Button(action: {self.presentationMode.wrappedValue.dismiss()}) {Image(systemName: "xmark") + .foregroundColor(.black) + } + } + + } +// .onTapGesture { +// self.presentationMode.wrappedValue.dismiss() +// } + } + }//ScrollView + }//NavigationView +} +// +//struct DescriptionView_Previews: PreviewProvider { +// static var previews: some View { +// DescriptionView() +// } +//} diff --git a/CookCookMom/View/NotificationListView.swift b/CookCookMom/View/NotificationListView.swift new file mode 100644 index 0000000..8d654f7 --- /dev/null +++ b/CookCookMom/View/NotificationListView.swift @@ -0,0 +1,91 @@ +// +// NotiTestView.swift +// CookCookMom +// +// Created by JaeUngJang on 2023/05/09. +// + +import SwiftUI + +struct NotificationListView: View { + + @Environment(\.managedObjectContext) var managedObjectContext + // 1. + @FetchRequest( + // 2. + entity: ChoppedIngredient.entity(), + // 3. + sortDescriptors: [ + NSSortDescriptor(keyPath: \ChoppedIngredient.timestamp, ascending: false) + ] + //,predicate: NSPredicate(format: "genre contains 'Action'") + // 4. + ) var items: FetchedResults + + @State var isPresented = false + @State var receivedMsg = ["carrot", "mushroom", "fish", "scallion", "onion", "paprika", "potato", "eggplant", "meat"] + + var body: some View { + NavigationView { + List { + ForEach(items, id: \.ingredient) { + NotificationRowView(notification: $0) + } + .onDelete(perform: deleteItem) + } + // .sheet(isPresented: $isPresented) { + // AddMovie { title, genre, release in + // self.addMovie(title: title, genre: genre, releaseDate: release) + // self.isPresented = false + // } + // } + + .listStyle(.automatic) + } + } + + func deleteItem(at offsets: IndexSet) { + // 1. + offsets.forEach { index in + // 2. + let item = self.items[index] + + // 3. + self.managedObjectContext.delete(item) + } + + // 4. + saveContext() + } + + +// func addItem(ingredientName: String, liked: Bool, timestamp: Date) { +// // 1 +// let newItem = Item(context: managedObjectContext) +// +// // 2 +// newItem.ingredientName = ingredientName +// newItem.liked = liked +// newItem.timestamp = timestamp +// +// // 3 +// saveContext() +// } + + + func saveContext() { + do { + try managedObjectContext.save() + } catch { + print("Error saving managed object context: \(error)") + } + } + +} + +struct NotiTestView_Previews: PreviewProvider { + static var previews: some View { + NotificationListView() + } +} + diff --git a/CookCookMom/View/NotificationRowView.swift b/CookCookMom/View/NotificationRowView.swift new file mode 100644 index 0000000..d448fbc --- /dev/null +++ b/CookCookMom/View/NotificationRowView.swift @@ -0,0 +1,91 @@ +// +// NotiRowTestView.swift +// CookCookMom +// +// Created by JaeUngJang on 2023/05/09. +// + +import SwiftUI +import CoreData + +struct NotificationRowView: View { + + let notification: ChoppedIngredient + + static let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "M월 dd일" + return formatter + } () + + static let timeFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.locale = Locale(identifier: "ko_KR") + formatter.timeZone = TimeZone(abbreviation: "KST") + formatter.timeStyle = .short + return formatter + } () + + + + func EngToKor(eng:String?) -> (String?, String?) { + switch eng { + case "carrot3D": + return ("🥕", "당근을") + case "mushroom": + return ("🍄", "버섯을") + case "fish": + return ("🐟", "생선을") + case "scallion": + return ("🧪", "대파를") + case "onion": + return ("🧅", "양파를") + case "paprika": + return ("🫑", "파프리카를") + case "potato": + return ("🥔", "감자를") + case "eggplant": + return ("🍆", "가지를") + case "meat": + return ("🥩", "고기를") + default: + return ("", "") + } + } + + var body: some View { + + HStack { + VStack(alignment: .leading) { +// notification.ingredientName.map(Text.init) +// .font(.body) +// EngToKor(eng: notification.ingredientName).map(Text.init) + + var sentence: (String?, String?) = EngToKor(eng: notification.ingredient) + Text("\(sentence.0!) 아이가 \(sentence.1!) 썰어 보냈습니다.") + .padding(1) + + + HStack { +// Text("\(notification.timestamp!, formatter: NotificationRowView.releaseFormatter)") + let a = notification.timestamp + + notification.timestamp.map { Text(Self.dateFormatter.string(from: $0)) } + .font(.subheadline) + .foregroundColor(.gray) + + notification.timestamp.map { Text(Self.timeFormatter.string(from: $0)) } + .font(.subheadline) + .foregroundColor(.gray) + } + } + Spacer() + } + } +} + +//struct NotiRowTestView_Previews: PreviewProvider { +// static var previews: some View { +// NotificationRowView() +// } +//} diff --git a/CookCookMom/View/SplashView.swift b/CookCookMom/View/SplashView.swift new file mode 100644 index 0000000..2718a32 --- /dev/null +++ b/CookCookMom/View/SplashView.swift @@ -0,0 +1,20 @@ +// +// SplashView.swift +// CookCookMom +// +// Created by 김수인 on 2023/05/13. +// + +import SwiftUI + +struct SplashView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +struct SplashView_Previews: PreviewProvider { + static var previews: some View { + SplashView() + } +} diff --git a/CookCookMom/ViewModel/Peripheral/PeripheralViewModel.swift b/CookCookMom/ViewModel/Peripheral/PeripheralViewModel.swift deleted file mode 100644 index 5a3bd67..0000000 --- a/CookCookMom/ViewModel/Peripheral/PeripheralViewModel.swift +++ /dev/null @@ -1,209 +0,0 @@ -// -// PeripheralViewModel.swift -// CookCookMom -// -// Created by 김예림 on 2023/05/08. -// - -import Foundation -import CoreBluetooth -import os - -class PeripheralViewModel: NSObject, ObservableObject { - - @Published var message: String = "" - @Published var isPossibleToSend: Bool = false - - - @Published var isSent: Bool = false - var peripheralManager: CBPeripheralManager! - var transferCharacteristic: CBMutableCharacteristic? - var connectedCentral: CBCentral? - var dataToSend = Data() - var sendDataIndex: Int = 0 - - - override init() { - super.init() - peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: [CBPeripheralManagerOptionShowPowerAlertKey: true]) - } - - // switch 메소드 - true 일 때, - func switchChanged() { - if isPossibleToSend { - peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [TransferService.serviceUUID]]) - - } else { - stopAction() - } - } - - // 뷰 나갈 시, 종료 - func stopAction() { - peripheralManager.stopAdvertising() - } - - - private func setUpPeripheral() { - let transferCharacteristic = CBMutableCharacteristic(type: TransferService.characteristicUUID, - properties: [.notify, .writeWithoutResponse], - value: nil, - permissions: [.readable, .writeable]) - - let transferService = CBMutableService(type: TransferService.serviceUUID, primary: true) - - transferService.characteristics = [transferCharacteristic] - - peripheralManager.add(transferService) - - self.transferCharacteristic = transferCharacteristic - } - - static var sendingEOM = false - - private func sendData() { - - guard let transferCharacteristic = transferCharacteristic else { - return - } - - - if PeripheralViewModel.sendingEOM { - let didSend = peripheralManager.updateValue("EOM".data(using: .utf8)!, for: - transferCharacteristic, onSubscribedCentrals: nil) - - if didSend { - PeripheralViewModel.sendingEOM = false - print("Sent: EOM") - isSent = true - } - return - } - - if sendDataIndex >= dataToSend.count { - return - } - - var didSend = true - while didSend { - - var amountToSend = dataToSend.count - sendDataIndex - if let mtu = connectedCentral?.maximumUpdateValueLength { - amountToSend = min(amountToSend, mtu) - } - - - let chunk = dataToSend.subdata(in: sendDataIndex..<(sendDataIndex + amountToSend)) - - didSend = peripheralManager.updateValue(chunk, for: transferCharacteristic, onSubscribedCentrals: nil) - - - if !didSend { - return - } - - let stringFromData = String(data: chunk, encoding: .utf8) - print("Sent \(chunk.count) bytes: \(String(describing: stringFromData))") - - - sendDataIndex += amountToSend - - if sendDataIndex >= dataToSend.count { - - PeripheralViewModel.sendingEOM = true - - - let eomSent = peripheralManager.updateValue("EOM".data(using: .utf8)!, - for: transferCharacteristic, onSubscribedCentrals: nil) - if eomSent { - - PeripheralViewModel.sendingEOM = false - print("Sent: EOM") - isPossibleToSend = false - } - return - } - } - } -} - - -extension PeripheralViewModel: CBPeripheralManagerDelegate { - func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { - -// isPossibleToSend = peripheral.state == .poweredOn - - switch peripheral.state { - case .poweredOn: - print(".powerOn") - setUpPeripheral() - return - - case .poweredOff : - print(".powerOff") - return - - case .resetting: - print(".restting") - return - - case .unauthorized: - print(".unauthorized") - return - - case .unknown: - print(".unknown") - return - - case .unsupported: - print(".unsupported") - return - - default: - print("A previously unknown central manager state occurred") - return - } - } - - - func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) { - print("Central subscribed to characteristic") - - if let message = message.data(using: .utf8) { - dataToSend = message - } - - sendDataIndex = 0 - - connectedCentral = central - - - sendData() - } - - - func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) { - print("Central unsubscribed from characteristic") - connectedCentral = nil - } - - - func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) { - sendData() - } - - - func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) { - for aRequest in requests { - guard let requestValue = aRequest.value, - let stringFromData = String(data: requestValue, encoding: .utf8) else { - continue - } - - print("Received write request of \(requestValue.count) bytes: \(stringFromData)") - message = stringFromData - } - } -} - - diff --git a/CookCookMom/ViewModel/SendIngredients/IngredientsViewModel.swift b/CookCookMom/ViewModel/SendIngredients/IngredientsViewModel.swift index a98d660..c24858d 100644 --- a/CookCookMom/ViewModel/SendIngredients/IngredientsViewModel.swift +++ b/CookCookMom/ViewModel/SendIngredients/IngredientsViewModel.swift @@ -6,11 +6,13 @@ // import Foundation +import CloudKit class IngredientsViewModel : ObservableObject { @Published var ingredientModels : [IngredientModel] @Published var sendMessage: String = "" @Published var canSend: Bool = false + @Published var newNoti: Bool = false var clickCount: Int = 0 { didSet { @@ -55,7 +57,15 @@ class IngredientsViewModel : ObservableObject { } clickCount = 0 } + + //알람 확인 함수 + func checkNotification() { + self.newNoti = false + } + + //새로운 알람 올 경우 + func newNotification() { + self.newNoti = true + } + } - - - diff --git a/Utils/NetworkManager.swift b/Utils/NetworkManager.swift new file mode 100644 index 0000000..2716cb6 --- /dev/null +++ b/Utils/NetworkManager.swift @@ -0,0 +1,60 @@ +// +// NetworkManager.swift +// CookCookMom +// +// Created by 박승찬 on 2023/05/15. +// + +import Foundation +import Network // Let's import Network +class NetworkManager: ObservableObject { + let monitor = NWPathMonitor() + let queue = DispatchQueue(label: "NetworkManager") + + @Published var isConnected = true + @Published var isntConnected = false + + // Image depends the network status. + var imageName: String { + return isConnected ? "wifi" : "wifi.slash" + } + + // Text depends on the network status. + var connectionDescription: String { + if isConnected { + return "Internet connection looks good!" + } else { + return "It looks like you're not connected to the internet" + } + } + + init() { + monitor.pathUpdateHandler = { path in + DispatchQueue.main.async { + self.isConnected = path.status == .satisfied + self.isntConnected = !self.isConnected + } + } + + monitor.start(queue: queue) + } + + // method working when you touch 'Check Status' button. + func startMonitoring() { + monitor.start(queue: queue) + monitor.pathUpdateHandler = { path in + self.isConnected = path.status == .satisfied + self.isntConnected = !self.isConnected + if path.usesInterfaceType(.wifi) { + print("Using wifi") + } else if path.usesInterfaceType(.cellular) { + print("Using cellular") + } + } + } + + // method stop checking. + func stopMonitoring() { + monitor.cancel() + } +}