From 49ebf4290454b31b8dc04b360e7a9d43c5623d40 Mon Sep 17 00:00:00 2001 From: Vin Bui Date: Fri, 21 Jun 2024 13:00:10 -0400 Subject: [PATCH 01/16] Remove codegen build phase --- README.md | 24 +++++------------------- TCAT.xcodeproj/project.pbxproj | 20 -------------------- 2 files changed, 5 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 2fb87ed7..ea0ac48b 100644 --- a/README.md +++ b/README.md @@ -36,31 +36,17 @@ fi ``` -- There should also be another run script labeled **UpliftAPI** If not, create a **New Run Script Phase** with the following script: - -```bash -CLI_PATH="./Pods/Apollo/apollo-ios-cli" -SECRETS_PATH="${SRCROOT}/TransitSecrets" - -if [ "${CONFIGURATION}" != "Release" ]; then - CONFIG_PATH="${SECRETS_PATH}/uplift-codegen-config-dev.json" -fi - -if [ "${CONFIGURATION}" = "Release" ]; then - CONFIG_PATH="${SECRETS_PATH}/uplift-codegen-config-prod.json" -fi +5. Select the `TCAT Debug` schema to use our development server and `TCAT Release` to use our production server. +6. Generate the Uplift API: -"${CLI_PATH}" generate -p "${CONFIG_PATH}" -f +- Dev: `./Pods/Apollo/apollo-ios-cli generate -p "TransitSecrets/uplift-codegen-config-dev.json" -f` +- Prod: `./Pods/Apollo/apollo-ios-cli generate -p "TransitSecrets/uplift-codegen-config-prod.json" -f` -``` - -5. Select the `TCAT Debug` schema to use our development server and `TCAT Release` to use our production server. -6. Generate the Uplift API with the following command: `./Pods/Apollo/apollo-ios-cli generate -p "TransitSecrets/uplift-codegen-config-dev.json" -f` 7. Build the project and you should be good to go. ## Common Issues -- If the build script for generating the API folder doesn't work, you can manually generate the API via `./Pods/Apollo/apollo-ios-cli generate -p "TransitSecrets/uplift-codegen-config-dev.json" -f` +- If the API is not working properly, try manually generating the API with the CLI. - If UpliftAPI is not detected or if your new written queries/mutations are not generated by Apollo, make sure that the generated UpliftAPI folder is linked to the TCAT target. You can do this by simply deleting the UpliftAPI group via the project navigator on Xcode and dragging the generated UpliftAPI folder from Finder to Xcode. diff --git a/TCAT.xcodeproj/project.pbxproj b/TCAT.xcodeproj/project.pbxproj index 3150cc59..7dfabf64 100644 --- a/TCAT.xcodeproj/project.pbxproj +++ b/TCAT.xcodeproj/project.pbxproj @@ -622,7 +622,6 @@ 2292F9DB215722ED00C8C931 /* SwiftLint */, 7E14AED52177E846006A344D /* Embed Foundation Extensions */, CE26CBF62B879837005D099A /* Crashlytics */, - 2E9416612BC60AE7003DEB44 /* UpliftAPI */, 882B9E91268F347446806E32 /* [CP] Embed Pods Frameworks */, 0B4CA64206AF6DA1763F9ACB /* [CP] Copy Pods Resources */, ); @@ -743,25 +742,6 @@ shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\"\n\nif which swiftlint >/dev/null; then\n swiftlint --fix && swiftlint\nelse\n echo \"WARNING: SwiftLint not installed\"\nfi\n"; }; - 2E9416612BC60AE7003DEB44 /* UpliftAPI */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = UpliftAPI; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "CLI_PATH=\"./Pods/Apollo/apollo-ios-cli\"\nSECRETS_PATH=\"${SRCROOT}/TransitSecrets\"\n\nif [ \"${CONFIGURATION}\" != \"Release\" ]; then\n CONFIG_PATH=\"${SECRETS_PATH}/uplift-codegen-config-dev.json\"\nfi\n\nif [ \"${CONFIGURATION}\" = \"Release\" ]; then\n CONFIG_PATH=\"${SECRETS_PATH}/uplift-codegen-config-prod.json\"\nfi\n\n\"${CLI_PATH}\" generate -p \"${CONFIG_PATH}\" -f\n"; - }; 882B9E91268F347446806E32 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; From 5fb58bf1c9c46e33a37a04c36c55ed3d70ea8aa8 Mon Sep 17 00:00:00 2001 From: cindy-x-liang <67083541+cindy-x-liang@users.noreply.github.com> Date: Sun, 4 Aug 2024 19:21:01 -0600 Subject: [PATCH 02/16] add route filtering --- TCAT/Controllers/HomeMapViewController.swift | 1 + .../HomeOptionsCardViewController.swift | 1 - TCAT/Controllers/SearchResultsViewController.swift | 1 + TCAT/Models/SearchManager.swift | 14 +++++++++++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/TCAT/Controllers/HomeMapViewController.swift b/TCAT/Controllers/HomeMapViewController.swift index 23e24a17..1739c44e 100644 --- a/TCAT/Controllers/HomeMapViewController.swift +++ b/TCAT/Controllers/HomeMapViewController.swift @@ -36,6 +36,7 @@ class HomeMapViewController: UIViewController { private let loadingIndicatorSize = CGSize.init(width: 40, height: 40) private let userDefaults = UserDefaults.standard + override func viewDidLoad() { super.viewDidLoad() diff --git a/TCAT/Controllers/HomeOptionsCardViewController.swift b/TCAT/Controllers/HomeOptionsCardViewController.swift index 0823cd3e..a9e56051 100644 --- a/TCAT/Controllers/HomeOptionsCardViewController.swift +++ b/TCAT/Controllers/HomeOptionsCardViewController.swift @@ -300,7 +300,6 @@ class HomeOptionsCardViewController: UIViewController { } // MARK: - Get Search Results - /// Get Search Results @objc func getPlaces(timer: Timer) { if let userInfo = timer.userInfo as? [String: String], diff --git a/TCAT/Controllers/SearchResultsViewController.swift b/TCAT/Controllers/SearchResultsViewController.swift index 73633253..8bb2d695 100755 --- a/TCAT/Controllers/SearchResultsViewController.swift +++ b/TCAT/Controllers/SearchResultsViewController.swift @@ -153,6 +153,7 @@ class SearchResultsViewController: UIViewController { } @objc private func getPlaces(timer: Timer) { + print("here") if let userInfo = timer.userInfo as? [String: String], let searchText = userInfo["searchText"], !searchText.isEmpty { diff --git a/TCAT/Models/SearchManager.swift b/TCAT/Models/SearchManager.swift index 2d46a866..71e98fbf 100644 --- a/TCAT/Models/SearchManager.swift +++ b/TCAT/Models/SearchManager.swift @@ -25,6 +25,9 @@ class SearchManager: NSObject { private let networking: Networking = URLSession.shared.request private let searchCompleter = MKLocalSearchCompleter() private var searchResults = [MKLocalSearchCompletion]() + + private let gshLat = 42.442558 + private let gshLong = -76.485336 override private init() { super.init() @@ -41,6 +44,13 @@ class SearchManager: NSObject { ) } } + private func sortLocations(_ s1: Place, _ s2: Place) -> Bool { + let s1Check = pow((s1.latitude-(self.gshLat)),2.0) + pow((s1.longitude-(self.gshLong)),2.0) + + let s2Check = pow((s2.latitude-(self.gshLat)),2.0) + pow((s2.longitude-(self.gshLong)),2.0) + return s1Check < s2Check + } + func performLookup(for query: String, completionHandler: @escaping SearchManagerCallback) { getAppleSearchResults(searchText: query).observe { [weak self] result in @@ -55,7 +65,9 @@ class SearchManager: NSObject { // If the list of Apple Places for this query already exists in // server cache, no further work is needed if let applePlaces = response.data.applePlaces { - let searchResults = applePlaces + busStops + let updatedApplePlaces = applePlaces.sorted(by: self.sortLocations) + + let searchResults = updatedApplePlaces + busStops completionHandler(searchResults, nil) } else { // Otherwise, we need to perform the Apple Places lookup locally From 398c5cb7da678c3c7f73b6034a9a93547321dc11 Mon Sep 17 00:00:00 2001 From: cindy-x-liang <67083541+cindy-x-liang@users.noreply.github.com> Date: Sun, 4 Aug 2024 19:25:23 -0600 Subject: [PATCH 03/16] deleted debugging stuff --- TCAT/Controllers/HomeMapViewController.swift | 1 - TCAT/Controllers/HomeOptionsCardViewController.swift | 1 + TCAT/Controllers/SearchResultsViewController.swift | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/TCAT/Controllers/HomeMapViewController.swift b/TCAT/Controllers/HomeMapViewController.swift index 1739c44e..23e24a17 100644 --- a/TCAT/Controllers/HomeMapViewController.swift +++ b/TCAT/Controllers/HomeMapViewController.swift @@ -36,7 +36,6 @@ class HomeMapViewController: UIViewController { private let loadingIndicatorSize = CGSize.init(width: 40, height: 40) private let userDefaults = UserDefaults.standard - override func viewDidLoad() { super.viewDidLoad() diff --git a/TCAT/Controllers/HomeOptionsCardViewController.swift b/TCAT/Controllers/HomeOptionsCardViewController.swift index a9e56051..0ebba13a 100644 --- a/TCAT/Controllers/HomeOptionsCardViewController.swift +++ b/TCAT/Controllers/HomeOptionsCardViewController.swift @@ -300,6 +300,7 @@ class HomeOptionsCardViewController: UIViewController { } // MARK: - Get Search Results + /// Get Search Results @objc func getPlaces(timer: Timer) { if let userInfo = timer.userInfo as? [String: String], diff --git a/TCAT/Controllers/SearchResultsViewController.swift b/TCAT/Controllers/SearchResultsViewController.swift index 8bb2d695..73633253 100755 --- a/TCAT/Controllers/SearchResultsViewController.swift +++ b/TCAT/Controllers/SearchResultsViewController.swift @@ -153,7 +153,6 @@ class SearchResultsViewController: UIViewController { } @objc private func getPlaces(timer: Timer) { - print("here") if let userInfo = timer.userInfo as? [String: String], let searchText = userInfo["searchText"], !searchText.isEmpty { From caf8aafce69c2435fc957f0dcf5344313f57c79f Mon Sep 17 00:00:00 2001 From: cindy-x-liang <67083541+cindy-x-liang@users.noreply.github.com> Date: Sat, 21 Sep 2024 21:31:41 -0400 Subject: [PATCH 04/16] Added firebase messaging to iOS --- Podfile | 1 + Podfile.lock | 17 +++++++- TCAT.xcodeproj/project.pbxproj | 12 +++++- TCAT/Base/AppDelegate.swift | 69 ++++++++++++++++++++++++++++++- TCAT/Supporting/Info.plist | 2 + TCAT/Supporting/TCAT.entitlements | 2 + TCAT/TCATDebug.entitlements | 12 ++++++ TCAT/TCATLocal.entitlements | 12 ++++++ 8 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 TCAT/TCATDebug.entitlements create mode 100644 TCAT/TCATLocal.entitlements diff --git a/Podfile b/Podfile index 7c2b6f10..482be536 100644 --- a/Podfile +++ b/Podfile @@ -21,6 +21,7 @@ target 'TCAT' do # Analytics pod 'Firebase' pod 'FirebaseCrashlytics' + pod 'Firebase/Messaging' # File Management pod 'Zip', '~> 1.1' diff --git a/Podfile.lock b/Podfile.lock index f5a62843..f3cd992e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -10,6 +10,9 @@ PODS: - FirebaseAnalytics (~> 10.24.0) - Firebase/CoreOnly (10.24.0): - FirebaseCore (= 10.24.0) + - Firebase/Messaging (10.24.0): + - Firebase/CoreOnly + - FirebaseMessaging (~> 10.24.0) - FirebaseAnalytics (10.24.0): - FirebaseAnalytics/AdIdSupport (= 10.24.0) - FirebaseCore (~> 10.0) @@ -50,6 +53,15 @@ PODS: - GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/UserDefaults (~> 7.8) - PromisesObjC (~> 2.1) + - FirebaseMessaging (10.24.0): + - FirebaseCore (~> 10.0) + - FirebaseInstallations (~> 10.0) + - GoogleDataTransport (~> 9.3) + - GoogleUtilities/AppDelegateSwizzler (~> 7.8) + - GoogleUtilities/Environment (~> 7.8) + - GoogleUtilities/Reachability (~> 7.8) + - GoogleUtilities/UserDefaults (~> 7.8) + - nanopb (< 2.30911.0, >= 2.30908.0) - FirebaseRemoteConfigInterop (10.24.0) - FirebaseSessions (10.24.0): - FirebaseCore (~> 10.5) @@ -142,6 +154,7 @@ DEPENDENCIES: - Apollo (~> 1.9.3) - DZNEmptyDataSet (from `https://github.com/cuappdev/DZNEmptyDataSet.git`) - Firebase + - Firebase/Messaging - FirebaseCrashlytics - FutureNova (from `https://github.com/cuappdev/ios-networking.git`) - GoogleMaps @@ -165,6 +178,7 @@ SPEC REPOS: - FirebaseCoreInternal - FirebaseCrashlytics - FirebaseInstallations + - FirebaseMessaging - FirebaseRemoteConfigInterop - FirebaseSessions - GoogleAppMeasurement @@ -213,6 +227,7 @@ SPEC CHECKSUMS: FirebaseCoreInternal: bcb5acffd4ea05e12a783ecf835f2210ce3dc6af FirebaseCrashlytics: af38ea4adfa606f6e63fcc22091b61e7938fcf66 FirebaseInstallations: 8f581fca6478a50705d2bd2abd66d306e0f5736e + FirebaseMessaging: 4d52717dd820707cc4eadec5eb981b4832ec8d5d FirebaseRemoteConfigInterop: 6c349a466490aeace3ce9c091c86be1730711634 FirebaseSessions: 2651b464e241c93fd44112f995d5ab663c970487 FutureNova: 95f9aa352b2c250253b96fdf380754afcc87c7f3 @@ -234,6 +249,6 @@ SPEC CHECKSUMS: Wormholy: ab1c8c2f02f58587a0941deb0088555ffbf039a1 Zip: 8877eede3dda76bcac281225c20e71c25270774c -PODFILE CHECKSUM: a3b80dd04ea30998a17c032f2730e21ee8517238 +PODFILE CHECKSUM: 03571a87e3df2cb79c3c62b5bd19cd6713131c52 COCOAPODS: 1.15.2 diff --git a/TCAT.xcodeproj/project.pbxproj b/TCAT.xcodeproj/project.pbxproj index 7dfabf64..7871ee40 100644 --- a/TCAT.xcodeproj/project.pbxproj +++ b/TCAT.xcodeproj/project.pbxproj @@ -127,6 +127,7 @@ BF74AC1E1F945D8E00AFD4E4 /* GoogleMaps.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF74AC1C1F945D8E00AFD4E4 /* GoogleMaps.framework */; }; D4756EA223986CB500FE7F0D /* ReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4756EA123986CB500FE7F0D /* ReachabilityManager.swift */; }; DD3D9C211F94297100B164D4 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3D9C201F94297100B164D4 /* Reachability.swift */; }; + EEB26AE22C9F9B9A002E863F /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEB26AE12C9F9B9A002E863F /* UserNotifications.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -271,6 +272,9 @@ BF74AC1C1F945D8E00AFD4E4 /* GoogleMaps.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleMaps.framework; path = Pods/GoogleMaps/Maps/Frameworks/GoogleMaps.framework; sourceTree = ""; }; D4756EA123986CB500FE7F0D /* ReachabilityManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReachabilityManager.swift; sourceTree = ""; }; DD3D9C201F94297100B164D4 /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; }; + EEB26AE02C9F998C002E863F /* TCATLocal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TCATLocal.entitlements; sourceTree = ""; }; + EEB26AE12C9F9B9A002E863F /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; }; + EEB26AE32C9FA60E002E863F /* TCATDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TCATDebug.entitlements; sourceTree = ""; }; FD69AF2A2B89212F00970C7E /* ci_post_clone.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_post_clone.sh; sourceTree = ""; }; /* End PBXFileReference section */ @@ -279,6 +283,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + EEB26AE22C9F9B9A002E863F /* UserNotifications.framework in Frameworks */, BF74AC1D1F945D8E00AFD4E4 /* GoogleMapsCore.framework in Frameworks */, BF74AC1E1F945D8E00AFD4E4 /* GoogleMaps.framework in Frameworks */, BF74AC1A1F945D7D00AFD4E4 /* GoogleMapsBase.framework in Frameworks */, @@ -292,6 +297,7 @@ 12F774CEB5023E6938BDCF3A /* Frameworks */ = { isa = PBXGroup; children = ( + EEB26AE12C9F9B9A002E863F /* UserNotifications.framework */, BF74AC1C1F945D8E00AFD4E4 /* GoogleMaps.framework */, BF74AC1B1F945D8E00AFD4E4 /* GoogleMapsCore.framework */, BF74AC191F945D7D00AFD4E4 /* GoogleMapsBase.framework */, @@ -575,6 +581,8 @@ 449A7C771D80D0E80019300C /* TCAT */ = { isa = PBXGroup; children = ( + EEB26AE32C9FA60E002E863F /* TCATDebug.entitlements */, + EEB26AE02C9F998C002E863F /* TCATLocal.entitlements */, 449A7C7F1D80D0E80019300C /* Assets.xcassets */, 2E70434D2BB75E10003AC1D6 /* PrivacyInfo.xcprivacy */, 2E9416662BC615B0003DEB44 /* Base */, @@ -1077,7 +1085,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; BUNDLE_APP_DISPLAY_NAME = "Ithaca Transit Beta"; - CODE_SIGN_ENTITLEMENTS = TCAT/Supporting/TCAT.entitlements; + CODE_SIGN_ENTITLEMENTS = TCAT/TCATDebug.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; @@ -1176,7 +1184,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; BUNDLE_APP_DISPLAY_NAME = "Ithaca Transit Local"; - CODE_SIGN_ENTITLEMENTS = TCAT/Supporting/TCAT.entitlements; + CODE_SIGN_ENTITLEMENTS = TCAT/TCATLocal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; diff --git a/TCAT/Base/AppDelegate.swift b/TCAT/Base/AppDelegate.swift index fc137710..1a05a5e3 100755 --- a/TCAT/Base/AppDelegate.swift +++ b/TCAT/Base/AppDelegate.swift @@ -13,12 +13,13 @@ import Intents import SafariServices import SwiftyJSON import UIKit +import FirebaseMessaging /// This is used for app-specific preferences let userDefaults = UserDefaults.standard @UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { +class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate { var window: UIWindow? private let encoder = JSONEncoder() @@ -36,7 +37,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Set Up Google Services FirebaseApp.configure() - + GMSServices.provideAPIKey(TransitEnvironment.googleMaps) // Update shortcut items @@ -90,6 +91,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate { self.window = UIWindow(frame: UIScreen.main.bounds) self.window?.rootViewController = navigationController self.window?.makeKeyAndVisible() + + //Set up notifications + UNUserNotificationCenter.current().delegate = self + + let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] + UNUserNotificationCenter.current().requestAuthorization( + options: authOptions, + completionHandler: { _, _ in } + ) + + application.registerForRemoteNotifications() + + + Messaging.messaging().delegate = self + + + + + + return true } @@ -97,6 +118,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { handleShortcut(item: shortcutItem) } + + func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { + Messaging.messaging().apnsToken = deviceToken + Messaging.messaging().token { token, error in + if let error = error { + print("Error fetching FCM registration token: \(error)") + } else if let token = token { + print("FCM registration token: \(token)") + + } + } + + } + func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { + print("application didFailToRegisterForRemoteNotificationsWithError") + } // MARK: - Helper Functions @@ -206,3 +243,31 @@ extension UIWindow { } } + +extension AppDelegate { + +//MessagingDelegate +// func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { +// self.firebaseToken = fcmToken! +// print("Firebase token: \(fcmToken)") +// } + + func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { + print("Firebase registration token: \(String(describing: fcmToken))") + + let dataDict: [String: String] = ["token": fcmToken ?? ""] + NotificationCenter.default.post( + name: Notification.Name("FCMToken"), + object: nil, + userInfo: dataDict + ) + // TODO: If necessary send token to application server. + // Note: This callback is fired at each app startup and whenever a new token is generated. + } + + //UNUserNotificationCenterDelegate + func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { + print("APNs received with: \(userInfo)") + } + +} diff --git a/TCAT/Supporting/Info.plist b/TCAT/Supporting/Info.plist index d54da69f..2e3c25cb 100755 --- a/TCAT/Supporting/Info.plist +++ b/TCAT/Supporting/Info.plist @@ -69,7 +69,9 @@ UIBackgroundModes + fetch location + remote-notification UILaunchStoryboardName LaunchScreen diff --git a/TCAT/Supporting/TCAT.entitlements b/TCAT/Supporting/TCAT.entitlements index 410c063f..531c4668 100644 --- a/TCAT/Supporting/TCAT.entitlements +++ b/TCAT/Supporting/TCAT.entitlements @@ -2,6 +2,8 @@ + aps-environment + development com.apple.security.application-groups group.tcat diff --git a/TCAT/TCATDebug.entitlements b/TCAT/TCATDebug.entitlements new file mode 100644 index 00000000..531c4668 --- /dev/null +++ b/TCAT/TCATDebug.entitlements @@ -0,0 +1,12 @@ + + + + + aps-environment + development + com.apple.security.application-groups + + group.tcat + + + diff --git a/TCAT/TCATLocal.entitlements b/TCAT/TCATLocal.entitlements new file mode 100644 index 00000000..531c4668 --- /dev/null +++ b/TCAT/TCATLocal.entitlements @@ -0,0 +1,12 @@ + + + + + aps-environment + development + com.apple.security.application-groups + + group.tcat + + + From b64690f1305610e6bd6d26e764e71991f32b5bb5 Mon Sep 17 00:00:00 2001 From: cindy-x-liang <67083541+cindy-x-liang@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:08:51 -0400 Subject: [PATCH 05/16] addressing richie's comments --- TCAT/Base/AppDelegate.swift | 51 +++++++++++++------------------------ 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/TCAT/Base/AppDelegate.swift b/TCAT/Base/AppDelegate.swift index 1a05a5e3..351a8286 100755 --- a/TCAT/Base/AppDelegate.swift +++ b/TCAT/Base/AppDelegate.swift @@ -100,18 +100,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUser options: authOptions, completionHandler: { _, _ in } ) - application.registerForRemoteNotifications() - - Messaging.messaging().delegate = self - - - - - - return true } @@ -122,15 +113,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUser func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { Messaging.messaging().apnsToken = deviceToken Messaging.messaging().token { token, error in - if let error = error { - print("Error fetching FCM registration token: \(error)") - } else if let token = token { - print("FCM registration token: \(token)") - - } + if let error = error { + print("Error fetching FCM registration token: \(error)") + } else if let token = token { + print("FCM registration token: \(token)") + + } } - - } + + } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("application didFailToRegisterForRemoteNotificationsWithError") } @@ -245,24 +236,18 @@ extension UIWindow { } extension AppDelegate { - -//MessagingDelegate -// func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { -// self.firebaseToken = fcmToken! -// print("Firebase token: \(fcmToken)") -// } func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { - print("Firebase registration token: \(String(describing: fcmToken))") - - let dataDict: [String: String] = ["token": fcmToken ?? ""] - NotificationCenter.default.post( - name: Notification.Name("FCMToken"), - object: nil, - userInfo: dataDict - ) - // TODO: If necessary send token to application server. - // Note: This callback is fired at each app startup and whenever a new token is generated. + print("Firebase registration token: \(String(describing: fcmToken))") + + let dataDict: [String: String] = ["token": fcmToken ?? ""] + NotificationCenter.default.post( + name: Notification.Name("FCMToken"), + object: nil, + userInfo: dataDict + ) + // TODO: If necessary send token to application server. + // Note: This callback is fired at each app startup and whenever a new token is generated. } //UNUserNotificationCenterDelegate From f6f082c649b10393cddce75cf884b44dc8ec1646 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Wed, 16 Oct 2024 15:19:50 -0400 Subject: [PATCH 06/16] Show delay times for start & end, needs double checked with backend --- TCAT/Views/DetailIconView.swift | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/TCAT/Views/DetailIconView.swift b/TCAT/Views/DetailIconView.swift index ae9dde0f..4fca643d 100755 --- a/TCAT/Views/DetailIconView.swift +++ b/TCAT/Views/DetailIconView.swift @@ -154,9 +154,21 @@ class DetailIconView: UIView { setTimeLabelTexts(for: direction, isLastStep: isLast) if direction.type == .walk { - scheduledTimeLabel.textColor = Colors.primaryText - centerScheduledLabel() - hideDelayedLabel() + if let delay = direction.delay { + if delay < 60 { + scheduledTimeLabel.textColor = Colors.liveGreen + centerScheduledLabel() + hideDelayedLabel() + } else { + scheduledTimeLabel.textColor = Colors.primaryText + showDelayedLabel() + offsetScheduledLabel() + } + } else { + scheduledTimeLabel.textColor = Colors.primaryText + hideDelayedLabel() + centerScheduledLabel() + } } else { if let delay = direction.delay { if delay < 60 { From 0b75754d9aa46404a00a05112f75564aff953c3c Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Sun, 27 Oct 2024 23:54:11 -0400 Subject: [PATCH 07/16] Modified / improved route UI --- TCAT/Assets.xcassets/Contents.json | 6 +- .../locationMarker.imageset/Contents.json | 21 +++ .../locationMarker.png | Bin 0 -> 7250 bytes .../spriteGrey.imageset/Contents.json | 21 +++ .../spriteGrey.imageset/sprite_grey.png | Bin 0 -> 53522 bytes .../RouteDetail+ContentViewController.swift | 148 ++++++++++++++++++ ...tailContentViewController+Extensions.swift | 2 + TCAT/Models/BusPath.swift | 2 +- TCAT/Models/WalkPath.swift | 43 ++++- 9 files changed, 231 insertions(+), 12 deletions(-) create mode 100644 TCAT/Assets.xcassets/locationMarker.imageset/Contents.json create mode 100644 TCAT/Assets.xcassets/locationMarker.imageset/locationMarker.png create mode 100644 TCAT/Assets.xcassets/spriteGrey.imageset/Contents.json create mode 100644 TCAT/Assets.xcassets/spriteGrey.imageset/sprite_grey.png diff --git a/TCAT/Assets.xcassets/Contents.json b/TCAT/Assets.xcassets/Contents.json index da4a164c..73c00596 100755 --- a/TCAT/Assets.xcassets/Contents.json +++ b/TCAT/Assets.xcassets/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/TCAT/Assets.xcassets/locationMarker.imageset/Contents.json b/TCAT/Assets.xcassets/locationMarker.imageset/Contents.json new file mode 100644 index 00000000..39ebecab --- /dev/null +++ b/TCAT/Assets.xcassets/locationMarker.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "locationMarker.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/TCAT/Assets.xcassets/locationMarker.imageset/locationMarker.png b/TCAT/Assets.xcassets/locationMarker.imageset/locationMarker.png new file mode 100644 index 0000000000000000000000000000000000000000..3dd3df326e1d208e9b17a4da8c1170dfe138cb91 GIT binary patch literal 7250 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 U-{IvFRMNNQRc>ZnzyI`q0Uo0WO#lD@ literal 0 HcmV?d00001 diff --git a/TCAT/Controllers/RouteDetail+ContentViewController.swift b/TCAT/Controllers/RouteDetail+ContentViewController.swift index 4bf4f602..ae846e2e 100755 --- a/TCAT/Controllers/RouteDetail+ContentViewController.swift +++ b/TCAT/Controllers/RouteDetail+ContentViewController.swift @@ -453,9 +453,38 @@ class RouteDetailContentViewController: UIViewController { } }() } + private var firstRouteSegment: [GMSCircle] = [] + private var secondRouteSegment: [GMSCircle] = [] + private var finalRouteSegment: [GMSCircle] = [] + private var finalDestinationCircles: [GMSCircle] = [] + private var finalDestinationMarkers: [GMSMarker] = [] + let firstWalkSegment = GMSMutablePath() + let secondWalkSegment = GMSMutablePath() + let finalWalkSegment = GMSMutablePath() + + private func createWalkPathCircle() -> UIImage { + let fillColor = UIColor(white: 0.82, alpha: 1.0) + let borderColor = UIColor(white: 0.57, alpha: 1.0) + let diameter: CGFloat = 70.0 + let borderWidth: CGFloat = 13.0 + + let renderer = UIGraphicsImageRenderer(size: CGSize(width: diameter, height: diameter)) + return renderer.image { context in + context.cgContext.setFillColor(borderColor.cgColor) + context.cgContext.setStrokeColor(borderColor.cgColor) + context.cgContext.setLineWidth(borderWidth) + context.cgContext.addEllipse(in: CGRect(x: borderWidth / 2, y: borderWidth / 2, width: diameter - borderWidth, height: diameter - borderWidth)) + context.cgContext.drawPath(using: .fillStroke) + + context.cgContext.setFillColor(fillColor.cgColor) + context.cgContext.addEllipse(in: CGRect(x: borderWidth, y: borderWidth, width: diameter - 2 * borderWidth, height: diameter - 2 * borderWidth)) + context.cgContext.fillPath() + } + } /// Draw all waypoints initially for all paths in [Path] or [[CLLocationCoordinate2D]], plus fill bounds private func drawMapRoute() { + var pathCount = 0 for path in paths { path.traveledPolyline.map = mapView path.map = mapView @@ -466,6 +495,125 @@ class RouteDetailContentViewController: UIViewController { setIndex(of: marker, with: waypoint.wpType) bounds = bounds.includingCoordinate(waypoint.coordinate) } + if let busPath = path as? BusPath { + // Helper function for creating bus stop circles + func busStopCircles(at coordinate: CLLocationCoordinate2D, on mapView: GMSMapView) -> GMSCircle { + let circle = GMSCircle(position: coordinate, radius: 50) + circle.fillColor = UIColor.white.withAlphaComponent(1.0) + circle.strokeColor = UIColor.black + circle.strokeWidth = 2.0 + circle.map = mapView + circle.zIndex = 2 + return circle + } + // Creates circles at the first and last coordinate points / stops for bus route(s) + if let startBusStopCoordinate = busPath.waypoints.first { + let startCircle = busStopCircles(at: startBusStopCoordinate.coordinate, on: mapView) + finalDestinationCircles.append(startCircle) + } + if let finalBusStopCoordinate = busPath.waypoints.last { + let endCircle = busStopCircles(at: finalBusStopCoordinate.coordinate, on: mapView) + finalDestinationCircles.append(endCircle) + } + } + // Extracts and appends all coordinates of waypoints + if let walkPath = path as? WalkPath { + for circleInfo in walkPath.circles { + let circle = GMSCircle(position: circleInfo.coordinate, radius: circleInfo.radius) + if pathCount == 0 { + firstRouteSegment.append(circle) + } else if pathCount == 3 { + // Walk - Bus - Walk scenario + secondRouteSegment.append(circle) + } else { + finalRouteSegment.append(circle) + } + } + } + pathCount += 1 + } + // Helper function for mapping location marker on map + func mapLocationMarker() -> UIImage? { + let targetSize = CGSize(width: 35, height: 35) + guard let originalImage = UIImage(named: "locationMarker") else { + return nil + } + UIGraphicsBeginImageContextWithOptions(targetSize, false, 0.0) + originalImage.draw(in: CGRect(origin: .zero, size: targetSize)) + let resizedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return resizedImage + } + // Maps first walking route segment on map + for coordinateIndex in 0 ..< firstRouteSegment.count { + let waypoint = self.firstRouteSegment[coordinateIndex] + let coordinates = CLLocation(latitude: waypoint.position.latitude, longitude: waypoint.position.longitude) + firstWalkSegment.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) + // Maps a location marker if a second walking route segment doesn't exist (i.e. walking for entire route) + if secondRouteSegment.count == 0 { + if coordinateIndex == firstRouteSegment.count - 1 { + let finalDestinationMarker = GMSMarker(position: coordinates.coordinate) + if let locationMarker = mapLocationMarker() { + finalDestinationMarker.icon = locationMarker + } + finalDestinationMarkers.append(finalDestinationMarker) + finalDestinationMarker.map = mapView + } + } + } + // Maps second segment of walk route in a Walk-Bus-Walk scenario + if secondRouteSegment.count > 0 { + for coordinateIndex in 0 ..< secondRouteSegment.count { + let waypoint2 = self.secondRouteSegment[coordinateIndex] + let coordinates = CLLocation(latitude: waypoint2.position.latitude, longitude: waypoint2.position.longitude) + secondWalkSegment.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) + if finalRouteSegment.count == 0 { + if coordinateIndex == secondRouteSegment.count - 1 { + let finalDestinationMarker = GMSMarker(position: coordinates.coordinate) + if let locationMarker = mapLocationMarker() { + finalDestinationMarker.icon = locationMarker + } + finalDestinationMarkers.append(finalDestinationMarker) + finalDestinationMarker.map = mapView + } + } + } + } + if finalRouteSegment.count > 0 { + for coordinateIndex in 0 ..< finalRouteSegment.count { + let waypoint2 = self.finalRouteSegment[coordinateIndex] + let coordinates = CLLocation(latitude: waypoint2.position.latitude, longitude: waypoint2.position.longitude) + finalWalkSegment.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) + if coordinateIndex == finalRouteSegment.count - 1 { + let finalDestinationMarker = GMSMarker(position: coordinates.coordinate) + if let locationMarker = mapLocationMarker() { + finalDestinationMarker.icon = locationMarker + } + finalDestinationMarkers.append(finalDestinationMarker) + finalDestinationMarker.map = mapView + } + } + } + // Configures polylines for each segment + func configurePolyline(for path: GMSPath) { + let walkPathCircle = createWalkPathCircle() + let polyline = GMSPolyline(path: path) + polyline.strokeWidth = 10 + let stampStyle = GMSSpriteStyle(image: walkPathCircle) + polyline.spans = [GMSStyleSpan(style: GMSStrokeStyle.transparentStroke(withStamp: stampStyle))] + polyline.map = mapView + } + configurePolyline(for: firstWalkSegment) + configurePolyline(for: secondWalkSegment) + configurePolyline(for: finalWalkSegment) + } + // Updates the size of beginning / end bus stop circles when zoomed in + func updateBusStopCircleSize() { + let circleRadiusScale = 1 / mapView.projection.points(forMeters: 1, at: mapView.camera.target) + let circleRadius = 4.5 * CLLocationDistance(circleRadiusScale) + + for circle in finalDestinationCircles { + circle.radius = circleRadius } } diff --git a/TCAT/Controllers/RouteDetailContentViewController+Extensions.swift b/TCAT/Controllers/RouteDetailContentViewController+Extensions.swift index 3233fc31..00656d54 100644 --- a/TCAT/Controllers/RouteDetailContentViewController+Extensions.swift +++ b/TCAT/Controllers/RouteDetailContentViewController+Extensions.swift @@ -187,6 +187,8 @@ extension RouteDetailContentViewController: GMSMapViewDelegate { busIndicators.append(indicator) } } + // Updates bus stop circle sizes + updateBusStopCircleSize() } } diff --git a/TCAT/Models/BusPath.swift b/TCAT/Models/BusPath.swift index 8c1aa649..524242f9 100755 --- a/TCAT/Models/BusPath.swift +++ b/TCAT/Models/BusPath.swift @@ -45,7 +45,7 @@ class BusPath: Path { dashColors = [color, .clear] - self.polylineWidth = 8 + self.polylineWidth = 5 self.untraveledPath = createPathFromWaypoints(waypoints: waypoints) self.traveledPath = untraveledPath diff --git a/TCAT/Models/WalkPath.swift b/TCAT/Models/WalkPath.swift index 9525f34a..8fd10baa 100644 --- a/TCAT/Models/WalkPath.swift +++ b/TCAT/Models/WalkPath.swift @@ -11,14 +11,13 @@ import GoogleMaps import SwiftyJSON class WalkPath: Path { - - var dashLengths: [NSNumber] = [6, 4] - var polylineWidth: CGFloat = 8 + var dashLengths: [NSNumber] = [30, 40] + var polylineWidth: CGFloat = 0 var traveledPath: GMSMutablePath? var untraveledPath: GMSMutablePath? + var circles: [(coordinate: CLLocationCoordinate2D, radius: Double)] = [] init(_ waypoints: [Waypoint]) { - super.init(waypoints: waypoints) self.color = Colors.metadataIcon @@ -28,10 +27,39 @@ class WalkPath: Path { self.path = untraveledPath self.strokeColor = color self.strokeWidth = polylineWidth + + guard let path = self.path else { return } + let intervalDistanceIncrement: CGFloat = 20 + var previousCircle: (coordinate: CLLocationCoordinate2D, radius: Double)? + // Maps circles in incremental distance + for coordinateIndex in 0 ..< path.count() - 1 { + let startCoordinate = path.coordinate(at: coordinateIndex) + let endCoordinate = path.coordinate(at: coordinateIndex + 1) + let startLocation = CLLocation(latitude: startCoordinate.latitude, longitude: startCoordinate.longitude) + let endLocation = CLLocation(latitude: endCoordinate.latitude, longitude: endCoordinate.longitude) + let pathDistance = endLocation.distance(from: startLocation) + let intervalLatIncrement = (endLocation.coordinate.latitude - startLocation.coordinate.latitude) / pathDistance + let intervalLngIncrement = (endLocation.coordinate.longitude - startLocation.coordinate.longitude) / pathDistance + + for intervalDistance in 0 ..< Int(pathDistance) { + let intervalLat = startLocation.coordinate.latitude + (intervalLatIncrement * Double(intervalDistance)) + let intervalLng = startLocation.coordinate.longitude + (intervalLngIncrement * Double(intervalDistance)) + let circleCoordinate = CLLocationCoordinate2D(latitude: intervalLat, longitude: intervalLng) - self.spans = GMSStyleSpans(untraveledPath!, [.solidColor(self.color)], dashLengths, .projected) - self.geodesic = false + if let previousCircle = previousCircle { + let circleLocation = CLLocation(latitude: circleCoordinate.latitude, longitude: circleCoordinate.longitude) + let previousCircleLocation = CLLocation(latitude: previousCircle.coordinate.latitude, longitude: previousCircle.coordinate.longitude) + if circleLocation.distance(from: previousCircleLocation) < intervalDistanceIncrement { + continue + } + } + + let isFinalDestination = (coordinateIndex == path.count() - 1) + circles.append((coordinate: circleCoordinate, radius: 5.0)) + previousCircle = (coordinate: circleCoordinate, radius: 5.0) + } + } } func createPathFromWaypoints(waypoints: [Waypoint]) -> GMSMutablePath { @@ -41,5 +69,4 @@ class WalkPath: Path { } return path } - -} +} From e72960987d6ae0a12ee3ec6bafa163b77084cc89 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Mon, 28 Oct 2024 00:20:51 -0400 Subject: [PATCH 08/16] Reduced redundant code; cleaned up files --- .../spriteGrey.imageset/Contents.json | 21 ---- .../spriteGrey.imageset/sprite_grey.png | Bin 53522 -> 0 bytes .../RouteDetail+ContentViewController.swift | 90 ++++++------------ TCAT/Models/WalkPath.swift | 5 +- 4 files changed, 32 insertions(+), 84 deletions(-) delete mode 100644 TCAT/Assets.xcassets/spriteGrey.imageset/Contents.json delete mode 100644 TCAT/Assets.xcassets/spriteGrey.imageset/sprite_grey.png diff --git a/TCAT/Assets.xcassets/spriteGrey.imageset/Contents.json b/TCAT/Assets.xcassets/spriteGrey.imageset/Contents.json deleted file mode 100644 index 8af013d8..00000000 --- a/TCAT/Assets.xcassets/spriteGrey.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "sprite_grey.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/TCAT/Assets.xcassets/spriteGrey.imageset/sprite_grey.png b/TCAT/Assets.xcassets/spriteGrey.imageset/sprite_grey.png deleted file mode 100644 index 37386734d9b65d22842caac7eab2fb672942eea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53522 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 U-{IvFRMNNQRc>ZnzyI`q0Uo0WO#lD@ diff --git a/TCAT/Controllers/RouteDetail+ContentViewController.swift b/TCAT/Controllers/RouteDetail+ContentViewController.swift index ae846e2e..b43c0f22 100755 --- a/TCAT/Controllers/RouteDetail+ContentViewController.swift +++ b/TCAT/Controllers/RouteDetail+ContentViewController.swift @@ -30,22 +30,28 @@ class RouteDetailContentViewController: UIViewController { /// Number of seconds to wait before auto-refreshing live tracking network call call, timed with live indicator var liveTrackingNetworkRefreshRate: Double = LiveIndicator.interval * 1.0 var liveTrackingNetworkTimer: Timer? - private var locationManager = CLLocationManager() var mapView: GMSMapView! - private let networking: Networking = URLSession.shared.request + private var locationManager = CLLocationManager() private var paths: [Path] = [] private var route: Route! private var routeOptionsCell: RouteTableViewCell? - + private var firstRouteSegment: [GMSCircle] = [] + private var secondRouteSegment: [GMSCircle] = [] + private var finalRouteSegment: [GMSCircle] = [] + private var finalDestinationCircles: [GMSCircle] = [] + private var finalDestinationMarkers: [GMSMarker] = [] + private let firstWalkSegment = GMSMutablePath() + private let secondWalkSegment = GMSMutablePath() + private let finalWalkSegment = GMSMutablePath() + private let networking: Networking = URLSession.shared.request + private let mapPadding: CGFloat = 80 + private let markerRadius: CGFloat = 8 private var banner: StatusBarNotificationBanner? { didSet { setNeedsStatusBarAppearanceUpdate() } } - private let mapPadding: CGFloat = 80 - private let markerRadius: CGFloat = 8 - /// Initalize RouteDetailViewController. Be sure to send a valid route, otherwise /// dummy data will be used. The directions parameter have logical assumptions, /// such as ArriveDirection always comes after DepartDirection. @@ -453,15 +459,7 @@ class RouteDetailContentViewController: UIViewController { } }() } - private var firstRouteSegment: [GMSCircle] = [] - private var secondRouteSegment: [GMSCircle] = [] - private var finalRouteSegment: [GMSCircle] = [] - private var finalDestinationCircles: [GMSCircle] = [] - private var finalDestinationMarkers: [GMSMarker] = [] - let firstWalkSegment = GMSMutablePath() - let secondWalkSegment = GMSMutablePath() - let finalWalkSegment = GMSMutablePath() - + // Helper function that draws individual walking circles private func createWalkPathCircle() -> UIImage { let fillColor = UIColor(white: 0.82, alpha: 1.0) let borderColor = UIColor(white: 0.57, alpha: 1.0) @@ -530,7 +528,7 @@ class RouteDetailContentViewController: UIViewController { } } } - pathCount += 1 + pathCount += 1 } // Helper function for mapping location marker on map func mapLocationMarker() -> UIImage? { @@ -544,14 +542,11 @@ class RouteDetailContentViewController: UIViewController { UIGraphicsEndImageContext() return resizedImage } - // Maps first walking route segment on map - for coordinateIndex in 0 ..< firstRouteSegment.count { - let waypoint = self.firstRouteSegment[coordinateIndex] - let coordinates = CLLocation(latitude: waypoint.position.latitude, longitude: waypoint.position.longitude) - firstWalkSegment.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) - // Maps a location marker if a second walking route segment doesn't exist (i.e. walking for entire route) - if secondRouteSegment.count == 0 { - if coordinateIndex == firstRouteSegment.count - 1 { + func mapRouteSegment(_ segment: [GMSCircle], to path: GMSMutablePath, addMarker: Bool = false) { + for (index, waypoint) in segment.enumerated() { + let coordinates = CLLocation(latitude: waypoint.position.latitude, longitude: waypoint.position.longitude) + path.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) + if addMarker && index == segment.count - 1 { let finalDestinationMarker = GMSMarker(position: coordinates.coordinate) if let locationMarker = mapLocationMarker() { finalDestinationMarker.icon = locationMarker @@ -561,53 +556,30 @@ class RouteDetailContentViewController: UIViewController { } } } - // Maps second segment of walk route in a Walk-Bus-Walk scenario - if secondRouteSegment.count > 0 { - for coordinateIndex in 0 ..< secondRouteSegment.count { - let waypoint2 = self.secondRouteSegment[coordinateIndex] - let coordinates = CLLocation(latitude: waypoint2.position.latitude, longitude: waypoint2.position.longitude) - secondWalkSegment.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) - if finalRouteSegment.count == 0 { - if coordinateIndex == secondRouteSegment.count - 1 { - let finalDestinationMarker = GMSMarker(position: coordinates.coordinate) - if let locationMarker = mapLocationMarker() { - finalDestinationMarker.icon = locationMarker - } - finalDestinationMarkers.append(finalDestinationMarker) - finalDestinationMarker.map = mapView - } - } - } + + // Maps each route segment and maps final location marker for last segment + mapRouteSegment(firstRouteSegment, to: firstWalkSegment, addMarker: secondRouteSegment.isEmpty) + if !secondRouteSegment.isEmpty { + mapRouteSegment(secondRouteSegment, to: secondWalkSegment, addMarker: finalRouteSegment.isEmpty) } - if finalRouteSegment.count > 0 { - for coordinateIndex in 0 ..< finalRouteSegment.count { - let waypoint2 = self.finalRouteSegment[coordinateIndex] - let coordinates = CLLocation(latitude: waypoint2.position.latitude, longitude: waypoint2.position.longitude) - finalWalkSegment.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) - if coordinateIndex == finalRouteSegment.count - 1 { - let finalDestinationMarker = GMSMarker(position: coordinates.coordinate) - if let locationMarker = mapLocationMarker() { - finalDestinationMarker.icon = locationMarker - } - finalDestinationMarkers.append(finalDestinationMarker) - finalDestinationMarker.map = mapView - } - } + if !finalRouteSegment.isEmpty { + mapRouteSegment(finalRouteSegment, to: finalWalkSegment, addMarker: true) } - // Configures polylines for each segment + + // Configures polylines for each walking segment func configurePolyline(for path: GMSPath) { let walkPathCircle = createWalkPathCircle() let polyline = GMSPolyline(path: path) - polyline.strokeWidth = 10 + polyline.strokeWidth = 9 let stampStyle = GMSSpriteStyle(image: walkPathCircle) polyline.spans = [GMSStyleSpan(style: GMSStrokeStyle.transparentStroke(withStamp: stampStyle))] polyline.map = mapView - } + } configurePolyline(for: firstWalkSegment) configurePolyline(for: secondWalkSegment) configurePolyline(for: finalWalkSegment) } - // Updates the size of beginning / end bus stop circles when zoomed in + // Adjusts the size of start / end bus stop circles based on zoom level func updateBusStopCircleSize() { let circleRadiusScale = 1 / mapView.projection.points(forMeters: 1, at: mapView.camera.target) let circleRadius = 4.5 * CLLocationDistance(circleRadiusScale) diff --git a/TCAT/Models/WalkPath.swift b/TCAT/Models/WalkPath.swift index 8fd10baa..85f9c782 100644 --- a/TCAT/Models/WalkPath.swift +++ b/TCAT/Models/WalkPath.swift @@ -27,7 +27,6 @@ class WalkPath: Path { self.path = untraveledPath self.strokeColor = color self.strokeWidth = polylineWidth - guard let path = self.path else { return } let intervalDistanceIncrement: CGFloat = 20 var previousCircle: (coordinate: CLLocationCoordinate2D, radius: Double)? @@ -54,8 +53,6 @@ class WalkPath: Path { continue } } - - let isFinalDestination = (coordinateIndex == path.count() - 1) circles.append((coordinate: circleCoordinate, radius: 5.0)) previousCircle = (coordinate: circleCoordinate, radius: 5.0) } @@ -69,4 +66,4 @@ class WalkPath: Path { } return path } -} +} From 8f111e1a80d34605604a582bc0cd7cfd61460809 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Mon, 28 Oct 2024 01:19:15 -0400 Subject: [PATCH 09/16] Changed location marker image, reorganizec code --- .../locationMarker.png | Bin 7250 -> 68499 bytes .../RouteDetail+ContentViewController.swift | 54 +++++++++--------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/TCAT/Assets.xcassets/locationMarker.imageset/locationMarker.png b/TCAT/Assets.xcassets/locationMarker.imageset/locationMarker.png index 3dd3df326e1d208e9b17a4da8c1170dfe138cb91..6f562c3625de5c24a60a1f983e3e5acee016db64 100644 GIT binary patch literal 68499 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 literal 7250 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 UIImage { let fillColor = UIColor(white: 0.82, alpha: 1.0) let borderColor = UIColor(white: 0.57, alpha: 1.0) @@ -483,6 +484,28 @@ class RouteDetailContentViewController: UIViewController { /// Draw all waypoints initially for all paths in [Path] or [[CLLocationCoordinate2D]], plus fill bounds private func drawMapRoute() { var pathCount = 0 + // Helper function for creating bus stop circles + func busStopCircles(at coordinate: CLLocationCoordinate2D, on mapView: GMSMapView) -> GMSCircle { + let circle = GMSCircle(position: coordinate, radius: 50) + circle.fillColor = UIColor.white.withAlphaComponent(1.0) + circle.strokeColor = UIColor.black + circle.strokeWidth = 2.0 + circle.map = mapView + circle.zIndex = 2 + return circle + } + // Helper function to map final location marker + func mapLocationMarker() -> UIImage? { + let targetSize = CGSize(width: 18, height: 30) + guard let originalImage = UIImage(named: "locationMarker") else { + return nil + } + UIGraphicsBeginImageContextWithOptions(targetSize, false, 0.0) + originalImage.draw(in: CGRect(origin: .zero, size: targetSize)) + let resizedImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return resizedImage + } for path in paths { path.traveledPolyline.map = mapView path.map = mapView @@ -494,16 +517,6 @@ class RouteDetailContentViewController: UIViewController { bounds = bounds.includingCoordinate(waypoint.coordinate) } if let busPath = path as? BusPath { - // Helper function for creating bus stop circles - func busStopCircles(at coordinate: CLLocationCoordinate2D, on mapView: GMSMapView) -> GMSCircle { - let circle = GMSCircle(position: coordinate, radius: 50) - circle.fillColor = UIColor.white.withAlphaComponent(1.0) - circle.strokeColor = UIColor.black - circle.strokeWidth = 2.0 - circle.map = mapView - circle.zIndex = 2 - return circle - } // Creates circles at the first and last coordinate points / stops for bus route(s) if let startBusStopCoordinate = busPath.waypoints.first { let startCircle = busStopCircles(at: startBusStopCoordinate.coordinate, on: mapView) @@ -528,19 +541,7 @@ class RouteDetailContentViewController: UIViewController { } } } - pathCount += 1 - } - // Helper function for mapping location marker on map - func mapLocationMarker() -> UIImage? { - let targetSize = CGSize(width: 35, height: 35) - guard let originalImage = UIImage(named: "locationMarker") else { - return nil - } - UIGraphicsBeginImageContextWithOptions(targetSize, false, 0.0) - originalImage.draw(in: CGRect(origin: .zero, size: targetSize)) - let resizedImage = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - return resizedImage + pathCount += 1 } func mapRouteSegment(_ segment: [GMSCircle], to path: GMSMutablePath, addMarker: Bool = false) { for (index, waypoint) in segment.enumerated() { @@ -557,7 +558,7 @@ class RouteDetailContentViewController: UIViewController { } } - // Maps each route segment and maps final location marker for last segment + // Maps each route segment and final location marker mapRouteSegment(firstRouteSegment, to: firstWalkSegment, addMarker: secondRouteSegment.isEmpty) if !secondRouteSegment.isEmpty { mapRouteSegment(secondRouteSegment, to: secondWalkSegment, addMarker: finalRouteSegment.isEmpty) @@ -579,7 +580,8 @@ class RouteDetailContentViewController: UIViewController { configurePolyline(for: secondWalkSegment) configurePolyline(for: finalWalkSegment) } - // Adjusts the size of start / end bus stop circles based on zoom level + + /// Adjusts the size of endpoint bus stop circles based on zoom level func updateBusStopCircleSize() { let circleRadiusScale = 1 / mapView.projection.points(forMeters: 1, at: mapView.camera.target) let circleRadius = 4.5 * CLLocationDistance(circleRadiusScale) From 491461fe722f1d2d83a452ff9ed10612926ffa76 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Mon, 28 Oct 2024 01:23:16 -0400 Subject: [PATCH 10/16] Minor comment changes --- .../RouteDetail+ContentViewController.swift | 51 +++++++++---------- TCAT/Models/WalkPath.swift | 2 +- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/TCAT/Controllers/RouteDetail+ContentViewController.swift b/TCAT/Controllers/RouteDetail+ContentViewController.swift index 4e435d55..2fd08de3 100755 --- a/TCAT/Controllers/RouteDetail+ContentViewController.swift +++ b/TCAT/Controllers/RouteDetail+ContentViewController.swift @@ -459,32 +459,11 @@ class RouteDetailContentViewController: UIViewController { } }() } - - /// Helper function that draws individual walking circles - private func createWalkPathCircle() -> UIImage { - let fillColor = UIColor(white: 0.82, alpha: 1.0) - let borderColor = UIColor(white: 0.57, alpha: 1.0) - let diameter: CGFloat = 70.0 - let borderWidth: CGFloat = 13.0 - - let renderer = UIGraphicsImageRenderer(size: CGSize(width: diameter, height: diameter)) - return renderer.image { context in - context.cgContext.setFillColor(borderColor.cgColor) - context.cgContext.setStrokeColor(borderColor.cgColor) - context.cgContext.setLineWidth(borderWidth) - context.cgContext.addEllipse(in: CGRect(x: borderWidth / 2, y: borderWidth / 2, width: diameter - borderWidth, height: diameter - borderWidth)) - context.cgContext.drawPath(using: .fillStroke) - - context.cgContext.setFillColor(fillColor.cgColor) - context.cgContext.addEllipse(in: CGRect(x: borderWidth, y: borderWidth, width: diameter - 2 * borderWidth, height: diameter - 2 * borderWidth)) - context.cgContext.fillPath() - } - } /// Draw all waypoints initially for all paths in [Path] or [[CLLocationCoordinate2D]], plus fill bounds private func drawMapRoute() { var pathCount = 0 - // Helper function for creating bus stop circles + // Helper function to create bus stop circles func busStopCircles(at coordinate: CLLocationCoordinate2D, on mapView: GMSMapView) -> GMSCircle { let circle = GMSCircle(position: coordinate, radius: 50) circle.fillColor = UIColor.white.withAlphaComponent(1.0) @@ -506,6 +485,26 @@ class RouteDetailContentViewController: UIViewController { UIGraphicsEndImageContext() return resizedImage } + // Helper function to create individual walking circles + func createWalkPathCircle() -> UIImage { + let fillColor = UIColor(white: 0.82, alpha: 1.0) + let borderColor = UIColor(white: 0.57, alpha: 1.0) + let diameter: CGFloat = 70.0 + let borderWidth: CGFloat = 13.0 + + let renderer = UIGraphicsImageRenderer(size: CGSize(width: diameter, height: diameter)) + return renderer.image { context in + context.cgContext.setFillColor(borderColor.cgColor) + context.cgContext.setStrokeColor(borderColor.cgColor) + context.cgContext.setLineWidth(borderWidth) + context.cgContext.addEllipse(in: CGRect(x: borderWidth / 2, y: borderWidth / 2, width: diameter - borderWidth, height: diameter - borderWidth)) + context.cgContext.drawPath(using: .fillStroke) + + context.cgContext.setFillColor(fillColor.cgColor) + context.cgContext.addEllipse(in: CGRect(x: borderWidth, y: borderWidth, width: diameter - 2 * borderWidth, height: diameter - 2 * borderWidth)) + context.cgContext.fillPath() + } + } for path in paths { path.traveledPolyline.map = mapView path.map = mapView @@ -517,7 +516,7 @@ class RouteDetailContentViewController: UIViewController { bounds = bounds.includingCoordinate(waypoint.coordinate) } if let busPath = path as? BusPath { - // Creates circles at the first and last coordinate points / stops for bus route(s) + // Create circles at the first and last coordinate points / stops for bus route(s) if let startBusStopCoordinate = busPath.waypoints.first { let startCircle = busStopCircles(at: startBusStopCoordinate.coordinate, on: mapView) finalDestinationCircles.append(startCircle) @@ -527,7 +526,7 @@ class RouteDetailContentViewController: UIViewController { finalDestinationCircles.append(endCircle) } } - // Extracts and appends all coordinates of waypoints + // Extract and append all coordinates of waypoints if let walkPath = path as? WalkPath { for circleInfo in walkPath.circles { let circle = GMSCircle(position: circleInfo.coordinate, radius: circleInfo.radius) @@ -558,7 +557,7 @@ class RouteDetailContentViewController: UIViewController { } } - // Maps each route segment and final location marker + // Map each route segment and draw final location marker for the last segment mapRouteSegment(firstRouteSegment, to: firstWalkSegment, addMarker: secondRouteSegment.isEmpty) if !secondRouteSegment.isEmpty { mapRouteSegment(secondRouteSegment, to: secondWalkSegment, addMarker: finalRouteSegment.isEmpty) @@ -567,7 +566,7 @@ class RouteDetailContentViewController: UIViewController { mapRouteSegment(finalRouteSegment, to: finalWalkSegment, addMarker: true) } - // Configures polylines for each walking segment + // Configure polylines for each walking segment func configurePolyline(for path: GMSPath) { let walkPathCircle = createWalkPathCircle() let polyline = GMSPolyline(path: path) diff --git a/TCAT/Models/WalkPath.swift b/TCAT/Models/WalkPath.swift index 85f9c782..48233ae1 100644 --- a/TCAT/Models/WalkPath.swift +++ b/TCAT/Models/WalkPath.swift @@ -30,7 +30,7 @@ class WalkPath: Path { guard let path = self.path else { return } let intervalDistanceIncrement: CGFloat = 20 var previousCircle: (coordinate: CLLocationCoordinate2D, radius: Double)? - // Maps circles in incremental distance + // Maps circle coordinates in incremental distance for coordinateIndex in 0 ..< path.count() - 1 { let startCoordinate = path.coordinate(at: coordinateIndex) let endCoordinate = path.coordinate(at: coordinateIndex + 1) From 9d12b05d49293c092cf32097c52bb9d73106b046 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Wed, 30 Oct 2024 15:30:04 -0400 Subject: [PATCH 11/16] Addressed Peter's comments --- TCAT.xcodeproj/project.pbxproj | 6 +-- .../RouteDetail+ContentViewController.swift | 53 +++++++++++-------- TCAT/Models/WalkPath.swift | 5 +- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/TCAT.xcodeproj/project.pbxproj b/TCAT.xcodeproj/project.pbxproj index 7871ee40..daff45a3 100644 --- a/TCAT.xcodeproj/project.pbxproj +++ b/TCAT.xcodeproj/project.pbxproj @@ -1004,7 +1004,7 @@ INFOPLIST_FILE = TCAT/Supporting/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ithaca Transit"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1101,7 +1101,7 @@ INFOPLIST_FILE = TCAT/Supporting/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ithaca Transit"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1200,7 +1200,7 @@ INFOPLIST_FILE = TCAT/Supporting/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ithaca Transit"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/TCAT/Controllers/RouteDetail+ContentViewController.swift b/TCAT/Controllers/RouteDetail+ContentViewController.swift index 2fd08de3..560df5b4 100755 --- a/TCAT/Controllers/RouteDetail+ContentViewController.swift +++ b/TCAT/Controllers/RouteDetail+ContentViewController.swift @@ -16,41 +16,39 @@ import SwiftyJSON import UIKit class RouteDetailContentViewController: UIViewController { - - var drawerDisplayController: RouteDetailDrawerViewController? - - /// Keep track of statuses of bus routes throughout view life cycle - var noDataRouteList: [Int] = [] - + + private var banner: StatusBarNotificationBanner? { + didSet { + setNeedsStatusBarAppearanceUpdate() + } + } var bounds = GMSCoordinateBounds() var busIndicators = [GMSMarker]() var buses = [GMSMarker]() var currentLocation: CLLocationCoordinate2D? var directions: [Direction] = [] + var drawerDisplayController: RouteDetailDrawerViewController? + private var finalDestinationCircles: [GMSCircle] = [] + private var finalDestinationMarkers: [GMSMarker] = [] + private var finalRouteSegment: [GMSCircle] = [] + private let finalWalkSegment = GMSMutablePath() + private var firstRouteSegment: [GMSCircle] = [] + private let firstWalkSegment = GMSMutablePath() /// Number of seconds to wait before auto-refreshing live tracking network call call, timed with live indicator var liveTrackingNetworkRefreshRate: Double = LiveIndicator.interval * 1.0 var liveTrackingNetworkTimer: Timer? - var mapView: GMSMapView! private var locationManager = CLLocationManager() + var mapView: GMSMapView! + private let mapPadding: CGFloat = 80 + private let markerRadius: CGFloat = 8 + /// Keep track of statuses of bus routes throughout view life cycle + var noDataRouteList: [Int] = [] + private let networking: Networking = URLSession.shared.request private var paths: [Path] = [] private var route: Route! private var routeOptionsCell: RouteTableViewCell? - private var firstRouteSegment: [GMSCircle] = [] private var secondRouteSegment: [GMSCircle] = [] - private var finalRouteSegment: [GMSCircle] = [] - private var finalDestinationCircles: [GMSCircle] = [] - private var finalDestinationMarkers: [GMSMarker] = [] - private let firstWalkSegment = GMSMutablePath() private let secondWalkSegment = GMSMutablePath() - private let finalWalkSegment = GMSMutablePath() - private let networking: Networking = URLSession.shared.request - private let mapPadding: CGFloat = 80 - private let markerRadius: CGFloat = 8 - private var banner: StatusBarNotificationBanner? { - didSet { - setNeedsStatusBarAppearanceUpdate() - } - } /// Initalize RouteDetailViewController. Be sure to send a valid route, otherwise /// dummy data will be used. The directions parameter have logical assumptions, @@ -473,18 +471,21 @@ class RouteDetailContentViewController: UIViewController { circle.zIndex = 2 return circle } + // Helper function to map final location marker func mapLocationMarker() -> UIImage? { let targetSize = CGSize(width: 18, height: 30) guard let originalImage = UIImage(named: "locationMarker") else { return nil } + UIGraphicsBeginImageContextWithOptions(targetSize, false, 0.0) originalImage.draw(in: CGRect(origin: .zero, size: targetSize)) let resizedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return resizedImage } + // Helper function to create individual walking circles func createWalkPathCircle() -> UIImage { let fillColor = UIColor(white: 0.82, alpha: 1.0) @@ -505,6 +506,7 @@ class RouteDetailContentViewController: UIViewController { context.cgContext.fillPath() } } + for path in paths { path.traveledPolyline.map = mapView path.map = mapView @@ -515,17 +517,20 @@ class RouteDetailContentViewController: UIViewController { setIndex(of: marker, with: waypoint.wpType) bounds = bounds.includingCoordinate(waypoint.coordinate) } + if let busPath = path as? BusPath { // Create circles at the first and last coordinate points / stops for bus route(s) if let startBusStopCoordinate = busPath.waypoints.first { let startCircle = busStopCircles(at: startBusStopCoordinate.coordinate, on: mapView) finalDestinationCircles.append(startCircle) } + if let finalBusStopCoordinate = busPath.waypoints.last { let endCircle = busStopCircles(at: finalBusStopCoordinate.coordinate, on: mapView) finalDestinationCircles.append(endCircle) } } + // Extract and append all coordinates of waypoints if let walkPath = path as? WalkPath { for circleInfo in walkPath.circles { @@ -542,12 +547,14 @@ class RouteDetailContentViewController: UIViewController { } pathCount += 1 } + func mapRouteSegment(_ segment: [GMSCircle], to path: GMSMutablePath, addMarker: Bool = false) { for (index, waypoint) in segment.enumerated() { let coordinates = CLLocation(latitude: waypoint.position.latitude, longitude: waypoint.position.longitude) path.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) if addMarker && index == segment.count - 1 { let finalDestinationMarker = GMSMarker(position: coordinates.coordinate) + if let locationMarker = mapLocationMarker() { finalDestinationMarker.icon = locationMarker } @@ -562,6 +569,7 @@ class RouteDetailContentViewController: UIViewController { if !secondRouteSegment.isEmpty { mapRouteSegment(secondRouteSegment, to: secondWalkSegment, addMarker: finalRouteSegment.isEmpty) } + if !finalRouteSegment.isEmpty { mapRouteSegment(finalRouteSegment, to: finalWalkSegment, addMarker: true) } @@ -571,10 +579,11 @@ class RouteDetailContentViewController: UIViewController { let walkPathCircle = createWalkPathCircle() let polyline = GMSPolyline(path: path) polyline.strokeWidth = 9 + let stampStyle = GMSSpriteStyle(image: walkPathCircle) polyline.spans = [GMSStyleSpan(style: GMSStrokeStyle.transparentStroke(withStamp: stampStyle))] polyline.map = mapView - } + } configurePolyline(for: firstWalkSegment) configurePolyline(for: secondWalkSegment) configurePolyline(for: finalWalkSegment) diff --git a/TCAT/Models/WalkPath.swift b/TCAT/Models/WalkPath.swift index 48233ae1..d9f496e2 100644 --- a/TCAT/Models/WalkPath.swift +++ b/TCAT/Models/WalkPath.swift @@ -11,11 +11,12 @@ import GoogleMaps import SwiftyJSON class WalkPath: Path { + + var circles: [(coordinate: CLLocationCoordinate2D, radius: Double)] = [] var dashLengths: [NSNumber] = [30, 40] var polylineWidth: CGFloat = 0 var traveledPath: GMSMutablePath? var untraveledPath: GMSMutablePath? - var circles: [(coordinate: CLLocationCoordinate2D, radius: Double)] = [] init(_ waypoints: [Waypoint]) { super.init(waypoints: waypoints) @@ -27,6 +28,7 @@ class WalkPath: Path { self.path = untraveledPath self.strokeColor = color self.strokeWidth = polylineWidth + guard let path = self.path else { return } let intervalDistanceIncrement: CGFloat = 20 var previousCircle: (coordinate: CLLocationCoordinate2D, radius: Double)? @@ -53,6 +55,7 @@ class WalkPath: Path { continue } } + circles.append((coordinate: circleCoordinate, radius: 5.0)) previousCircle = (coordinate: circleCoordinate, radius: 5.0) } From 123810698d219ca6aab392648f14d8bff143bd08 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Wed, 30 Oct 2024 17:44:30 -0400 Subject: [PATCH 12/16] Fixed minor issue --- .../RouteDetail+ContentViewController.swift | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/TCAT/Controllers/RouteDetail+ContentViewController.swift b/TCAT/Controllers/RouteDetail+ContentViewController.swift index 560df5b4..a14cdc4e 100755 --- a/TCAT/Controllers/RouteDetail+ContentViewController.swift +++ b/TCAT/Controllers/RouteDetail+ContentViewController.swift @@ -47,8 +47,6 @@ class RouteDetailContentViewController: UIViewController { private var paths: [Path] = [] private var route: Route! private var routeOptionsCell: RouteTableViewCell? - private var secondRouteSegment: [GMSCircle] = [] - private let secondWalkSegment = GMSMutablePath() /// Initalize RouteDetailViewController. Be sure to send a valid route, otherwise /// dummy data will be used. The directions parameter have logical assumptions, @@ -537,9 +535,6 @@ class RouteDetailContentViewController: UIViewController { let circle = GMSCircle(position: circleInfo.coordinate, radius: circleInfo.radius) if pathCount == 0 { firstRouteSegment.append(circle) - } else if pathCount == 3 { - // Walk - Bus - Walk scenario - secondRouteSegment.append(circle) } else { finalRouteSegment.append(circle) } @@ -565,11 +560,7 @@ class RouteDetailContentViewController: UIViewController { } // Map each route segment and draw final location marker for the last segment - mapRouteSegment(firstRouteSegment, to: firstWalkSegment, addMarker: secondRouteSegment.isEmpty) - if !secondRouteSegment.isEmpty { - mapRouteSegment(secondRouteSegment, to: secondWalkSegment, addMarker: finalRouteSegment.isEmpty) - } - + mapRouteSegment(firstRouteSegment, to: firstWalkSegment, addMarker: finalRouteSegment.isEmpty) if !finalRouteSegment.isEmpty { mapRouteSegment(finalRouteSegment, to: finalWalkSegment, addMarker: true) } @@ -578,14 +569,12 @@ class RouteDetailContentViewController: UIViewController { func configurePolyline(for path: GMSPath) { let walkPathCircle = createWalkPathCircle() let polyline = GMSPolyline(path: path) - polyline.strokeWidth = 9 - let stampStyle = GMSSpriteStyle(image: walkPathCircle) + polyline.strokeWidth = 9 polyline.spans = [GMSStyleSpan(style: GMSStrokeStyle.transparentStroke(withStamp: stampStyle))] polyline.map = mapView } configurePolyline(for: firstWalkSegment) - configurePolyline(for: secondWalkSegment) configurePolyline(for: finalWalkSegment) } From 6f38fff7b595efc2833d5013067c27fa59ca0ee3 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Wed, 6 Nov 2024 16:00:26 -0500 Subject: [PATCH 13/16] Addressed Richie's comments p1 --- .../RouteDetail+ContentViewController.swift | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/TCAT/Controllers/RouteDetail+ContentViewController.swift b/TCAT/Controllers/RouteDetail+ContentViewController.swift index a14cdc4e..dabf3967 100755 --- a/TCAT/Controllers/RouteDetail+ContentViewController.swift +++ b/TCAT/Controllers/RouteDetail+ContentViewController.swift @@ -169,7 +169,7 @@ class RouteDetailContentViewController: UIViewController { } /// Fetch live-tracking information for the first direction's bus route. - /// Handles connection issues with banners. Animated indicators. + /// Handles connection issues with banners. Animated indicators. @objc func getBusLocations() { // swiftlint:disable:next reduce_boolean let directionsAreValid = route.directions.reduce(true) { result, direction in @@ -455,7 +455,38 @@ class RouteDetailContentViewController: UIViewController { } }() } - + + /// Helper function to create individual walking circles + func createWalkPathCircle() -> UIImage { + let fillColor = UIColor(white: 0.82, alpha: 1.0) + let borderColor = UIColor(white: 0.57, alpha: 1.0) + let diameter: CGFloat = 70.0 + let borderWidth: CGFloat = 13.0 + + let renderer = UIGraphicsImageRenderer(size: CGSize(width: diameter, height: diameter)) + return renderer.image { context in + context.cgContext.setFillColor(borderColor.cgColor) + context.cgContext.setStrokeColor(borderColor.cgColor) + context.cgContext.setLineWidth(borderWidth) + context.cgContext.addEllipse(in: CGRect(x: borderWidth / 2, y: borderWidth / 2, width: diameter - borderWidth, height: diameter - borderWidth)) + context.cgContext.drawPath(using: .fillStroke) + + context.cgContext.setFillColor(fillColor.cgColor) + context.cgContext.addEllipse(in: CGRect(x: borderWidth, y: borderWidth, width: diameter - 2 * borderWidth, height: diameter - 2 * borderWidth)) + context.cgContext.fillPath() + } + } + + /// Configure polylines for each walking segment + func configurePolyline(for path: GMSPath) { + let walkPathCircle = createWalkPathCircle() + let polyline = GMSPolyline(path: path) + let stampStyle = GMSSpriteStyle(image: walkPathCircle) + polyline.strokeWidth = 7 + polyline.spans = [GMSStyleSpan(style: GMSStrokeStyle.transparentStroke(withStamp: stampStyle))] + polyline.map = mapView + } + /// Draw all waypoints initially for all paths in [Path] or [[CLLocationCoordinate2D]], plus fill bounds private func drawMapRoute() { var pathCount = 0 @@ -473,9 +504,7 @@ class RouteDetailContentViewController: UIViewController { // Helper function to map final location marker func mapLocationMarker() -> UIImage? { let targetSize = CGSize(width: 18, height: 30) - guard let originalImage = UIImage(named: "locationMarker") else { - return nil - } + guard let originalImage = UIImage(named: "locationMarker") else { return nil } UIGraphicsBeginImageContextWithOptions(targetSize, false, 0.0) originalImage.draw(in: CGRect(origin: .zero, size: targetSize)) @@ -484,27 +513,6 @@ class RouteDetailContentViewController: UIViewController { return resizedImage } - // Helper function to create individual walking circles - func createWalkPathCircle() -> UIImage { - let fillColor = UIColor(white: 0.82, alpha: 1.0) - let borderColor = UIColor(white: 0.57, alpha: 1.0) - let diameter: CGFloat = 70.0 - let borderWidth: CGFloat = 13.0 - - let renderer = UIGraphicsImageRenderer(size: CGSize(width: diameter, height: diameter)) - return renderer.image { context in - context.cgContext.setFillColor(borderColor.cgColor) - context.cgContext.setStrokeColor(borderColor.cgColor) - context.cgContext.setLineWidth(borderWidth) - context.cgContext.addEllipse(in: CGRect(x: borderWidth / 2, y: borderWidth / 2, width: diameter - borderWidth, height: diameter - borderWidth)) - context.cgContext.drawPath(using: .fillStroke) - - context.cgContext.setFillColor(fillColor.cgColor) - context.cgContext.addEllipse(in: CGRect(x: borderWidth, y: borderWidth, width: diameter - 2 * borderWidth, height: diameter - 2 * borderWidth)) - context.cgContext.fillPath() - } - } - for path in paths { path.traveledPolyline.map = mapView path.map = mapView @@ -544,7 +552,7 @@ class RouteDetailContentViewController: UIViewController { } func mapRouteSegment(_ segment: [GMSCircle], to path: GMSMutablePath, addMarker: Bool = false) { - for (index, waypoint) in segment.enumerated() { + segment.enumerated().forEach { index, waypoint in let coordinates = CLLocation(latitude: waypoint.position.latitude, longitude: waypoint.position.longitude) path.addLatitude(coordinates.coordinate.latitude, longitude: coordinates.coordinate.longitude) if addMarker && index == segment.count - 1 { @@ -564,18 +572,10 @@ class RouteDetailContentViewController: UIViewController { if !finalRouteSegment.isEmpty { mapRouteSegment(finalRouteSegment, to: finalWalkSegment, addMarker: true) } - - // Configure polylines for each walking segment - func configurePolyline(for path: GMSPath) { - let walkPathCircle = createWalkPathCircle() - let polyline = GMSPolyline(path: path) - let stampStyle = GMSSpriteStyle(image: walkPathCircle) - polyline.strokeWidth = 9 - polyline.spans = [GMSStyleSpan(style: GMSStrokeStyle.transparentStroke(withStamp: stampStyle))] - polyline.map = mapView - } + configurePolyline(for: firstWalkSegment) configurePolyline(for: finalWalkSegment) + } /// Adjusts the size of endpoint bus stop circles based on zoom level From fbb3ab025c7882ca4e16c7edcf532581486c8d7a Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Wed, 6 Nov 2024 16:00:54 -0500 Subject: [PATCH 14/16] Addressed Richie's comments p2 --- TCAT/Models/WalkPath.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TCAT/Models/WalkPath.swift b/TCAT/Models/WalkPath.swift index d9f496e2..0c851eb5 100644 --- a/TCAT/Models/WalkPath.swift +++ b/TCAT/Models/WalkPath.swift @@ -51,9 +51,7 @@ class WalkPath: Path { let circleLocation = CLLocation(latitude: circleCoordinate.latitude, longitude: circleCoordinate.longitude) let previousCircleLocation = CLLocation(latitude: previousCircle.coordinate.latitude, longitude: previousCircle.coordinate.longitude) - if circleLocation.distance(from: previousCircleLocation) < intervalDistanceIncrement { - continue - } + if circleLocation.distance(from: previousCircleLocation) < intervalDistanceIncrement { continue } } circles.append((coordinate: circleCoordinate, radius: 5.0)) From cb541f98ae343bd3b20541ebc7c29879a0cd5702 Mon Sep 17 00:00:00 2001 From: Angelina Chen Date: Wed, 6 Nov 2024 16:01:39 -0500 Subject: [PATCH 15/16] Addressed Richie's comments p3 --- TCAT.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TCAT.xcodeproj/project.pbxproj b/TCAT.xcodeproj/project.pbxproj index daff45a3..7871ee40 100644 --- a/TCAT.xcodeproj/project.pbxproj +++ b/TCAT.xcodeproj/project.pbxproj @@ -1004,7 +1004,7 @@ INFOPLIST_FILE = TCAT/Supporting/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ithaca Transit"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; - IPHONEOS_DEPLOYMENT_TARGET = 18.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1101,7 +1101,7 @@ INFOPLIST_FILE = TCAT/Supporting/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ithaca Transit"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; - IPHONEOS_DEPLOYMENT_TARGET = 18.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1200,7 +1200,7 @@ INFOPLIST_FILE = TCAT/Supporting/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ithaca Transit"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; - IPHONEOS_DEPLOYMENT_TARGET = 18.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", From 10060fbf5178cf8cdf8e2c3aecb45d160f51bd0b Mon Sep 17 00:00:00 2001 From: Richie Sun Date: Wed, 6 Nov 2024 18:08:38 -0500 Subject: [PATCH 16/16] Incremented Build and Version --- TCAT.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TCAT.xcodeproj/project.pbxproj b/TCAT.xcodeproj/project.pbxproj index 7871ee40..ed0b1369 100644 --- a/TCAT.xcodeproj/project.pbxproj +++ b/TCAT.xcodeproj/project.pbxproj @@ -1009,7 +1009,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.0.2; + MARKETING_VERSION = 2.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.cornellappdev.tcat; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1106,7 +1106,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.0.2; + MARKETING_VERSION = 2.0.3; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" -DDEBUG"; "OTHER_SWIFT_FLAGS[arch=*]" = "$(inherited) \"-D\" \"COCOAPODS\""; PRODUCT_BUNDLE_IDENTIFIER = com.cornellappdev.tcat.debug; @@ -1205,7 +1205,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 2.0.2; + MARKETING_VERSION = 2.0.3; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" -DLOCAL"; "OTHER_SWIFT_FLAGS[arch=*]" = "$(inherited) \"-D\" \"COCOAPODS\""; PRODUCT_BUNDLE_IDENTIFIER = com.cornellappdev.tcat.debug;