diff --git a/AvH Plan.xcodeproj/project.pbxproj b/AvH Plan.xcodeproj/project.pbxproj index afefb03..d839058 100644 --- a/AvH Plan.xcodeproj/project.pbxproj +++ b/AvH Plan.xcodeproj/project.pbxproj @@ -599,7 +599,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer: k.duezgoeren@gmail.com (R9NVDFCQHW)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -661,7 +661,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer: k.duezgoeren@gmail.com (R9NVDFCQHW)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; diff --git a/AvH Plan/AppDelegate.swift b/AvH Plan/AppDelegate.swift index f80c7bc..ec75064 100644 --- a/AvH Plan/AppDelegate.swift +++ b/AvH Plan/AppDelegate.swift @@ -10,7 +10,7 @@ import UIKit import Firebase @UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { +class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate { var window: UIWindow? @@ -19,27 +19,40 @@ class AppDelegate: UIResponder, UIApplicationDelegate { FirebaseApp.configure() -// if #available(iOS 10.0, *) { -// // For iOS 10 display notification (sent via APNS) -// UNUserNotificationCenter.current().delegate = self -// -// let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] -// UNUserNotificationCenter.current().requestAuthorization( -// options: authOptions, -// completionHandler: {_, _ in }) -// } else { -// let settings: UIUserNotificationSettings = -// UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) -// application.registerUserNotificationSettings(settings) -// } -// -// application.registerForRemoteNotifications() - - Messaging.messaging().subscribe(toTopic: "substitutions-ios") - Messaging.messaging().subscribe(toTopic: "substitutions-broadcast") - Crashlytics.sharedInstance().setUserIdentifier(UserDefaults.standard.string(forKey: "username")) + if #available(iOS 10.0, *) { + // For iOS 10 display notification (sent via APNS) + UNUserNotificationCenter.current().delegate = self + + let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] + UNUserNotificationCenter.current().requestAuthorization( + options: authOptions, + completionHandler: {_, _ in }) + } else { + let settings: UIUserNotificationSettings = + UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) + application.registerUserNotificationSettings(settings) + } + + application.registerForRemoteNotifications() + InstanceID.instanceID().instanceID { (result, error) in + if let error = error { + print("Error fetching remote instance ID: \(error)") + } else if let result = result { + print("Remote instance ID token: \(result.token)") + } + } + Messaging.messaging().delegate = self return true } + + func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { + print("Firebase registration token: \(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. + } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. diff --git a/AvH Plan/Base.lproj/Main.storyboard b/AvH Plan/Base.lproj/Main.storyboard index c3a1be2..c97ba54 100644 --- a/AvH Plan/Base.lproj/Main.storyboard +++ b/AvH Plan/Base.lproj/Main.storyboard @@ -163,12 +163,25 @@ + + + + + + + + + + + + + diff --git a/AvH Plan/CustomizationViewController.swift b/AvH Plan/CustomizationViewController.swift index b4590e5..be605a3 100644 --- a/AvH Plan/CustomizationViewController.swift +++ b/AvH Plan/CustomizationViewController.swift @@ -9,7 +9,7 @@ import UIKit import MagazineLayout -class CustomizationViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateMagazineLayout { +class CustomizationViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateMagazineLayout, UITextFieldDelegate { var courses = [String]() var translatedCourses = [String]() @@ -24,6 +24,16 @@ class CustomizationViewController: UIViewController, UICollectionViewDataSource, @IBOutlet weak var txtCourses: UITextField! @IBOutlet weak var defaultSegments: UISegmentedControl! + @IBOutlet weak var textToolbar: UIToolbar! + + @IBAction func textDismissButton(_ sender: Any) { + view.endEditing(true) + } + + func textFieldDidBeginEditing(_ textField: UITextField) { + textField.inputAccessoryView = textToolbar + } + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) courses = self.df.courses @@ -45,6 +55,10 @@ class CustomizationViewController: UIViewController, UICollectionViewDataSource, override func viewDidLoad() { super.viewDidLoad() + self.txtName.delegate = self + self.txtClasses.delegate = self + self.txtCourses.delegate = self + self.txtName.text = prefs.string(forKey: "username") self.txtClasses.text = prefs.string(forKey: "classes") self.txtCourses.text = prefs.string(forKey: "courses") diff --git a/AvH Plan/DataFetcher.swift b/AvH Plan/DataFetcher.swift index 9a13b91..8df9f5f 100644 --- a/AvH Plan/DataFetcher.swift +++ b/AvH Plan/DataFetcher.swift @@ -55,6 +55,7 @@ class DataFetcher { var infoList = [String]() var menuList = [String]() var isPersonalEmpty = true + var personalPlanCount = 0 do { let doc = try SwiftSoup.parse(html) @@ -119,6 +120,7 @@ class DataFetcher { date <- mDate, time <- mTime, room <- mRoom) _ = try db.run(insertPersonal) isPersonalEmpty = false + personalPlanCount += 1 } } } else if courses != nil && courses != "" && classes != nil && classes != "" { @@ -131,6 +133,7 @@ class DataFetcher { date <- mDate, time <- mTime, room <- mRoom) _ = try db.run(insertPersonal) isPersonalEmpty = false + personalPlanCount += 1 } } } @@ -138,6 +141,7 @@ class DataFetcher { } + prefs.set(personalPlanCount, forKey: "personalPlanCount") if isPersonalEmpty { personalSubst.append(SubstModel(group: NSLocalizedString("personal_plan_empty", comment: ""), course: "", additional: "", date: "", time: "", room: "")) let insertPersonal = personal.insert(group <- NSLocalizedString("personal_plan_empty", comment: ""), course <- "", additional <- "", date <- "", time <- "", room <- "") diff --git a/AvH Plan/InfoViewController.swift b/AvH Plan/InfoViewController.swift index 1f8ba50..a34a9b8 100644 --- a/AvH Plan/InfoViewController.swift +++ b/AvH Plan/InfoViewController.swift @@ -46,6 +46,14 @@ class InfoViewController : UIViewController { self.df.doAsync(do: "info") { infoArray in self.content.text = infoArray[0] as? String self.refreshControl.endRefreshing() + if let tabItems = self.tabBarController?.tabBar.items { + let tabItem = tabItems[1] + if self.prefs.integer(forKey: "personalPlanCount") != 0 { + tabItem.badgeValue = "\(self.prefs.integer(forKey: "personalPlanCount"))" + } else { + tabItem.badgeValue = nil + } + } } } } diff --git a/AvH Plan/MenuViewController.swift b/AvH Plan/MenuViewController.swift index 5793bc0..d15c06a 100644 --- a/AvH Plan/MenuViewController.swift +++ b/AvH Plan/MenuViewController.swift @@ -17,6 +17,7 @@ class MenuViewController : UIViewController, UICollectionViewDataSource, UIColle let layout = MagazineLayout() var collectionView: UICollectionView let identifier = "menu_cell" + let prefs = UserDefaults.standard required init?(coder decoder: NSCoder) { collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) @@ -62,6 +63,14 @@ class MenuViewController : UIViewController, UICollectionViewDataSource, UIColle self.items = menuItems as! [String] self.collectionView.reloadData() self.refreshControl.endRefreshing() + if let tabItems = self.tabBarController?.tabBar.items { + let tabItem = tabItems[1] + if self.prefs.integer(forKey: "personalPlanCount") != 0 { + tabItem.badgeValue = "\(self.prefs.integer(forKey: "personalPlanCount"))" + } else { + tabItem.badgeValue = nil + } + } } } @@ -83,8 +92,6 @@ class MenuViewController : UIViewController, UICollectionViewDataSource, UIColle return cell } - // generated stubs filled with return values - func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeModeForItemAt indexPath: IndexPath) -> MagazineLayoutItemSizeMode { let widthMode = MagazineLayoutItemWidthMode.fullWidth(respectsHorizontalInsets: true) let heightMode = MagazineLayoutItemHeightMode.dynamic diff --git a/AvH Plan/PlanViewController.swift b/AvH Plan/PlanViewController.swift index 8f3048c..5d6d4f6 100644 --- a/AvH Plan/PlanViewController.swift +++ b/AvH Plan/PlanViewController.swift @@ -9,6 +9,7 @@ import UIKit import MagazineLayout import Crashlytics +import Firebase class PlanViewController : UIViewController, UICollectionViewDataSource, UICollectionViewDelegateMagazineLayout { @@ -16,6 +17,7 @@ class PlanViewController : UIViewController, UICollectionViewDataSource, UIColle var substs = [SubstModel]() let refreshControl = UIRefreshControl() let df = DataFetcher.sharedInstance + let planPrefs = UserDefaults.standard let layout = MagazineLayout() var collectionView: UICollectionView var url = "" @@ -33,12 +35,16 @@ class PlanViewController : UIViewController, UICollectionViewDataSource, UIColle override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + Messaging.messaging().subscribe(toTopic: "substitutions-ios") + Messaging.messaging().subscribe(toTopic: "substitutions-broadcast") + Crashlytics.sharedInstance().setUserIdentifier(UserDefaults.standard.string(forKey: "username")) + view.addSubview(collectionView) collectionView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - collectionView.topAnchor.constraint(equalTo: view.topAnchor), // getToolbarBottomAnchor()), + collectionView.topAnchor.constraint(equalTo: view.topAnchor), collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) collectionView.register(UINib(nibName: "PlanViewCell", bundle: nil), forCellWithReuseIdentifier: identifier) @@ -80,6 +86,14 @@ class PlanViewController : UIViewController, UICollectionViewDataSource, UIColle self.substs = substitutions as! [SubstModel] self.collectionView.reloadData() self.refreshControl.endRefreshing() + if let tabItems = self.tabBarController?.tabBar.items { + let tabItem = tabItems[1] + if self.planPrefs.integer(forKey: "personalPlanCount") != 0 { + tabItem.badgeValue = "\(self.planPrefs.integer(forKey: "personalPlanCount"))" + } else { + tabItem.badgeValue = nil + } + } } }