Commit bd2c5197 authored by Zach Knox's avatar Zach Knox
Browse files

Merge branch 'superfluousness' into '3-favorites'

# Conflicts:
#   WhatsOpen/WhatsOpen/Views/FacilitiesListViewController.swift
parents 0794102d 8f9d6f0b
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="DGD-49-9Ue">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="DGD-49-9Ue">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13527"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
......@@ -72,7 +72,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="naC-sZ-bcy">
<rect key="frame" x="0.0" y="64" width="375" height="559"/>
<rect key="frame" x="0.0" y="116" width="375" height="507"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<gestureRecognizers/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="eqw-AF-DSB">
......@@ -483,8 +483,8 @@
<navigationController title="Root Navigation" automaticallyAdjustsScrollViewInsets="NO" id="DGD-49-9Ue" sceneMemberID="viewController">
<toolbarItems/>
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="ulx-sh-XJ1">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" largeTitles="YES" id="ulx-sh-XJ1">
<rect key="frame" x="0.0" y="20" width="375" height="96"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<textAttributes key="titleTextAttributes">
......
......@@ -34,7 +34,7 @@ class MainTableViewController: UITableViewController {
SRCTNetworkController.performDownload { (facilities) in
self.facilitiesArray = Array(facilities)
self.facilitiesArray = Array(facilities!)
self.tableView.reloadData()
}
}
......
......@@ -22,11 +22,11 @@ enum Day: Int {
class Facility: Object, MapContext, Mappable {
@objc dynamic var slug = ""
@objc dynamic var facilityName = ""
var facilityLocation: Locations? = Locations()
var category: Categories? = Categories()
var facilityTags: List<FacilityTags>? = List<FacilityTags>()
var mainSchedule: MainSchedule? = MainSchedule()
var specialSchedule: SpecialSchedule? = SpecialSchedule()
@objc dynamic var facilityLocation: Locations? = Locations()
@objc dynamic var category: Categories? = Categories()
var facilityTags: List<FacilityTags>? = List<FacilityTags>()
@objc dynamic var mainSchedule: MainSchedule? = MainSchedule()
@objc dynamic var specialSchedule: SpecialSchedule? = SpecialSchedule()
required convenience init?(map: Map) {
......
......@@ -15,33 +15,40 @@ import ObjectMapper
class SRCTNetworkController: NSObject {
//Use this for testing with the new API, might make it possible to get stuff moving pre official release
//https://api.srct.gmu.edu/whatsopen/v2/facilities/?format=json
public static func performDownload(completion: @escaping (_ result: List<Facility>) -> Void) {
public static func performDownload(completion: @escaping (_ result: List<Facility>?) -> Void) {
let requestURL: NSURL = NSURL(string: "https://api.srct.gmu.edu/whatsopen/v2/facilities/?format=json")!
let requestURL: NSURL = NSURL(string: "https://api.srct.gmu.edu/whatsopen/v2/facilities/?format=json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL as URL)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest as URLRequest) {
let task = session.dataTask(with: urlRequest as URLRequest) {
(data, response, error) -> Void in
if(error != nil) {
completion(nil)
return
}
else {
let httpResponse = response as! HTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
if let dataN = data {
if let json = try? JSONSerialization.jsonObject(with: dataN, options: []) as? [[String: Any]] {
// Map function to iterate through each JSON tree
let facilities = json!.map({ (json) -> Facility in
let facility = Facility()
let map = Map(mappingType: .fromJSON, JSON: json, toObject: true, context: facility, shouldIncludeNilValues: true)
facility.mapping(map: map)
return facility
})
// This is where completion is called
// Right after the array is done mapping all facility objects
completion(List(facilities))
}
}
}
}
let httpResponse = response as! HTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
if let dataN = data {
if let json = try? JSONSerialization.jsonObject(with: dataN, options: []) as? [[String: Any]] {
// Map function to iterate through each JSON tree
let facilities = json!.map({ (json) -> Facility in
let facility = Facility()
let map = Map(mappingType: .fromJSON, JSON: json, toObject: true, context: facility, shouldIncludeNilValues: true)
facility.mapping(map: map)
return facility
})
// This is where completion is called
// Right after the array is done mapping all facility objects
completion(List(facilities))
}
}
}
}
task.resume()
......
......@@ -10,9 +10,21 @@ import UIKit
import DeckTransition
import RealmSwift
//Realm Model
class FacilitiesModel: Object {
var facilities = List<Facility>()
@objc dynamic var lastUpdated = Date()
@objc dynamic let id = 0
}
class FacilitiesListViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UIViewControllerPreviewingDelegate {
// array of all facilities
let realm = try! Realm()
var facilitiesArray = List<Facility>()
// array of facilities that pass the current filters
......@@ -100,7 +112,7 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
}
@IBAction func RefreshButton(_ sender: Any) {
refresh(sender)
refresh(sender, forceUpdate: true)
}
override func viewWillAppear(_ animated: Bool) {
......@@ -174,7 +186,8 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
navigationItem.title = "What's Open"
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
configureSearchController()
LocationsListLayout.invalidateLayout()
......@@ -185,19 +198,30 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
LocationsListLayout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10)
refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
LocationsList.addSubview(refreshControl)
LocationsList.refreshControl = refreshControl
LocationsList.alwaysBounceVertical = true
SRCTNetworkController.performDownload { (facilities) in
self.facilitiesArray = List(facilities)
DispatchQueue.main.async {
self.LocationsList.reloadData()
let date = Date()
self.LastUpdatedLabel.title = "Updated: " + self.shortDateFormat(date)
}
/*
let defaults = UserDefaults.standard
let facilitiesFromDefaults = defaults.object(forKey: "FacilitiesList") as! List<Facility>?
let lastUpdatedList = defaults.object(forKey: "lastUpdatedList") as! Date?
if(facilitiesFromDefaults == nil || lastUpdatedList == nil) {
refresh(self)
}
else if(lastUpdatedList! < Date(timeIntervalSinceNow: -86400.0)) {
refresh(self)
}
else {
facilitiesArray = facilitiesFromDefaults!
}
*/
refresh(self, forceUpdate: false)
LocationsList.reloadData()
}
func isSearchBarEmpty() -> Bool {
return searchController.searchBar.text?.isEmpty ?? true
......@@ -247,13 +271,87 @@ class FacilitiesListViewController: UIViewController, UICollectionViewDelegate,
return filtered
}
@objc func refresh(_ sender: Any) {
func refresh(_ sender: Any, forceUpdate: Bool = true) {
refreshControl.beginRefreshing()
if(forceUpdate) {
update(sender);
}
else {
let results = realm.objects(FacilitiesModel.self)
if results.count > 0 {
let model = results[0]
let facilities = model.facilities
let lastUpdated = model.lastUpdated
if(facilities.isEmpty || lastUpdated < Date(timeIntervalSinceNow: -86400.0)) {
update(sender)
}
else {
facilitiesArray = facilities
self.LastUpdatedLabel.title = "Updated: " + self.shortDateFormat(lastUpdated)
}
}
else {
update(sender)
}
}
LocationsList.reloadData()
let date = Date()
LastUpdatedLabel.title = "Updated: " + shortDateFormat(date)
refreshControl.endRefreshing()
}
func update(_ sender: Any) {
SRCTNetworkController.performDownload { (facilities) in
if(facilities == nil) {
DispatchQueue.main.async {
let results = self.realm.objects(FacilitiesModel.self)
if results.count > 0 {
let model = results[0]
let facilitiesFromDB = model.facilities
let lastUpdated = model.lastUpdated
self.facilitiesArray = facilitiesFromDB
self.LocationsList.reloadData()
self.LastUpdatedLabel.title = "Updated: " + self.shortDateFormat(lastUpdated)
}
else {
self.facilitiesArray = List<Facility>()
}
}
}
else {
self.facilitiesArray = facilities!
DispatchQueue.main.async {
//let defaults = UserDefaults.standard
//defaults.set(facilities, forKey: "FacilitiesList")
let date = Date()
//defaults.set(date, forKey: "lastUpdatedList")
self.LocationsList.reloadData()
self.LastUpdatedLabel.title = "Updated: " + self.shortDateFormat(date)
let model = FacilitiesModel()
model.facilities = facilities!
model.lastUpdated = date
let results = self.realm.objects(FacilitiesModel.self)
if results.count == 0 {
try! self.realm.write {
self.realm.add(model)
}
}
else {
let fromRealm = results[0]
try! self.realm.write {
fromRealm.facilities = model.facilities
fromRealm.lastUpdated = model.lastUpdated
}
}
}
}
}
}
func shortDateFormat(_ date: Date) -> String {
let dateFormatter = DateFormatter()
......@@ -447,3 +545,5 @@ extension FacilitiesListViewController: UISearchResultsUpdating {
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment